News for hackers. Stuff that matters.
Re:The general value of typed functional programming lies in... by hristov on Monday February 24, 2020 @11:57AM (#22405781)
I am not sure this is the only value, but it is generally true. And this is one of the great advantages of haskell.

By the way, now that I know some haskell, I see this edge case sloppiness all the time and it is really annoying. For example, here is something that annoyed me just recently. You go to yahoo finance and there they will show you the revenues of a company as well as the revenue growth from past year. But sometimes this revenue growth number is not available. For example, the company may not have existed past year, or perhaps it was not public past year and thus it did not publicly disclose its revenues. When they cannot compute revenue growth for these reasons, yahoo finance will helpfully show revenue growth as "N/A", i.e., not available.

That seems all nice and logical, but I noticed that yahoo finance tended to show that revenue growth was not available for many established public companies for which they should have the data. I looked at it more closely and noticed with shock that if the revenue growth of a company was about 0%, yahoo finance would still show it as "N/A"! So some programmer just decided to use 0 as not available and just erased a lot of useful information from their system. Now when I see a company that has N/A as revenue growth on yahoo finance I have to go and check whether the revenue growth was zero, or it was truly unavailable. As I said -- really annoying.

This is of course a textbook case for Haskells Maybe concept. You can have a type that is a Maybe Int, and that means it have a value or it can be Nothing. Thus, you encompass the edge case of not having the value available, without using an embarrassing hack that deletes real data. But of course Haskell gives you more power than just using Maybe. You can create a type that can encompass all kinds of edge cases and information about them. For example, you can embed a reason why the revenue growth data was not available, if that is the case.

Re:The general value of typed functional programming lies in... by dmitriid on Monday February 24, 2020 @01:47PM (#22407050)
> This is of course a textbook case for Haskells Maybe concept. You can have a type that is a Maybe Int, and that means it have a value or it can be Nothing. Thus, you encompass the edge case of not having the value available

If you encompass it this way. Literally nothing stops you from encoding this behavior in Haskell. Because the behavior you described is *if revenue is equal to zero, display it as N/A".

No magic monad will prevent this.

Re:The general value of typed functional programming lies in... by BoiledCabbage on Monday February 24, 2020 @03:07PM (#22407883)
No, but it's the difference between implicit and explicit stupidity. All of us do implicit stupidity all of the time - it's human nature (or more accurately a side effect of working in a difficult field). When transformed into a choice between explicit stupidity, or doing things the right way, we instead usually choose to to do things the right way -- or at minimum do it the wrong way to test something out then change it to the write way. Being explicit is what makes that change likely to happen, rather than just be ignored.
Re:The general value of typed functional programming lies in... by dmitriid on Tuesday February 25, 2020 @02:54PM (#22416732)
No. No matter how much you dress it with words, technology is not magic. Monads are not magic. Haskell is not magic.

If your data and/or problem is modeled as "if 0 then N/A" no amount of "human nature implicitly explicitly transformed" will help you.

Dealing with non-existent data as opposed to "value = 0" is just as natural in Java, C++ or Javascript as it is in Haskell. And yet, that didn't help.

Re:The general value of typed functional programming lies in... by munchbunny on Monday February 24, 2020 @01:04PM (#22406507)
> 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.

Re:The general value of typed functional programming lies in... by Spivak on Monday February 24, 2020 @01:14PM (#22406626)
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.

Re:The general value of typed functional programming lies in... by heartbeats on Monday February 24, 2020 @03:19PM (#22408006)
C.

  typedef struct{int filled; union{void* data;} val;} maybe;
Re:The general value of typed functional programming lies in... by marcosdumay on Monday February 24, 2020 @04:36PM (#22408709)
How does that fail at compile time if you try to read a value when there is none?
Re:The general value of typed functional programming lies in... by madmax96 on Monday February 24, 2020 @04:58PM (#22408907)
Some of Dawson Engler’s work helps solve this problem, starting around [1]. In that, he shows us how to write custom compiler rules in a high-level language. These rules are sufficient to enforce that maybe type. In another paper, Engler (or one of his several talented students, can’t remember now) shows us how to automatically infer many of these rules.

[1] https://web.stanford.edu/~engler/mc-osdi.pdf

Re:The general value of typed functional programming lies in... by heartbeats on Monday February 24, 2020 @05:19PM (#22409040)
If you try to use it val directly, it fails. You must unpack it first.

To do something like x.get() in Scala when x is empty is a runtime error, not a compile-time error.

Re:The general value of typed functional programming lies in... by Scarbutt on Monday February 24, 2020 @01:39PM (#22406955)
Scala3 and Kotlin.
Re:The general value of typed functional programming lies in... by still_grokking on Monday February 24, 2020 @02:14PM (#22407324)
You mean Scala 2. And likely even Scala 1 had this. (Scala 3 is still in development).

But Kotlin? Since when does Kotlin have pattern matching with exhaustive checks? Also it does not have an `Maybe a` / `Option[A]` type out-of-the box.

Re:The general value of typed functional programming lies in... by dangets on Monday February 24, 2020 @03:46PM (#22408253)
Kotlin will do exhaustive checks in a `when` block when it is an expression. You can add a `.let { }` at the end of the when statement if you want to enforce this and not really return anything.

    sealed class Communication
    data class Email(val emailAddress: String) : Communication()
    data class Shouting(val preferredName: String) : Communication()
    object HiveMind : Communication()

    fun exhaustiveWhen(comm: Communication) {
        // not exhaustively checked (will compile)
        when (comm) {
            is Email -> println("sending email to ${comm.emailAddress}")
        }

        // *is* exhaustively checked (error at compile time)
        //  must add HiveMind or 'else' branch
        val result = when (comm) {
            is Email -> println("sending email to ${comm.emailAddress}")
            is Shouting -> println("HELLO, ${comm.preferredName}!")
        }

        // *is* exhaustively checked
        when (comm) {
            is Email -> println("sending email to ${comm.emailAddress}")
            is Shouting -> println("HELLO, ${comm.preferredName}!")
        }.let {  }
    }
Re:The general value of typed functional programming lies in... by still_grokking on Monday February 24, 2020 @05:14PM (#22409013)
Sure. But that doesn't look helpful to me as it works only sometimes…

Even the syntax can be made less awkward[1] this look still like a wonky hack to me where the user can do way to much wrong.

[1] https://proandroiddev.com/til-when-is-when-exhaustive-31d69f...

Re:The general value of typed functional programming lies in... by skybrian on Monday February 24, 2020 @02:36PM (#22407560)
Kotlin distinguishes between nullable and not-null references, which is an alternative to the maybe type. It serves roughly the same purpose, to replace runtime errors with compile-time verification that you haven't missed a corner case.
Re:The general value of typed functional programming lies in... by still_grokking on Monday February 24, 2020 @04:59PM (#22408917)
It's not an alternative for a Maybe Monad. It's an orthogonal concept.

Whether a type is nullable or not is a property of the type. This creates more or less two mirror universes of types, and you can't mix even "the same" types from that incompatible universes.

An Option type is on the other hand side a distinguished parametric type on its own (I wrote `Maybe a` / `Option[A]` for a reason). It can "wrap" arbitrary other types without "infecting" those with the nullability property. Being a proper parametric type makes `Maybe` / `Option` also "just a type constructor". Therefore it can be composed with other types and type constructors according to common rules. `Maybe` / `Option` doesn't require any special rules in the language (which would make the language more difficult to learn and use)!

Also `null` is very different form `Empty` / `None`: A null value can still "sneak in" through arbitrary references and cause run-time errors if one has to interoperate with a "null unsafe" language or system (and that's more or less "the whole universe" out there). A `None` can not "sneak in" as it can be only assigned to something of `Option` type. Sure this doesn't solve the "null problem" as such but one can at least distinguish the cases where the model value is really optional, and the cases where one needs to deal with `null`s coming (potentially) form the outside world. In the one case one will use the Option type throughout the rest of the program, in the other case one will preform some null-check as early as possible and "unwrap" the underlying none-null value to work with it directly thereafter.

Re:The general value of typed functional programming lies in... by acomar on Monday February 24, 2020 @02:47PM (#22407670)
that prevents you from assigning null to a non-nullable reference. does it also error if you dereference a nullable reference without first checking if it's null?
Re:The general value of typed functional programming lies in... by waheoo on Monday February 24, 2020 @12:57PM (#22406445)
Ive noticed other languages with this feature, they call them optional types, you can pass in a null or a type value.

/s slightly, maybe more snarky, but seriously, optional types are way overhyped. Null objects are far more useful than optionals. Optionals tend to leak all over the show.

Re:The general value of typed functional programming lies in... by bobbylarrybobby on Monday February 24, 2020 @05:45PM (#22409260)
The point of optionals is that they leak, and leak visibly. You cannot use an optional where a non-optional is expected, whereas in C nothing will stop you from writing `x->y` when x is, or might be, NULL. Thus the optional (and non-optional) types turn null pointer errors into compiler errors.

If you wish to reduce "leakiness", you can dispatch on the null-ness of the variable; Swift lets you write `if let x = x { /* x is non-optional in here * / }`, which binds a non-optional value inside the braces, and `guard let x = x else { return } /* x is non-optional now * /` which binds a non-optional value after the braces. So as soon as you consume an optional value, you are free to "un-leak" it and extract its value (if it has one) immediately.

Re:The general value of typed functional programming lies in... by K0nserv on Monday February 24, 2020 @02:13PM (#22407314)
I upvoted you because I think it's unfair that you are being downvoted while contributing to the discussion, that said you are completely wrong. Without Optional/Maybe nulls leak everywhere except you have no idea where they are. This leads programmers to engage in defensive programming for all references since there is nothing to help them understand what they should expect to be null in some cases. Optional/Maybe encourages good data modelling by making values that might be missing very clear. It encourages a style of programming that eliminates these issue via better modelling or by rejecting bad data earlier.

For example consider a network response that in a JS app might be passed around as an opaque object. In a language like Swift this is infeasible, you have to transition from the network serialized version to concrete models at the network layer. If you encounter mismatches in the expectation of what is optional you have to handle it here at the edge of the program. This enables massively safer code and makes reasoning about your program much simpler if anything.

As a concerete example say an API response tells you if a user is verified(for some domain specific definition of "verified"), additionally you want to know when they were verified maybe to give them a hint when they need to do it again. You coudl model this as:

    {
      "verified": false,
      "verified_at": null
    }
before they have verified and

    {
      "verified": true,
      "verified_at": "2020-02-24T15:31:12Z"
    }
after they have verified.

In Swift this would then be modelled as

    struct Users {
        let verified: Bool
        let verifiedAt: Date?
    }
However this introduces an Optional which complicates code that needs to deal with users who are verified or not. Instead you could model the same thing and avoid this issue as:

    {
      "verification_status": {
        "status": "unverified"
      }
    }
for the unverified case and

    {
      "verification_status": {
        "status": "verified",
        "at": "2020-02-24T15:31:12Z"
      }
    }
for the verified case. In Swift this can be nicely modelled without any Optionals using an enum

    enum VerificationStatus {
        case unverified
        case verified(Date)
    }

    struct User {
        let verificationStatus: VerificationStatus
    }
Better optional value visibility leads to better data modelling.
Re:The general value of typed functional programming lies in... by Smaug123 on Monday February 24, 2020 @01:10PM (#22406576)
Nulls leak exactly as badly as optionals, except it's additionally impossible to tell where nulls have leaked to.
Re:The general value of typed functional programming lies in... by a1369209993 on Monday February 24, 2020 @02:28PM (#22407480)
Actually, nulls leak worse than optionals, because it's impossible to tell where nulls have leaked to (so you end up forgetting to filter out a null at a interface where you would have decided to filter out a maybe).
Re:The general value of typed functional programming lies in... by baseballdork on Monday February 24, 2020 @01:06PM (#22406536)
I don't understand. In this situation an optional type is a reasonable solution to the problem: None => N/A, Some(0%) => 0%.
Re:The general value of typed functional programming lies in... by heavenlyblue on Monday February 24, 2020 @01:09PM (#22406571)
Only if you are speaking of Scalia?
Re:The general value of typed functional programming lies in... by swirepe on Monday February 24, 2020 @01:19PM (#22406675)
>Scalia

:)

Re:The general value of typed functional programming lies in... by justAnotherNET on Monday February 24, 2020 @12:48PM (#22406347)
Swift has this as well, but calls them “Optional”. The concept is definitely useful!
Re:The general value of typed functional programming lies in... by davinic on Monday February 24, 2020 @01:11PM (#22406596)
Also Java has Optional<T> and C# has Nullable<T>.
Re:The general value of typed functional programming lies in... by LessDmesg on Monday February 24, 2020 @01:30PM (#22406828)
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... by howellnick on Monday February 24, 2020 @01:51PM (#22407082)
C# 8.0 introduced "Nullable Reference Types" (https://devblogs.microsoft.com/dotnet/embracing-nullable-ref...), which, if enabled, can help solve this problem.
Re:The general value of typed functional programming lies in... by navaati on Monday February 24, 2020 @02:41PM (#22407607)
> was blindly copied over from C++.

From C! AFAIK C++'s references can not be null!

Re:The general value of typed functional programming lies in... by dep_b on Tuesday February 25, 2020 @04:56AM (#22412012)
The big difference is that nullability is the standard in Java and C# while in Swift it's the other way round, it's non-nullable unless you clearly indicate it's not.