6 ms·
I may be mistaken, but I believe type switches in Go address this criticism: type Fruit struct { Name string Species string } /
by zemo 14y ago
I may be mistaken, but I believe type switches in Go address this criticism:
type Fruit struct {
Name string
Species string
}
// define a method on Fruit structs named Rename
func (f *Fruit) Rename(s string) {
f.Name = s
}
type Candy struct {
Name string
Company string
}
// define a method on Candy structs named Rename
func (c *Candy) Rename(s string) {
c.Name = s
}
// any type that defines a method named Rename is also
// of type Renamable.
type Renamable interface {
Rename(string)
}
// produce something that implements Renamable. Its
// fields will be unknown, but the method Rename will be
// known to exist.
func SomeProducer(...) Renamable {
...
}
x := SomeProducer(...)
// at this point, x is of type Renamable. We do not
// know what fields it has. The only thing we know is
// that it has some method named Rename that takes a
// single string for its only argument and returns
// nothing.
switch t := x.(type) {
case Fruit:
// T is of type Fruit, while x is of type Renamable
fmt.Print(t.Species)
case Candy:
// T is of type Candy, while x is of type Renamable
fmt.Print(t.Company)
default:
// some other type.
}
it's in the Switch section of the Go spec: http://golang.org/ref/spec#Switch_statements http://golang.org/ref/spec#Switch_statements
- AnswerAndForget 14y agoNot exactly. You see, you have to define new types from scratch with your approach. With Haskell's approach, you just have to use the Maybe parametric type, which just needs to be defined once. In other words, you just go and use a generic type instead of writing your own, like new List<Integer> instead of new ListInteger in Java.
- zemo 14y agounless 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.