Hacker News new | ask | show | jobs
by timtadh 4242 days ago
I feel like you haven't met a lot of Go programmers in that case. The programmers I have met who use Go or are interested in it are often genuinely good programmers. Of course there are "crowd" followers in any language as popular in Go but Go is not a "Blub" language nor does it attract Blub programmers.

Do I as a Go programmer sometimes wish that Go had feature X. Of course I do! I want that feature when I want that feature. But, I find Go to occupy an extremely practical position in my personal programming language continuum do to its fairly unique mix of features. Note, it is not the features themselves that are unique many languages individually have them. Indeed, they often also include features I miss in Go. Rather, it is the particular mixture which is useful.

EDIT: To respond directly to the Blub article.

Features pg calls out for LISP:

    Garbage collection, introduced by Lisp in about 1960, is now widely
    considered to be a good thing. Runtime typing, ditto, is growing in
    popularity. Lexical closures, introduced by Lisp in the early 1970s, are
    now, just barely, on the radar screen. Macros, introduced by Lisp in the mid
    1960s, are still terra incognita.
 
Go score card:

    Garbage Collection [x]
    Runtime Typing [p]*
    Lexical Clusures [x]
    Macros [ ]

    * Go has some dynamic typing capabilities but nothing like Python or LISP.
      Many would consider that a "good thing". It partially depends on what you
      are doing.
Go has a 3/4 on the score card of features. Macros are of course enormously useful but also very difficult to shoe horn into a c-family language properly since they need to be expanded at compile time (unless you just go ahead and embed you compiler backend into the runtime system of your language. That would be kinda of crazy/awesome but you could do it). Rust has of course proven the utility of such a choice.

I can't speak for pg, but Go has many fantastic features and is not a Blub. The features which are missing are not, by and large, features of LISP.

EDIT 2: To add some more fuel to this fire...

pg concludes the article with:

    During the years we worked on Viaweb I read a lot of job descriptions. A new
    competitor seemed to emerge out of the woodwork every month or so. The first
    thing I would do, after checking to see if they had a live online demo, was
    look at their job listings. After a couple years of this I could tell which
    companies to worry about and which not to. The more of an IT flavor the job
    descriptions had, the less dangerous the company was. The safest kind were
    the ones that wanted Oracle experience. You never had to worry about those.
    You were also safe if they said they wanted C++ or Java developers. If they
    wanted Perl or Python programmers, that would be a bit frightening-- that's
    starting to sound like a company where the technical side, at least, is run
    by real hackers. If I had ever seen a job posting looking for Lisp hackers,
    I would have been really worried.
Note, he explicitly says here: not all languages are the same. He would worry when a company wanted Python programmers. Why? Because to him Python mixture of features represented a nice chunk of what LISP is providing him. Let's do another score card:

Python Score Card

    Garbage Collection [x]
    Runtime Typing [x]
    Lexical Clusures [x]
    Macros [ ]*

    * It is somewhat possible through black magic hackery to create an AST level
      macro in Python. It is messy. It is cool. It's kinda crunky. And I am not
      sure anyone has ever seriously used this ability. It certainly isn't main
      stream. Checkout https://github.com/lihaoyi/macropy for inspiration.
Norvig agrees with this assessment: http://norvig.com/python-lisp.html . Given that many people are ok with moving from Python to Go <https://www.reddit.com/r/golang/comments/2aup1g/why_are_peop... it seems reasonable to conclude that Go is an exceptible replacement for Python. Something no one has concluded about Java (for instance).

Therefore, I believe pg would have been equally worried or almost as concerned about Go programmers as Python programmers.

4 comments

> Macros are of course enormously useful but also very difficult to shoe horn into a c-family language properly since they need to be expanded at compile time (unless you just go ahead and embed you compiler backend into the runtime system of your language. That would be kinda of crazy/awesome but you could do it). Rust has of course proven the utility of such a choice.

Rust doesn't do that. Rust expands the macros at compile-time. Integrating the whole compiler into the runtime wouldn't make much sense considering what area Rust is targeting.

It's also recommended to not link a crate that is used during runtime with the compiler or parser because they're fairly big and would bloat your final build by a large amount.

yep. I never meant to imply that rust macros were expanded at runtime. I was trying to use rust as an example of a c-style langauge with a nice macro system.
Actually, to be a little more constructive about this: I'd be really interested to hear from anyone who's used Go after doing a serious project in any of Haskell, Scala, F# or OCaml. All the Go advocacy I read seems to ignore that this language segment exists, and all the Go programmers I speak to seem to take a very "blub" position on features like pattern matching, ADTs, and the various things I'd summarize as "good type systems". So it would be great to hear from someone who's used these things seriously, understands their advantages, but still thinks Go is making the correct tradeoff.
I use Scala at work. I would rather write in Go than in Scala. While there are many things to like in Scala there are also many misfeatures such as the `implicit` key word which can create a lot of spooky action at a distance. Scala is an engineering tour de force and has many interesting ideas. However, I find that it has too many features and has a syntax with encourages obscure code. In contrast Go may be verbose at times but it is always very easy for me to read and follow.

I recently needed to dive into a legacy Scala code base which had not been worked on in a year. The engineer who had written it had moved on from the company and no one knew how it worked. The code was extremely difficult to read and reason about. Some of this was do to the programmer who wrote it but some of it was also do to language features. Is it possible write clear and concise Scala? Absolutely! But, the language does not necessarily encourage that style at this time.

Other functional languages I have used include: Scheme and SML. I want to check out OCaml next. I have also played around a bit with F* (not F#).

Languages without decent compile-time type systems are pg's own blub.
pg writes about macros as the top of the blub ladder whereas you mention compile-time type systems, but I'd say it isn't a ladder but a twin-peaked hill, i.e. strongly-typed lazy functional code (e.g. Haskell) and dynamically-typed variadic homoiconic code (Lisp). They have an "impedance mismatch" such that they don't inter-translate very well, unless they use clunky addons like Template Haskell macros or Typed Clojure annotations. The pure form of each language, however, is based on two mutually exclusive foundations, i.e. strongly typed auto-curried parameters vs variadic untyped macro parameters.

The strong typing and lazy evaluation of Haskell makes it easy for functions to take only one argument at a time. Although a function could take a tuple parameter, it is usually rewritten to take each component of the tuple as a separate parameter, which makes the strong typing and built-in currying simple, higher structures like monads possible, and a syntax to suit this style. Lisp functions and macros, on the other hand, must be variadic to enable the homoiconicity of the language. It's therefore much more difficult for parameters to be typed, or to curry them. The syntax requires explicit visual nesting.

The poster child of each style, monads and macros, are thus two peaks in language abstraction simply because of these different required foundations of each, and if you, lmm, have achieved Haskell-style enlightenment, then dynamic variadic homoiconic languages are your blub.

I use scala so I have both (somewhat clunky) macros and types. I am not unaware of the costs of clunkiness or the merits of the lisp approach, and I have not stopped looking for a language that can combine both advantages - in contrast to pg, who seems to dismiss the value of strong types without ever having used them seriously.
You're right, but don't assume that there are only two peaks. That's making the same mistake you're arguing against.
>Macros are of course enormously useful but also very difficult to shoe horn into a c-family language properly since they need to be expanded at compile time (unless you just go ahead and embed you compiler backend into the runtime system of your language.

No, that's not necessary at all, with Rust-like macros which are simple pattern->template things. Macros have zero runtime cost.

I totally agree I made this point badly.