
Why Go? Use Racket - leanthonyrn
https://cxwangyi.wordpress.com/2012/07/22/why-go-use-racket/
======
jamra
I'm sorry you lost me after your outrageous claim that one must learn
everything about the standard types of Go before one can program effectively.

You should know about how your types are passed around if you are using any
language.

The example given was arrays in Go. Arrays are passed by value, but slices
(pointers to arrays) are passed by reference. This is very simply described in
the Effective Go reading. It's not a hard concept. I don't like you writing
off Go with that example. It sounds like you made an emotional decision
against the language and are grasping for logical reasons to support your
already made decision.

How many people programming with Go pass arrays around? It's an easy lesson to
learn.

~~~
eloff
There are many valid criticisms of go, but the one presented in this article
make no sense. Or maybe only make sense if you're a huge dynamic languages fan
and can't stomach static typing. Personally, as someone who used to be a huge
fan of dynamic languages like Python, I've sobered up as I've grown older and
had to fight with large python and JavaScript code bases. A compiler that is
fast with clear error messages is tremendously valuable.

~~~
Dewie
If using dynamic typing like Python's is being drunk, then at least Go is like
being tipsy - not quite sober, but quite functioning.

~~~
bkeroack
Only if you make a habit of using reflection (you shouldn't). Otherwise it's
designated driver all the way.

~~~
thomasahle
> Only if you make a habit of using reflection Or type switches. Or nearly
> anything involving interface{}.

------
nine_k
No. Because static typing.

However much Go's type system might lack some means of expression, the type
system is there, and it prevents many bugs that can easily crop up while using
a dynamic language.

I'd rather say 'use OCaml' or 'use F#' or even 'use Haskell'.

~~~
rdtsc
Or Clojure or Erlang. Funny enough out of "functional" languages those have
probably just as much (or even more) been used to develop distributed, fault
tolerant systems than F# or Haskell. Just saying.

BTW both Clojure and Erlang allow a form a gradual typing.

From personal experience. I've used both static (C#, C++, Java) and dynamic
typing (Python, Erlang), and have to say, the prevents-many-bugs excuse as the
main problem with dynamic types just wasn't true.

Maybe my code is more complicated and dealing with distributed state,
consistency, and protocols but what what kills everything is usually logic
errors, network failures, files not being there, misconfiguration, segfaults,
user-after-free, and the most evil ones, shared global states in a concurrent
shared-heap environment.

Things like "oh I expected an int but got a string" are pretty trivial and
easy discovered.

Moreover, in a recent service I implemented. I did in Python and I believe the
faster development time and less code to write in general, gave me time to
write better integration tests that exercises and covered the code a lot
better. I would have had to write the tests anyway, even if this was written
in Haskell.

Perhaps static typing helps a lot more in large code bases. Think of a large
game, or a CAD application or some huge C++ back-end. But, if you buying into
the whole micro-services fad, well, you shouldn't have large code bases if you
can help it.

Another big motivation for types, which I think most people have in mind when
they pick a strongly typed language is performance. Usually static typing and
a very large performance increase would go hand in hand. Now with the effort
put into v8 and PyPy we see that gap getting smaller.

~~~
lomnakkus
> Or Clojure or Erlang. Funny enough out of "functional" languages those have
> probably just as much (or even more) been used to develop distributed, fault
> tolerant systems than F# or Haskell. Just saying.

(I generally agree with the gist of your comment, I think. This just stuck
out.)

I don't believe Clojure belongs in that class (as "proven" for writing
reliable software), but whatever.

If you want truly reliable software and have the budget, then you just need to
throw _process_ at the problem -- it doesn't matter much which language you
use. Several (if not all) the Mars landers were programmed in C -- with very
few critical flaws experienced/discovered[2]. The Ericsson switches that
achieved previously-unheard-of reliability were programmed in Erlang, but they
used _process_ and a huge number of engineers to achieve that. (Plus they're
mostly stateless and so can just reset if they do it fast enough and don't
lose _important_ state when doing so.)

For large-scale software which _has to evolve fast_ , I belive strong type
systems do win out. It's not so much that they prevent bugs which could be
caught by test suites, but having a strong type system means that you can be
_certain_ that there are a _lot_ of tests that you actually will never have to
write or, more importantly, _rewrite_ as the system evolves.

There have been actual studies which may be of interest[1], but even if I'm on
the "winning" side, I don't think I would put too much stock in the
methodology/analysis of this particular study. (E.g. concluding that
JavaScript suffers from few concurrency bugs relative to other languages is
kind of being oblivious of the fact that JS is single-threaded (semantically)
and that all the other languages in the comparison permit "real"
concurrency/parallellism, and that it should thus perhaps be excluded from the
category or at least treated separately.)

[1]
[http://macbeth.cs.ucdavis.edu/lang_study.pdf](http://macbeth.cs.ucdavis.edu/lang_study.pdf)

[2] [https://www.usenix.org/conference/hotdep12/workshop-
program/...](https://www.usenix.org/conference/hotdep12/workshop-
program/presentation/holzmann)

(Sorry, references out of order because edited-post-facto)

~~~
mietek
_> If you want truly reliable software and have the budget, then you just need
to throw process at the problem -- it doesn't matter much which language you
use._

I also generally agree with your comment, but I have to take issue with this
statement. If this were true, Ericsson wouldn’t have had to abandon the AXE-N
project.

Quoting from Joe Armstrong’s PhD thesis[1]:

“1995: The AXE-N project was a project to build a “next generation switch” to
replace the Ericsson AXE-10. This extremely large project ran from 1987-95.
After the AXE-N project collapsed a decision was made to “restart” the project
using Erlang. This project eventually resulted in the development of the
AXD301 switch.”

“During the period 1996–1997 a three-person group (myself, Magnus Fröberg and
Martin Björklund) redesigned and implemented the OTP core libraries.”

“1998: Ericsson delivered the first AXD301. The AXD301 is the subject of one
of our case studies in Chapter 8. At the time of writing (2003) the AXD301 has
over 1.7 million lines of Erlang code which probably makes it the largest
system ever to be written in a functional style of programming.”

[1]:
[http://www.erlang.org/download/armstrong_thesis_2003.pdf](http://www.erlang.org/download/armstrong_thesis_2003.pdf)

~~~
lomnakkus
Thanks for digging out the history. I don't think we can conclude from your
excerpts that the deciding factor was Erlang. However, I accept that my
statement that it was "just engineers and process" may have been exaggerated
or mistaken.

~~~
mietek
The deciding factor, as always, is the ability to manage complexity. There are
many ways to improve this ability, and process is certainly one of them,
however, the choice of programming language is, to my mind, the most important
one.

XenSource/Citrix is another great example[1]:

“In 2002, members of Cambridge University released the open source Xen project
to provide free high-performance virtualization technology for the masses.”

“In 2004, the team founded the company XenSource and began developing the
enterprise-level distributed management software that would make
virtualization easy and form the backbone of their products in the years to
come. A team of thirty dedicated programmers in Palo Alto California began
developing the software in C, Python and Ruby.”

“Two years later, the US team had succeeded in burning tens of millions of
dollars funding but had failed to produce any product. So XenSource, under new
management, took the bold step of replacing their large team of US developers
with a team of only four British OCaml developers. Within months, all of the
Python and Ruby was replaced, both reliability and performance were
dramatically improved and the company shipped their first product. One year
later, XenSource sold to Citrix for $500M.”

[1]: [http://ocamlnews.blogspot.co.uk/2008/11/stunning-slides-
abou...](http://ocamlnews.blogspot.co.uk/2008/11/stunning-slides-about-growth-
of-ocaml.html)

~~~
lomnakkus
Indeed. I must admit that my pro-FP inner geek giggled just a little bit at
this bit of "money talks".

I think it's imperative to question the "reliability and performance were
dramatically improved" kinds of statements with quantitative research. It's
just that this kind of research is _insanely_ hard.

(Disclosure: I'm definitely on the FP team, but I want do be able to argue
_objectively_ and _quantitatively_ for the benefits of my approach.)

~~~
mietek
I fully agree. Have you seen the 1994 Hudak study[1]?

“A simplified version of real-world problem was chosen by the Naval Surface
Warfare Center (NSWC). This problem, a geometric region server (geo-server) is
one component of a much larger system, NSWC’s AEGIS Weapons System (AWS),
which NSWC is in the process of redesigning.”

“The participants, each considered an expert programmer in one of the
programming languages being tested, was asked to write a fully functional
prototype of the geo-server, while keeping track of software development
metrics such as development time and lines of code and documentation.”

“The results indicate that the Haskell prototype took significantly less time
to develop and was considerably more concise and easier to understand than the
corresponding prototypes written in several different imperative languages,
including Ada and C++.”

[1]:
[http://www.cs.yale.edu/publications/techreports/tr1049.pdf](http://www.cs.yale.edu/publications/techreports/tr1049.pdf)

~~~
lomnakkus
Yes, indeed, I've read it. Unfortunately, I think we should regard the early
studies (such as Hudak's) as basically preliminary and mostly not-well-
founded. I know that's horribly conservative, but y'know...

------
tedsuo
The OP's complaint about Go's type system seems to mainly be that memory
allocation is explicit.

Go is always "pass by value", and it's true that I've watched developers
struggle to grasp the full ramifications of what that means regarding memory
usage. But not understanding the subtlety of memory allocation usually means
your programs will simply run slower and consume more memory. It does not
usually mean that your programs will run incorrectly.

Given that the OP mentions that they find the slower, more expensive execution
of racket programs to be an acceptable trade-off, I'm surprised that they have
a problem with this.

Personally, I prefer running in a language that allows me to reason about the
memory allocation explicitly. I'd only prefer to give that up in favor of a
declarative language that could compute the optimal execution for me.
Unfortunately that language is a bit of a unicorn for general purpose
programming.

~~~
lucio
In Go you can pass a pointer, and a pointer to a pointer. I understand both
cases are usually called "pass-by-reference". If you call "pass-by-value" to
passing a pointer, then the notion of "pass-by-value" and "pass-by-ref" are
not very useful.

~~~
tedsuo
If what you are passing is a pointer, then the value of the pointer (an
integer) is copied. So pointers are passed by value.

"Pass by reference" means that the runtime will convert what looks like an
instruction to copy a value (such as a data structure) into an instruction to
copy only the address. Go has no such concept. You cannot make a new value
that is a "reference" to another value. If you make a new variable that takes
a value, that variable allocates a new block of memory the size of that value.
Assigning a value to the variable (or passing a value to a function) makes a
copy of the value into the new memory address. You can make a "reference" only
by explicitly making a pointer and copying the address of another object.

"Pass by reference" languages treat everything as a pointer by default,
forcing you to make a copy operation when you do not want this behavior. This
may seem like an equivalent programming model, and possibly simpler because
this pointer business if confusing at first. However, basic concepts such as a
call stack or an array of values can no longer be expressed easily, because
with "pass by reference" languages you have removed the concept of a value
from the language. So pass-by-reference languages can lead to confusion in
large programs, even if they seem simpler at first.

Basically, go is "pass by value" because the language forces you to always be
explicit about when you are copying an entire value, and when you are only
copying a pointer.

------
inconshreveable
Of the complaints you can make about Go's type system (and there are many),
being too complex is not one of them.

------
dhemmerling
In the comments he says he changed his mind about Go, and the necessity of the
efficiency gain over Racket. So there's some confusion apparently.
[https://cxwangyi.wordpress.com/2012/07/22/why-go-use-
racket/...](https://cxwangyi.wordpress.com/2012/07/22/why-go-use-
racket/#comment-871)

------
vvpan
It's a chicken and egg problem, but the real reason for me to use Go vs Racket
is that learning the former will further my career significantly, while latter
won't at all. Sad, but true.

~~~
michaelsbradley
It depends. Learning Racket and the design methodology taught by Felleisen, et
al. could help you become a better programmer _in general_ , and thus
significantly further your career.

 _How to Design Programs, Second Edition_

[http://www.ccs.neu.edu/home/matthias/HtDP2e/](http://www.ccs.neu.edu/home/matthias/HtDP2e/)

~~~
vvpan
Sure, I agree. But the impact is much less direct. Most interviews go like
this: "Have you worked with Angular?". And you just don't really need to be a
very good programmer to have a well-paying job.

------
4ad
Author thinks Go's select statement has any resemblance to with epoll and
kqueue. Didn't read further.

~~~
bentronic
That's too bad, because you missed the brilliant ending to the post, in which
the author answers the question posed in the title:

> P.S. As noted in [link], Racket programs build and run much slower than Go
> programs.

------
aikah
I like crosscompilation and being able to deploy a stand alone executable
without the whole sdk needed.Does racket do that?

~~~
michaelsbradley
Yes, that's possible:

[http://docs.racket-lang.org/raco/exe.html](http://docs.racket-
lang.org/raco/exe.html)

[http://docs.racket-lang.org/raco/exe-dist.html](http://docs.racket-
lang.org/raco/exe-dist.html)

~~~
wtf_is_up
I may have missed in those docs any mention of cross-compilation. The first
result for 'cross compile racket' is [1]. Of course that's from 2013, so maybe
it changed since then.

[1] [https://groups.google.com/forum/m/#!topic/racket-
users/LLB6o...](https://groups.google.com/forum/m/#!topic/racket-
users/LLB6oV1VsPo)

~~~
michaelsbradley
You're right – I keyed in on "stand-alone executable" and not the
"crosscompilation" part of the question.

------
michaelsbradley
The blog post is a couple of years old, so it's probably worth noting that
_PLaneT_ [1], mentioned by the author, has been superseded by a new _Packages_
[2] system. PLaneT is still operating, however, and libraries hosted there can
be installed with raco[3].

[1] [http://planet.racket-lang.org/](http://planet.racket-lang.org/)

[2] [http://pkgs.racket-lang.org/](http://pkgs.racket-lang.org/)

[3] [http://docs.racket-lang.org/raco/index.html?q=](http://docs.racket-
lang.org/raco/index.html?q=)

------
copsarebastards
I'll come right out and say that I _despise_ Go. It's a terrible language that
ignores decades of language research and brings nothing new to the field, but
has become popular due to Google hype.

That said, Go -> Racket is a pretty big jump. Even though I think Go is
terrible, I can at least take the time to see the problems it's solving and
offer comparable languages. I suggest Rust as a Go replacement.

Don't get me wrong, Racket is pretty good. It's not the Lisp I would pick (I
really like Gambit Scheme) but it's at least a Lisp. But a high-level language
like Racket isn't really comparable to Go. They're just in different spaces.

~~~
kibwen
Rust's and Go's strengths are very dissimilar, there's no reason to consider
one as the replacement for the other without considering a dozen other worthy
languages in between.

~~~
copsarebastards
Sure, if you make vague enough statements, they're hard to disprove, which
might lead you to believe that what you said is correct even though you
haven't made a provable or disprovable claim.

There are plenty of problems where one might consider using Go or Rust. The
same cannot be said of Go and Racket, or Rust and Racket. I wouldn't consider
using Racket for a situation where I need high performance or low memory usage
--the numbers just don't work. Likewise I wouldn't look at Go or Rust for
building a data-presentation type webapp.

------
Dewie
I'm inclined to disagree about the distinction between pointers and values
being explicit, and how that is bad - I think it might be the right decision
in an imperative language that tries to be performant in a straightforward way
(as opposed to language that tries to be performant by relying on compiler
optimizations - that might work for certain languages). It allows you to be
aware and more careful about indirection and memory layout, which obviously
can buy you a lot with regards to performance.

It certainly seems like the more lower-hanging fruit than what the usual
advice for getting a fast programming language is - make memory management
explicit/manual (though it seems that if you have pervasive manual memory
management, you end up with a clear and explicit distinction between values
and pointers to values anyway).

------
mistobaan
shouldn't be: Why Go? (Use (Racket))

~~~
chc
That looks like you want to use the result of Racket, rather than use Racket
itself.

------
fixxer
Racket's website ([http://racket-lang.org/](http://racket-lang.org/)) has an
"explain" button by the code snippet. Is the existence of such a button
perhaps a statement about the quality of the syntax?

~~~
samth
No, it's a statement that the developers of Racket care about explaining how
things work.

~~~
fixxer
Perhaps because they need to? Or do you find Racket as clear as other
languages? Even other Lispy ones?

Without trying to be insulting, I find Racket aesthetically unappealing.

