Hacker News new | past | comments | ask | show | jobs | submit login

I agree with everything except Go is fun or the assertion that it combines best of both dynamic and statically compiled languages. It is a minimalistic get-it-done language, I would say it is 'modern java'. There are no aha moments that you experience while learning go. It always feels like - ya, I have seen that. Go did not take the best of the pre-existing languages, it took the minimal set that made sense to the designers; for example: it omitted 'best' features like map, reduce and filter in favour of 'plain old boring' for loops. I wonder how many programmers can wake up in the morning and say to themselves - wow, I am going to program in Go today.



Go's aha moment is its low cognitive overhead. It eschews power and conciseness for clarity, everywhere. It takes the exact opposite approach to functional languages, preferring boring simplicity to powerful but cryptic abstraction.

It turns out that an uncompromising devotion to clarity is quite powerful in its own right. It's not right for every use case, but highly compelling for many.


You're mistaking familiarity for simplicity. You cannot get much simpler than the lambda calculus, full stop. It has three concepts--lambdas, variables and application--and one evaluation rule. That is all. The rest of the language features are almost always just a thin layer over this.

Even when you add types, it's still an amazingly simple model. And the types do not generally affect the runtime behavior of code at all.

Functional languages are the very picture of something simple but not necessarily easy. Go, at least for you, is the opposite: it's easy because it's similar to what you're used to, but it also has quite a bit of surface area.

My impression is that Go vies for simplicity of implementation over simplicity of semantics. It is a very operational sort of language. Its goal is to make the how clear--the code reflects what it does.

Languages like Haskell, on the other hand, are completely the opposite. Haskell values simplicity of semantics over simplicity of implementation. It is a very denotational sort of language. Its goal is to make the what clear--the code reflects what it means.

It's a difference in philosophies, certainly, just not quite in the way you construed it to be.


Yes!

Exceedingly simple semantics combining to form a difficult-to-use language is often called a "Turing Tar Pit," a place where everything is possible but nothing of interest is easy.

Conway's Game of Life is even simpler than the lambda calculus, and people build all sorts of amazing things in it, but examples like a calculator that outputs human-readable digits are circus tricks.


>Exceedingly simple semantics combining to form a difficult-to-use language

Who was suggesting that we should form difficult to use languages on those simple semantics?


Nobody, I was just introducing the term "Turing Tar Pit" for those who hadn't heard it.



Go's aha moment is its low cognitive overhead.

I think some of us already had that with the first Java versions. Actually, Go looks a lot like old Java versions, minus the VM, plus Goroutines/channels, and static duck typing.

I have written a fair share of Go code and ultimately it's a very boring, but predictable language. If it builds a larger ecosystem, it will not be much different than a Java that compiles to native code. Without some of the advantages of the JVM.

(What we are really seeing here on HN lately is a hype, pretty much like node.js and FP before. Go has a better chance to stick, because it has a good steward.)


I kind of agree with that, but Java really needed a reboot. It's more a cultural thing than a technological one.

But I'm actually a bit cynical about that. Pretty soon the framework peddlers will descend on Go just as they have descended on Java, JavaScript and Python. Once again a couple of switch statements will be replaced by tens of thousands of lines of framework code.

It will be called "beautiful" and "elegant" and "DRY" and those still complaining about the bloat will be told that they don't have to use the features they don't need, but not knowing all the features and all the hooks and all the optimization tricks will once again make you look incompetent and behind the times.


Yeah, it's the Java culture and the stuff bolted on top by Sun and other business software vendors in an effort to keep relevant and appeal to CIO:s.

But I don't agree with the prediction: Python and JavaScript aren't really drowning in BS produced by architecture astronauts. It exists but it's not prevalent.


Java platform has already had plenty of reboots.

Play, Grails and Vert.x have shaken up web development. Scala, Groovy and Clojure for languages.


> If it builds a larger ecosystem, it will not be much different than a Java that compiles to native code.

True, and we already have that for those willing to pay for Java native compilers.


Honest question: what do you consider the advantages of the JVM over native code?


- "Write once, run everywhere." as the sibling poster mentions. I can build on my Mac, deploy on whatever the server platform is.

Snapshot and release builds of our build server are distributed via a Nexus-managed repository. So, everyone codes against exactly the same dependencies, regardless of the platform.

- Hotswapping/JRebel.

- Good interoperability with other languages. E.g. the Typesafe folks implemented Akka in Scala. Java gets it for (well, almost) free.

- Easy monitoring and instrumentation.

Obviously, there are downsides as well, such as startup times (twofold: starting the VM and Hotspot detection/compilation), preset heap size, expensive JNI (native interface), etc.


> Write once, run everywhere

Well, so Go is "write once, build 3-9x, run anywhere".. close enough ;)


i think i would rather build a binary for each platform and run as fast as possible than to build once and run slow on all platforms.


Except that Java code typically runs as fast or faster in the JVM than compiled Go code[1]. Of course, Go is still new and gc and gcc-go will be optimized further.

But Java bytecode execution is definitely not slow and usually within 2x the execution time of a C implementation, which is faster than the vast majority of other language implementations.

[1] At least in the language benchmarks game. Yes, I know that microbenchmarks are not representative, etc. etc. etc. (Until your favorite language is faster ;).)


Java is a damn memory hog, but for server-side kind of stuff, not really slow.


Only it's the reverse. Java runs faster than Go.


For now, if this continues to narrow it will not be true much longer: http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?t...


This is a false dichotomy.


Well-defined semantics, including for "errors" like integer overflow or null dereference.

A community that's converged on a deterministic, crossplatform way of representing library dependencies (maven).

An ABI that includes a notion of objects, which makes cross-language interoperability with objects easier (though counterbalanced by not having a cross-language notion of functions).


Definitely deployment flexibility. Write on OSX, Test on Linux, Run on Solaris.

But also performance. JVM can be faster than say C/C++ code in many cases.


"Write once, run anywhere"


I've heard this far more commonly from Java programmers as "Write once, debug everywhere", but maybe that's changed. (this was quite some time ago)


Go's aha moment IMHO is at the edges. If you have built a complex application (250k+ lines) in C++, Python or Java you know about the quiet undignified pains those projects often suffer.

- Horrible build systems (and horrible build times)

--- Go compiles fast, and the compile and dependency system is baked in

- Impossible to untangle dependencies (don't ever remove an include, who knows where it is used)

--- Go forces you to either use a dependency or remove it, stopping dependency cruft from ever building up

- Nightmare deploys (system wide assumptions)

--- Go deploys with a single platform dependent binary, it is absolutely awesome

- Inconsistent formatting, self-directed standards on formatting.

--- Gofmt is the one true format, heck, even some bad formatting won't compile (try to uncuddle your else to see)

- Inconsistent build systems and build system quality, made worse by using libraries and systems that have their OWN build systems.

--- Go get combined with its include system (use it or lose it) really let you tie together systems in a sane way without any custom build routes.

- Dealing with modern concurrency

--- Go having built in channel communication makes many problems trivial, and allows new methods of abstraction (goes to Go's model of composition).


I'll take Java as an example, since I only use Python for short scripts.

- Horrible build systems (and horrible build times)

Maven is a great build system, Java has good compile times, and most modern Java IDEs have incremental compilation. And you can specify versions of dependencies, rather than having to maintain a list of SHA1 hashes of versions considered to be stable.

(don't ever remove an include, who knows where it is used)

This is primarily a problem in C/C++, where one can indirectly get the correct dependencies by accident. Most modern compiled languages don't have this problem.

Go forces you to either use a dependency or remove it, stopping dependency cruft from ever building up

Which can be annoying for debugging. I'd rather have my IDE or linter give warnings.

- Nightmare deploys (system wide assumptions)

'mvn package', it's also easy to configure maven to build an archive with dependencies, configuration files, or whatever you'd like to be in a deploy.

In fact, deployments are even easier than in Go, since my package built on OS X will also deploy on a Linux server. My colleagues use different platforms (a mixture of Linux, Windows, and OS X) and it's never a problem.

- Inconsistent formatting, self-directed standards on formatting.

It's good that the Go team made a standard formatting. That said, my employer has a default layout. It's a matter of importing an XML file in Eclipse or IntelliJ and everything is in company layout (yay).

- Inconsistent build systems and build system quality

Nearly every Java library is available via Central Maven Repository. Including versioning :), meaning that if upstream changes their API, it's not your problem. In contrast to Go repository/packages.

Dealing with modern concurrency

Ever heard of Actor models and Akka? Composable concurrency, across more than one machine. With supervision, routing, etc.


You are right, it is just as simple as using Java, Akka, Maven, working at a company with a good standard formatting and structure and being forced to use an IDE with conditional compilation and only using packages that support Maven and put themselves in the Maven Ultra-Centralized Repo.

Or you could use Go and the text editor of your choice.


Stop being so silly.

  brew install maven
And use the text editor of your choice.

(Or you could just install IntelliJ and get a stellar development environment with nearly everything you'd ever need.)


>Go's aha moment is its low cognitive overhead.

You mean its strength is that is a Blub language?

Because the "low cognitive overhead" is exactly what Java was touted for, back in the day (before the EE madness).


It may make the blubs more effective, but that doesn't necessarily mean it can't also make the geniuses more effective too.


"Blub" refers to the language itself, rather than the developers. As in "think (no deeper than) in Blub (language concepts)"

I can see both sides of the "clever is better/worse" argument, though. E.g. - C++ operator overloading is powerful and harmful.


> Go's aha moment is its low cognitive overhead.

Very good for replaceable programmers, the dream of every manager. :)


Simplicity in design is still a panacea, only good programmers can do it on non trivial systems. Go will allow for better clarity, but beautiful code will not write itself.


Low cognitive overhead is also good for your future self, that will have to maintain the 'clever' mess which you wrote in a hurry ... In my experience so far, the abstractions that Go offers for writing concurrent code are very nice and easy to understand, and deploying it is really good - it generates static binaries, which you simply upload where you need them. It is a very practical language.


>It takes the exact opposite approach to functional languages, preferring boring simplicity to powerful but cryptic abstraction.

Yes, functional programming is based on the idea that abstractions should be cryptic. That's a very reasonable observation, and not at all ignorant.


Thanks for reading my article. It is my opinion that Go is fun, but it's just that, an opinion. I'm glad we have the diversity in programming languages that allows us to pick what we like (esp. when it comes to the server). Best.


If you don't think Go is fun, you've never made a channel of channels of functions.


I do look forward to programming in Go. My day gig is working with PHP and horribly written Python (globals everywhere). Go is, simply put, refreshing. So much, that I'm moving away from Python as my go to web language to Go.


Spoken like someone who hasn't written much Go, or at least hasn't used it for what it's best at. I suggest you read Effective Go and try writing some concurrent applications. It's aha moments are plentiful once you realize the power in the simplicity.


I have written Go code, and what the language offers is no different from java.util.concurrent, .NET TPL, C++ Cilk, PPL, and many other frameworks offer.


Goroutines aren't really the selling point. It's simple enough to implement similar concepts in any language. It's the combination of a set of complimentary features, the maturity and the stability that really sells Go.


They might be for programmers who don't have threads. Maybe that explains why its so popular with Python/Ruby/PHP folks?


You can't call Go mature.


> it omitted 'best' features like map, reduce and filter in favour of 'plain old boring' for loops

Well, it included closures, so luckily it's trivial to add those after the fact.


Yeah, per type or with interface{}, where every function has to do run-time introspection.

Maybe trivial, but not lots of fun.


Go has first-class functions, so if you want map/reduce/filter there's nothing stopping you.


Except that you lose type safety (or write an implementation for every permutation of types..)


Didn't realize that, thanks.


Go doesn't have parametric polymorphism. So yeah, there is something stopping you.



Yes, stopping me. "You can resort to a horrible ugly cludge and lose type safety for your efforts" is not having parametric polymorphism.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: