4 ms·
> 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
by munchbunny 7y ago
> 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.
- Spivak 7y agoAny 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.
- Scarbutt 7y agoScala3 and Kotlin.
- still_grokking 7y agoYou 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.
- skybrian 7y agoKotlin 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.
- acomar 7y agothat 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?
- still_grokking 7y agoIt'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.
- dangets 7y agoKotlin 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 { } }
- still_grokking 7y agoSure. 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-31d69f630a8b https://proandroiddev.com/til-when-is-when-exhaustive-31d69f...
- heartbeats 7y agoC. typedef struct{int filled; union{void* data;} val;} maybe;
- marcosdumay 7y agoHow does that fail at compile time if you try to read a value when there is none?
- madmax96 7y agoSome 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 https://web.stanford.edu/~engler/mc-osdi.pdf
- heartbeats 7y agoIf 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.
- deleted 7y ago[deleted]