Live data from Hacker News

The general value of typed functional programming lies in leaving no edge cases

np.reddit.com

81–90 of 172 posts

Re: The general value of typed functional programming lies in leaving no edge cases

#81
post #2

Edge case removed: for i=0 to 10 {print(a[i])} vs for x in a {print(x)} With functional programming it gets even better: a.filter {}.map{print} Pseudo code, of course. I list several “functional“ examples in Swift here: https://github.com/melling/SwiftCookBook/blob/master/functio... Functional programming is also a higher level language. map, reduce,filter, flatten, flapMap, drop, take, zip, ... Learn the concepts in…

I program mainly in C++, and I often start off writing things as: for (auto x : someContainer) { //do something with x } But inevitably, I end up needing either an iterator pointing to a particular item at the end, or I need an index to pass to some other function, and this style makes that impossible. Perhaps it's just the domain I work in, but even after years of trying to make this work, it still only works about…

Why not just pass the reference instead of an iterator or index? That’s what I do the best majority of the time. It’s rare that I actually need a specific iterator or pointer.

Just change your loop to auto& x.

Re: The general value of typed functional programming lies in leaving no edge cases

#82
post #47
post #28

Earlier quoted context omitted.

This is also one of the problems with programming with exceptions. You lean on the fact that an exception will be thrown and just propogate up until it finds something, so the normal mindset of an exception-based programmer is to program for the happy-case and only vaguely think about what happens if it goes wrong. I know, I've written a lot of code in this style for many years myself. In some cases, that's not a pro…

This is especially evident in e.g. third-party Python libraries. For example, say you have a pandas dataframe with a column "foo" and you accidentally try to read column "fooo". Instead of getting a useful exception like "PandasException: Attempted to read nonexistent column 'fooo'", you get a traceback 10 layers deep, terminating in something like "pandas.hashtable.PyObjectHashTable.get_item" which ought to be total…

This is how it should be done, I'm such a fan of this page: https://www.psycopg.org/docs/errors.html

Edit: by "this" I meant to agree with parent: Getting a useful, well defined exception is how it should be done. Psycopg2 does this very well.

Re: The general value of typed functional programming lies in leaving no edge cases

#83
post #66

Earlier quoted context omitted.

Haskell is so much better, and you would learn that with about 5 minutes learning about the number types

Haskell still doesn't track NaN in the type system.

You're right, it does, and it exists at the value level if you are using floating point. But in Haskell you have, for example, Rational numbers to avoid many such problems.

I was, however, surprised to not see any kind of a (significant) `safeDiv` function on hackage, and no NonZero newtype (outside of quickcheck). But, for this kind of thing its so easy to roll yourself, I am guessing this is what people do (and I have seen).

Re: The general value of typed functional programming lies in leaving no edge cases

#84
post #75

Earlier quoted context omitted.

Swift has this as well, but calls them “Optional”. The concept is definitely useful!

Also Java has Optional and C# has Nullable .

That's not important in practice. What's important is that null infects all reference types in Java and C#, whether you asked for it or not. Just today I've spent a half an hour looking for a null dereference error - which the type system should've warned me of but didn't. The sad fact is, neither Java nor C# are fixable, because no new feature will fix the broken, null-unsafe code already written. All because of this billion dollar mistake that should've had no place in a GCed language but was blindly copied over from C++. The sooner Java gives way to Kotlin and completely fades into obscurity, the better.

Re: The general value of typed functional programming lies in leaving no edge cases

#85
post #76
post #38

Earlier quoted context omitted.

Someone once describing the forces acting on a race car pointed out that the horizontal forced in a curve were high enough to throw you from the car if not for the five point harness (F1 probably doesn’t have this behavior due to the cockpit design). Sometimes safety equipment lets you go faster.

> Sometimes safety equipment lets you go faster. Even simpler: brakes let you go faster. When I was cycling a while ago, my brakes broke in the middle of a cross-country ride. I didn't want to push the bike back all the way, but you can bet your hat that I rode extremely slowly and cautious.

Both brakes broke, or the front brake did? You can get by with just the front brake. Question is if you had enough tools to do that surgery. Would depend on the brakes.

I don't think anybody remembers how shit bike brakes were before dual pivot came along. God bless Shimano and keep it forever. When I got my first set, I started emergency-braking with 2 fingers because I was worried I'd pole vault myself if I actually squeezed like I meant it. (I have high grip strength).

Re: The general value of typed functional programming lies in leaving no edge cases

#86
post #28

Earlier quoted context omitted.

This is also one of the problems with programming with exceptions. You lean on the fact that an exception will be thrown and just propogate up until it finds something, so the normal mindset of an exception-based programmer is to program for the happy-case and only vaguely think about what happens if it goes wrong. I know, I've written a lot of code in this style for many years myself. In some cases, that's not a pro…

Exceptions are the worst because there's a hidden nested world of control flow you can't barely begin to reason about. Exceptions are a "comes-from" statement, like a "goto" but much worse.

This just gave me the thought... if exception stack traces came with the argument values of each method call, they would be 1000x more helpful. You wouldn't even have to attach a debugger and step through in many cases.

Re: The general value of typed functional programming lies in leaving no edge cases

#87
post #19
post #14

Earlier quoted context omitted.

You can use a functional style in those languages as well. Or do you mean with Rust's borrow checker you have less mutability to worry about?

If you have a Rust enum with Color{Red,Green,Blue), if for some reason you update to Color{Red,Green,Blue,Yellow}, the rustc compiler will force you to manage the new Yellow case wherever you want to "match" a pattern on Color, so overall you have less chance to forget to manage the new case everywhere. This kind of error is not managed by a C or C++ compiler (as far as I know). But from my understanding, this is not…

Kotlin also enforce exhaustivity in when(), for enums and ADTs (sealed class's)

Re: The general value of typed functional programming lies in leaving no edge cases

#88
post #86

Earlier quoted context omitted.

Exceptions are the worst because there's a hidden nested world of control flow you can't barely begin to reason about. Exceptions are a "comes-from" statement, like a "goto" but much worse.

This just gave me the thought... if exception stack traces came with the argument values of each method call, they would be 1000x more helpful. You wouldn't even have to attach a debugger and step through in many cases.

I think they do in python, or at least can be retrieved. I know they show up in the stack trace on Sentry when an unhandled exception occurs.

Re: The general value of typed functional programming lies in leaving no edge cases

#89
post #28

Forget the performance or the fancy memory management stuff, this is one of the best things about Rust: it makes you deal with edge cases by default (while allowing you to write code in a largely imperative or functional-lite style). It's why I think it competes for market share with some of what is currently Java/C# and similar languages. A lot of people who use those languages care about correctness, and Rust is bi…

This is also one of the problems with programming with exceptions. You lean on the fact that an exception will be thrown and just propogate up until it finds something, so the normal mindset of an exception-based programmer is to program for the happy-case and only vaguely think about what happens if it goes wrong. I know, I've written a lot of code in this style for many years myself. In some cases, that's not a pro…

Exceptions and Maybe types aren't mutually exclusive. They should be used together. Maybe types handle variability that is expected and predictable, like a dictionary not having a certain key; exceptions handle the unexpected situations, like a file handle being closed too early.

Maybes explicitly express what the programmer has foreseen, exceptions form a safety net over it. You need both in a wholesome language. That's wht even Haskell has exceptions.

Re: The general value of typed functional programming lies in leaving no edge cases

#90
post #78

Earlier quoted context omitted.

> You can create a type that can encompass all kinds of edge cases and information about them. This is not unique to functional programming languages. Haskell was definitely a trailblazer for this, but plenty of conventional languages support this now with relative ease.

Any language with a type system at all can create a Maybe type. The difference is that failing to handle the None case is a runtime exception in most languages where in Haskel/Rust it won’t compile. I don’t know of any mainstream language that has bolted on that level of verification.

Scala3 and Kotlin.
Post reply on HN