"...but nothing beyond that. As long as Node.js exists in this world, I can't truly hate anything else."<p>I found this hilarious. I am also rather underwhelmed (to be nice) with Nodejs and a little bothered at its wide adoption.<p>I have also been learning racket recently; my formal language and functional programming class uses it. I had some previous experience with common lisp but the raw nature of scheme still pleasantly surprised me a little bit.<p>EDIT: From what I remember, javascript was "inspired" by scheme. Obviously that when well...
This sums up quite a lot about Lisps in general. I'm amazed OP got so fast to this "insight" :)<p><pre><code> (And this is probably Lisp's greatest weakness as well – with this level of
possible diversity, everyone has to use the “common lowest denominator”
simply because nobody can agree on what alternative syntax / library / etc.
is better and should be used.)
Off-topic: it's not enough to give everyone opportunity to improve the
language; you have to choose the winners and promote them heavily. The rules
of free market don't work here; people won't use the best thing, they'll use
the one which is available out of the box and which is used by their peers.</code></pre>
As others have said, this does justice to the idea of actually learning a new language...or perhaps because it is Racket a new family or ecosystem of languages. Anyway, if you're still curious about pairs verus lists and why anyone would use dotted pairs, I like to think about it as where Lisps show that they are from the age when running close to the metal was a given.<p>And it all goes back to <i>car</i> and <i>cdr</i> and the fact that they are (or rather were) embedded assembly language and there to give raw access to Lisp's linked memory model (as opposed to the sequential memory model of Fortran). A dotted pair has two efficiency advantages over a proper list and both stem from the fact that the last cell of the last pair of a proper list contains 'nil (or 'null in Racket).<p>Storing two values in a proper list requires two cons cells - the first with the first value and a pointer to the second cons cell and a second cons cell containing the second value and a null pointer. In contrast, a dotted pair holds two values in a single cons cell - halving the memory requirement.<p>The second advantage is that when there are only two values there's no need to walk the list and test for 'null (or 'nil) on the <i>cdr</i>. This saves an instruction step.<p>Philosophically, dotted pairs allow for <i>car</i> and <i>cdr</i> to be used symmetrically. Calling <i>cdr</i> on a dotted pair returns the second value directly just as calling <i>car</i> on any list returns the first value directly. Lastly, one of the things that is awesome about Lisp is the way in which lists can model data structures, and in the case of a dotted pairs their efficiencies are available to all those structures which consist of or rely on paired values.<p>Of course, this may be obvious and on a machine with 10+ GB of RAM not really applicable, but I find it fun to think about anyway.
I like the approach you took to writing this post. This wasn't the typical attempt to summarize an entire programming language in a page (which IMO is done too often, too poorly), but rather an exploration. As you went through each section, I could see how you were approaching various problems and learned a lot about Racket in the process. I would love to see more of this style of post.
This is how I usually implemented quicksort in Racket:<p><pre><code> (define (quicksort xs)
(if (null? xs)
xs
(let*
([hd (car xs)]
[tail (cdr xs)]
[smaller (filter (lambda (x) (< x hd)) tail)]
[bigger (filter (lambda (x) (>= x hd)) tail)])
(append (quicksort smaller) (list hd) (quicksort bigger))))
</code></pre>
It's great to see a hugely superior implementation, and I love that people are writing about and using Racket like this because the more people do that the more resources there will be for people like me to learn from.
I love Scheme. And I love Clojure, which is IMHO Scheme plus some great ideas from Haskell.<p>I regret there's no Scheme or Clojure running on LLVM, which I think is a much better platform than the JVM. Julia, that resembles Dylan (another Lisp), is the perfect example.
It seems as if several of the author's problems come, oddly for someone who's used both strict (Pascal) and non-strict (Haskell) langauges, from being confused about Racket's strictness. Why is time a special form? Because otherwise (time (expensive)) would just get the result of (expensive). Why doesn't (list 1 (2 3) 4) work? Because list isn't a special form, it's a function. Why doesn't quote turn '(list 1 2 3) into '(1 2 3)? (Well, this one isn't about evaluation order, admittedly.) Because if it did it ... wouldn't be quote.
A friend of a friend has considerably code in Scheme, Common Lisp and Clojure, when you ask him which is the true Lisp, guess what will he answer? Haskell!<p>Haskell does really create a big impact on some developers.<p>Just an anecdote ;)
One note:<p>> Racket's default IDE is better than GHCi and probably on par with Emacs (you almost certainly can configure Emacs to be better than anything, but it's not trivial and people don't bother, while DrRacket provides autocompletion and documentation out of the box).<p>Last I used it (a few years ago), DrRacket was very laggy, so I would find it very hard to use for a serious project. YMMV, maybe it's improved.
Web apps are a hack on a hack, yes. But it's kind of ironic he hates Javascript so much when Javascript is a pretty cool programming language heavily influenced by Scheme, which is awfully similar to Racket.<p>But hey, I like people who call it like they see it, and there certainly are some drawbacks to Javascript too.
he will be amazed when he discovers custodians.
<a href="http://docs.racket-lang.org/reference/eval-model.html#%28part._custodian-model%29" rel="nofollow">http://docs.racket-lang.org/reference/eval-model.html#%28par...</a>