https://rwmj.wordpress.com/2013/07/03/golang-bindings-for-li...
There's still room out there for the C replacement language. Something with ML/OCaml-level of expressiveness but with a replaceable garbage collector might be the sweet spot.
https://rwmj.wordpress.com/2013/07/03/golang-bindings-for-li...
There's still room out there for the C replacement language. Something with ML/OCaml-level of expressiveness but with a replaceable garbage collector might be the sweet spot.
The `:=` does a fair bit for the programmer in cutting back on writing types. For me, the most needed place for type inference would be for writing anonymous closures (like what Rust has). In most other places, I am quite content with writing the types, particularly at the top level.
> Like what’s the point of all the odd rules around := vs =
The former is short-hand for variable declaration with assignment and type deduction, while the latter is just regular assignment. The primary benefit here is type deduction, which partially relieves the lack of type inference.
> and what types you can and can’t assign and pass to functions
Huh?
> And why do you have to declare imports, when the compiler could work them out for you (it’ll even moan if you import something which is not used!)
The compiler absolutely cannot work them out for you. If you have a package `github.com/PeepA/wat` and a package `github.com/PeepB/wat`, how will the Go compiler know which `wat` package to import?
The Go compiler merely moans if an import (or its alias) hasn't been used in the source file that it was imported in. I like this feature, even if it is a mild bother while debugging.
> Hello, world is about 8 lines of code. Camel case! Java rang, wants its boilerplate back.
It's two lines. [1]
> No breakthrough on error handling.
Breakthrough? I'm not sure what you were expecting, but I think the error handling is pretty sane and at least far better than error handling conventions established in C. It could be adjusted if sum types were added to the language, but that has its own trade offs.
If you desperately want exception-style error handling, then you can use panic/defer/recover, but it's frowned upon to overuse it.
> The whole design of GOROOT/GOPATH is completely broken. It’s actually worse than Java’s broken CLASSPATH crap which is some kind of achievement, I guess.
I have the exact opposite opinion. Did you know that you probably shouldn't be setting `GOROOT`? [2] After Go is installed, you just need to set `GOPATH` and add `$GOPATH/bin` to your `PATH`. That's it.
> It’s not even enforced error checking, so bad programmers will still be able to write bad code.
That is true, but Go's compiler forces you to address errors returned by functions that also return another value. You either need to explicitly ignore it or use the variable the error is stored in. (Lest you get an "unused variable" compiler error.) This doesn't cover all cases---like completely ignoring the return value(s) of a function---but don't throw the baby out with the bath water!
[1] - http://play.golang.org/p/ihEoJ0yL9I
[2] - http://dave.cheney.net/2013/06/14/you-dont-need-to-set-goroo...
> It’s not even enforced error checking, so bad programmers will still be able to write bad code.
Bad programmers will always be able to write bad code. You can't structure a programming language around preventing bad code without completely hamstringing the language.
You can only do this for sufficiently motivated and well-informed programmers.
> The design of Go's error handling mechanism, while not the worst approach imaginable, unfortunately makes the programmer exert extra effort in order to do the "right thing".
Most error handling mechanisms I've seen make doing of of the worst things imaginable (silently throwing away the error) the easiest thing to do. I'm not so sure it's any easier or harder to do the right thing in Go, in the particular context of a highly concurrent system.
EDIT: But I haven't investigated Erlang's mechanism yet. I've heard it's quite good.
Barely and badly: you can ignore the error and it's by far the simplest course of action. Contrary to Haskell where it is easier to propagate it, or Erlang where it is just as easy to turn the error into a fault if you don't want to handle it.
> don't throw the baby out with the bath water!
There is no baby in that bath water.
But hey, I guess I'll give you credit where credit is due: you do know Go's error handling is only an improvement compared to C's, although you still err in declaring it "far better".
> (and the one I picked is merely the worst, your hello world is as disingenuous as Java's with all newlines removed — a single line)
I ran `gofmt` on that code before sharing it, so it conforms to Go's "One True Style". More importantly, my "Hello World" is quite readable, unlike a single line Java "Hello World". This last point in particular addresses the OP's central point: that Go is just as verbose as Java because of the length of "Hello World".
No, it's got nothing to do with sum types, Erlang does not use sum types yet for all the similarity of Go's error handling to Erlang's, Erlang is vastly superior.
> I acknowledged that such enforcement was not exhaustive and that errors could be ignored by the user.
And that's insufficient, errors can almost always be silently ignored by the user (even in languages with sum types which turn errors into faults, you should be able to silence the fault). The issue in Go is that ignoring errors is the simplest thing you can do. And not only that, not ignoring them is a significant step up in complexity and amount of code.
> The issue in Go is that ignoring errors is the simplest thing you can do. And not only that, not ignoring them is a significant step up in complexity and amount of code.
I agree that error handling requires more code, but I disagree that it increases complexity. Most error handling cases I've ever written are just passing them up to the caller:
if err != nil {
return nil, err
}
That is not added complexity IMO---particularly since it is an extraordinarily strong idiom---so I suppose we are at an impasse.Yes, if 10 tokens, 3 lines and a conditional are not added complexity to you, I suppose we are.
I too thought this, until I took a couple of minutes to actually understand how it's supposed to be used. It's a very opinionated setup, but it seems well thought out.
Even if it were demonstrably true that functional programming languages are a "better" (leaving this loosely-defined for now) choice than Go in 100% of the circumstances in which one would choose to use Go, your argument still wouldn't hold water, as it neglects other important characteristics of a programming language that are neither quantifiable nor useful in the context of comparing programming languages, such as perceived simplicity and the ability to hold the entire programming language in one's head.
What's the value in denouncing a programming language because it isn't designed with your favorite programming paradigm in mind? That's just dick.
Also, are you really going to call-out Rob Pike and Russ Cox on whether or not they truly understand Functional Programming like you do?
Really? Really?
Could you please explain what you mean when you say they don't understand functional languages as well as you? The lack of eval() and code-as-data in Go? Something else?
Every pure FP approach to side-effects I've seen has been a mess, stuff like with-open-file. It's fine if that's the minority of your code and you're getting enough out of being able to pass code around as lists of nested statements to make that worth it. For go's stated use case, it's not worth it.
In any case, I don't even know what we're arguing about anymore. My point is simply that FP is not about having no side effects, and saying "side effects are important" does not argue against the value of other FP innovations, such as HM-style type inference, option types, pattern matching, first-class functions, algebraic data types, etc.
I'm saying that if Scheme, LISP and Haskell are all functional languages, obviously the type system is besides the point -- they're radically different in that aspect. Functional programming is about functions.
I never understood why anyone classified Lisp (typically CL) as a functional language, as it isn't any more functional than Python, Ruby or Perl.
Go seems to be pegged as a complement/replacement for C/C++/D(maybe no experience)/misc assembly. I don't see how functional languages will help at all for these tasks. You could argue maybe that security would be improved to a degree, but I really am having a hard time at imagining a low level driver being written in purely functional code. I know of only forth being used for some of those tasks in things like boot proms but that is a bit different in that it wasn't really an entire os built on top of things.
I find this somewhat ironic as I'm currently looking to replace a number of ruby/perl/shell scripts at work with go this winter. Not for any reason of maintainability, but the horrible task it is to deal with gems/cpan/"extras". And rather than program in pain with C I was thinking go would be a decent compromise as I can make rpm's rather easily for deployment and a makefile. Go seems to be perfect for these glue level things that escape the basic confines of most scripting.
But I don't know yet, this weekend is my "learn go and find a test framework like rspec in it" task. It looks similar enough to C that I could get up to speed ish in a day.
I take it the go vein is more akin to: everything a framework(insert noun here) does for you it does to you?
I wholeheartedly agree, note i've used ruby for about 10 years aka: before rails, and there are times I want to strangle rails with a garrote for some of its choices in how it does things.
Ranting done, do you/anyone have any specific codebases I should look to for a good example of go programming methodology?
The scripts that will be replaced tend to be fairly heave with i/o and other stupid process manipulation, i.e. detect that some subprocess sigtermed etc... pretty boring stuff normally but I use threading rather heavily in ruby at the moment. So doing concurrency a bit more easily would be nice, especially since most of the things are just i/o derivatives of pack/unpack calls on things across many many devices. I've tested out celluloid with ruby and its great, but again that gets to gem/dependency management horror.
Guessing I just need to work with it and I'll find things out. Should hop into a go irc channel if there is one on freenode.
How? That is precisely what I use haskell for, and it has been by far the least terrible programming experience of my life.
>'No side effects' is great for certain types of coding
That comment shows a very superficial understanding of functional programming. Side effects are never the whole point of what you are doing. You are assuming "no side effects" means you are limited in some way. That is incorrect.
Appeal to authority really only works if the people you mention are authorities. On what basis would any reasonable person conclude that either of the people you mentioned are authorities on functional programming? Have either of them even been willing to respond to the constantly referenced parametric polymorphism paper from the 1970s yet?
Excellent point. I agree.
However, my entire argument wasn't based on an appeal to authority. I included it as a snarky invitation to "lay it on the table".
I am not in either's fan club, and I find it easy to believe that they indeed do not understand functional languages.
Go was written at Google to solve very specific problems Google had. Looming large was the need for a C family language that implemented concurrency, fast compiles, and so on. The C family requirement is quite simple: most google engineers are young and don't know functional programming, have experience with Google's existing C/C++ code base, and they will be using Go to replace and extend existing systems already in C/C++. A new functional paradigm, nice as it is, would just get in their way. I'm not enamored by many features of the language, but I'm really hard pressed to say that those features do not solve Google's problems.
Stephen Wolfram writes about the birth of Mathematica: "Macsyma was written in LISP, and lots of people said LISP was the only possibility. But a young physics graduate student named Rob Pike convinced me that C was the “language of the future”, and the right choice." http://blog.wolfram.com/2013/06/06/there-was-a-time-before-m...
That's Rust: http://pcwalton.github.io/blog/2013/06/02/removing-garbage-c...
Regarding the semicolon rules, you won't like this observation, but in my 3 years of writing Rust the semicolon rule has literally has never led to a single bug.
However, I don't recall it being a problem in my experimentation with Rust either.
I'm a C++ developer and go so far as to make it harder. I map ; to <esc> in vim, and enter the actual char with a second ; (from from normal mode).
However, I hate semi colons so I agree with you there. You should check out the nimrod programming language.
Revamping I/O is very high on the list. Brian Anderson et al are working on it as we speak.
It's surprisingly logical and convenient. Everytime I `return null` (or just `null`) in CoffeeScript I wonder if Rust's way isn't beter.
The difference between ML and C++ is a tradeoff between efficiency and safety in my eyes. D comes from the C/C++ level of efficiency and improves safety. ML comes from a safe point and tries to be efficient.
Everyone is welcome to their opinion, but it'd be nice if they actually supported it with some explanation if they want to bandy it about in public.
But I'll explain the GOROOT stuff in a bit more detail ...
Basically the way it's set up prevents golang modules from being packaged up for Linux distros. There are two main problems. Firstly the 'go' utility tries to recompile installed modules, which isn't going to work as those modules are in files and directories owned by root and 'go' is not running as root. By very carefully setting up timestamps it's usually possible to avoid this, but it's fragile.
Secondly if you do install a golang package, you can't compile an alternative copy in GOPATH, because the one in the (root-owned) GOROOT overrides it. Which is dumb and backwards.
Also, you should not be installing third party packages in `GOROOT`. If you do, then yes, you're going to be in some trouble.
[1] - https://wiki.archlinux.org/index.php/Go_Package_Guidelines
Then maintain two different and distinct `GOPATH` directories. One for development libraries and one for other stuff.
'var' is not the type inference, ':=' is the type inference.
Or "got it" and didn't find it any that good, for the types of problems they work on.