'Knowing Perl' is a rather hard thing to do when the list of completely ad-hoc implicit variables and hidden context-sensitive surprises is seemingly endless.
Your grasp of English seems to include subject-verb number agreement, and I suspect you can handle pronouns. You'd do just fine with Perl.
Yes, lots of tutorials explain it badly, and yes, lots of people say "Why should a programming language take cues from natural language?", but implicit variables and context are concepts that primary school children have mastered. They're not that difficult.
Yeah, that was not my point. These aren't but idiosyncrasies of Perl's design, and to model itself on constructs which evolved without direction and which take years to master, just to save a keystroke or two once in a blue moon, is a rather questionable road to take.
Seriously, in what other language don't you ever finish discovering what's on the default namespace, what side-effects any given statement, or hell, expression has, or which syntactic forms are supported, and on and on?
Well, PHP, but we know what the connotations of that are.
And by the way, I'm doing rather 'fine' in Perl, if not for the ever-present worrying about type mismatches (particularly arrays), the frustration of how dirty many operations are (unless you are using a recent version, regex substitution must mutate a variable), the laboriousness of the stock error handling mechanisms (make your own stack trace!) and so on.
I think mattacular wrote about the run-of-the-mill programming blog that gets submitted to HN. They feel more substantial than one of those spammy "125 free icon sets that'll turn you into a Design god", but they're mostly half-baked regurgitations of Software Engineering folk-wisdom, rehashed from a dozen other blogs which quote some testimony from a famous book.
No code, no maths, no algorithms, no statistics, no nothing.
A well known and tested approach, sum types (tagged unions), would have been way better, but it was cast aside because the designers were apparently unaware of the improvements to union types made since C's inception:
There is no reason for any new language to lack tagged union types. It disturbs me that Brian Cox rejects a simple, proven language feature that he does not even understand, even though it would take all of 2 minutes of searching/reading to understand. I'm sure he spent at least that long composing the replies in that thread, never moving past the ego-threat of "will Go ever have X?" to honestly evaluate the question.
"There is no reason for any new language to lack X" is false for all X. Languages differ in their goals, and there's no feature that all languages have to have. Even basic features like assignment can be questioned.
You're jumping to a false conclusion that Go's designers were not aware of those language features, and that that was the reason why they aren't in Go.
You said that sum types were omitted from Go because the designers were not aware of more recent developments. That's not true. They were omitted because they do not mesh well with the other features of the language, such as zero types, interfaces and embedding.
Whether you agree with that latter point is moot. Go's designers were and are fully aware of sum types; they chose to omit them from Go for a reason, not because they were ignorant of their existence.
Isn't the ecosystem always trotted out while defending PHP, as well as its 'accessibility' to amateurs? Well, those amateurs are part of the PHP ecosystem, and you'll have to put up with that... or not.
Who said anything about coolness? Seriously, why do people think that just because all languages are Turing complete, any further discussion is just a popularity contest?
The point is that if you know one of the languages cited by the parent ("C++, Perl, and even PHP"), then you do make your life easier by working with that language rather than choosing one which you don't know.
All other things being equal, sure, choose the maximally powerful language in whichever dimension makes sense. But all other things are usually not equal.
If you are working on a project by yourself, here are some things which are more important than the characteristics of the language:
- your knowledge of the problem domain
- your knowledge of general software development
- your knowledge of the limits, capabilities and ecosystem
of the language (aka project experience)
Also, if you're working with others, the following factors are more important than choice of language:
- your customer's expectations (if you're shipping software to them)
- the ability to recruit experienced individuals for your project
- the availability of mentors / reviewers within your organization
- the availability of secondary resources (books, FAQ, etc)
Not 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.
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"?
> 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.
it 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?
> 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.
It'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).
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.
What 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.
The 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.
I think if they add sum types and pattern matching or otherwise make this feature possible, it will completely change the way people write Go code and it would become a very different language.
Consider all the error-checks in Go -- these are all incorrect from a boolean-blindness perspective, and that would be a lot of code to rewrite if they add proper constructs to Go. Thus, I really believe it is just a mistake -- one that is only possible to make out of ignorance.
Because Go is concurrent and has mutable types, race conditions could cause the assumptions gleaned from the booleans to be false in the very next statement. Boolean blindness is a result of the language.
No, that's false -- consider the Maybe case. If you carry around the content of the Maybe, it will still remain valid even after the Maybe itself is overwritten. Races are of course still possible but they don't relate to boolean blindness.