6 ms·
unless I'm missing something, that seems to address a separate difference in the specifics of Go and Haskell's type systems, namely that Go's interfaces and Has
by zemo 14y ago
unless I'm missing something, that seems to address a separate difference in the specifics of Go and Haskell's type systems, namely that Go's interfaces and Haskell's sum types are different. Yes, they're different. I really only meant to say that the article is predicated on the notion that we're only able to branch on booleans instead of predicates. As for checking for null values...
var x *MyType
...
switch x {
case nil:
// blah
default:
// blah
}
tada, no boolean required, no having to "establish the provenance" of any bits. Sure, inside the nil case, the compiler doesn't actually stop you from unsafely attempting to access the fields of x, and, in that way, Haskell is safer than Go.
I'm not trying to assert that Go is better than Haskell or that they are the same; I've never programmed Haskell so I'm not qualified to make such a statement. I'm merely addressing the specific "Boolean Blindness" criticism.
I don't really think that criticism is in any way valid, since "Boolean Blindness" isn't a criticism of a language design, it's a criticism of how one might use a particular language. To say that Go committed "Boolean Blindness" is predicated on the following assumptions:
- you can only branch on a boolean
- given a value and a type, the only thing you can do is obtain a boolean indicating whether or not that value is of that type
as far as Go is concerned, those statements are factually inaccurate.
Given some variable `x` of unknown type, and a type `t`, is there some way, in Haskell, to create a boolean `v` such that the value of `v` is `true` when `x` is of type `t` and `false` otherwise? And if so, is there some way to branch on this boolean value `v`? Because if that is true, then how has Haskell not committed the same atrocity of "Boolean Blindness"?
- Peaker 14y ago> tada, no boolean required, no having to "establish the provenance" of any bits. Sure, inside the nil case, the compiler doesn't actually stop you from unsafely attempting to access the fields of x, But you do have to establish the provenance of your conditional. You have to keep track of whether you compared against nil yourself. Whether this is expressed as if(x != nil) or as a boolean-blind switch case, the information is lost and it is up to the user to keep track of the meaning of 'x' under all the conditions it is run. Of course Haskell is capable of expressing boolean blind and unsafe code. But Haskell, unlike go is also capable of expressing non-blind, safe code. Go is only able to express boolean blind code (again, it is not about a boolean condition but about whether branching buys you type information). When you compare against nil, it is up to you to keep track of the provenance.
- wonderzombie 14y agoit is up to the user to keep track of the meaning of 'x' under all the conditions it is run OK, so it's a bit like you're chaining assumptions together, rather than putting them next to one another? This makes Monads, esp. `>>=`, make a bunch more sense to me. Like, the difference is between chaining/linking two operations (incl. checking what `x` is), by using the result of one check as the input to the other, and basically putting two operations next to one another (not to say that the `if` is meaningless, just that once the `if` is evaluated, the associated block has to take the `if`'s word for it). The bonus is that Haskell handles the first part, the check, for you if you let it. It's an implicit (well sorta) and immutable precondition to whatever's next, at a logical/linguistic level. And I guess the reason why booleans in particular are problematic is because you're sorta bolting them on, and they inherently compress information into yes/no, which is otherwise not terribly useful for the block following?
- zemo 14y ago> You have to keep track of whether you compared against nil yourself. that's true in the case of comparing against nil, which I've already agreed with. I never said that Go is as safe as or safer than Haskell, I said that your assertion that there's "no way to branch and get type information" is a factual inaccuracy that misrepresents the language. The fact that you haven't commented on type switches in any way shows that you're not really interested in anything other than your own sense of superiority. Haskell is a better programming language. As a programmer of a programming language that is not Haskell, I am inferior to you. There.
- Peaker 14y agoIt's not just comparing against nil, it's any comparison or switch-case besides a type-switch. A type-switch seems to be non-boolean-blind indeed, but it seems to have too much syntactic overhead, as Go code generally uses if branches when a type-safe case is due (e.g: When analyzing return codes).
- zemo 14y ago>it seems to have too much syntactic overhead yeah, it's pretty ugly. I don't think anyone in the Go community would disagree with you there. >Go code generally uses if branches when a type-safe case is due (e.g: When analyzing return codes). Sure, that's mostly true of that use case. The difference is that if you return multiple values, one of which is an error, the other returned value is often the zero-value for that type. If you have an error, the other value isn't de facto nothing. I have to admit that I've never used that "feature" and I can't even contrive a hypothetical situation where I would want to. The reality is that it's not a sin to branch on a value. If you want to do something based on whether one date is earlier than the other, I can't see why you would need to bring a type system to a boolean party. I think Rob Pike summed it up really well, when he said something to the effect of "people ask me why we would make a language that's not theoretically interesting, and they're right; Go isn't very interesting from a theoretical standpoint, it's just useful". They're not really setting out to revolutionize programming theory; they're setting out to revolutionize programming practice. Go is designed to let large numbers of non-genius-level programmers make concurrent software that's pretty stable, while Haskell is designed to scare the everliving shit out of anyone that sucks at programming. From my experiences, the Haskell programmers that I know are probably the smartest programmers I know that have never made anything that's of any interest to non-programmers. That's not really meant to say something about the value of that type of programming; I think it's valuable, it's just not the type of programming that I'm interested in doing. A friend of mine that is a Haskell programmer once showed me how great of a programming language Coq is by showing me how to prove that multiplication is commutative, which is probably the most intellectually masturbatory thing I've ever seen anyone do with programming. Of course, some of my other friends who were into that type of programming thought it was very, very cool. By contrast, I made some toy that I showed to my infant niece and it made her giggle and that made me happy. The happiness of my users is more important to me than the purity of my code. So... it just depends what you want to do. I think you're actually correct, and I appreciate what I've learned about Haskell's type system, but I think you're just missing the point of the Go project or what makes people like it. They haven't set out to make the most perfectly safe, beautiful and pure programming language, because Haskell already did that and the world doesn't need two Haskells; we just need a saner Java for writing big concurrent programs that can quickly compiled to machine code.
- deleted 14y ago[deleted]
- blinks 14y agoI _think_ the complaint is the following: if x == nil { x.doSomethingCrazy(); // Runtime error? } else { ... } "Boolean blindness" (bah) is that either the type system should catch this at compile time (because we know x is nil), or the language should make it impossible to phrase (pattern matching to pull the information out, such as with the Maybe type). Go has many type system oddities (reflection instead of generics, for instance), but the things they _have_ done (auto-implementation of interfaces, for example) are pretty cool.
- Peaker 14y agoI find it unforgivable for a language in 2012 to repeat decades old design mistakes, and for no apparent benefit. What's worse is that it appears this was all done out of ignorance, not conscious choice.
- CasualSuperman 14y agoYou think Rob Pike and Ken Thompson made what you consider a mistake out of ignorance? Just because you don't like it doesn't make it a mistake.
- Peaker 14y agoWhat benefit does it have? What purpose does it serve? As far as I know, these guys have a reputation in industry moreso than in academic circles. It seems entirely believable that they have taken no interest in language design outside of industry, where the state of the art lags a few decades behind that of academia.
- CasualSuperman 14y agoThe benefit is not having to code it. The most bug-free components are the ones that aren't there. Also, it's only v1. I don't think anybody's said that they're opposed to putting it in, so give it time. Maybe file a feature request.