eli's puzzle

This commit is contained in:
Danny Yoo 2011-07-26 14:58:50 -04:00
parent 5ebf716f69
commit 41c38a0b3b
2 changed files with 127 additions and 0 deletions

View File

@ -0,0 +1,45 @@
#lang planet dyoo/whalesong
;; Eli's puzzle
;;
;; http://lists.racket-lang.org/users/archive/2011-July/046849.html
(require (planet dyoo/whalesong/world))
(define-struct world (seq output))
;; streak: (listof number) -> number
(define (streak lst)
(let ([elt (car lst)])
(let loop ([lst lst])
(cond
[(null? lst) 0]
[(= (car lst)
elt)
(add1 (loop (cdr lst)))]
[else
0]))))
(define (my-drop lst n)
(cond
[(= n 0)
lst]
[else
(my-drop (cdr lst) (sub1 n))]))
(define (tick w)
(let* ([streak-length (streak (world-seq w))]
[next-self-describing-chunk
(list streak-length (car (world-seq w)))])
(make-world (append (my-drop (world-seq w) streak-length)
next-self-describing-chunk)
(append (world-output w)
(list streak-length
(car (world-seq w)))))))
(define (draw w)
(world-output w))
(big-bang (make-world '(1) '())
(on-tick tick 1)
(to-draw draw))

82
excerpt.html Normal file
View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head></head>
<body>
<p>If people say that Racket is just a Lisp, they are short-selling
Racket a little. It's more accurate to say that Racket is a language
laboratory, because it supports many different languages,
including <tt><a href="http://docs.racket-lang.org/lazy/index.html">lazy</a></tt>,
<tt><a href="http://docs.racket-lang.org/frtime/index.html">frtime</a></tt>,
and the
HTDP <a href="http://docs.racket-lang.org/htdp-langs/index.html">teaching</a>
languages.</p>
<p>However, these examples are all problematic: they lack the power to
convince. Skeptics may accept that Racket has a lot of Lisp dialects,
but surely, they may add, there's a world of difference between a
simple dialect of Lisp and a different programming language. And even
though each of these language examples use wildly different semantics,
their differences are drowning in the homogenous sea of
parentheses.</p>
<p>In order to make the point that Racket is a language laboratory, we
must show examples of Racket languages that look nothing like Lisp.
Let's take a stab at the heart of the problem. What would happen if
we showed a Racket program like this?
<code>
<pre>
#lang planet dyoo/bf
++++++[>++++++++++++<-]>.
>++++++++++[>++++++++++<-]>+.
+++++++..+++.>++++[>+++++++++++<-]>.
<+++[>----<-]>.<<<<<+++[>+++++<-]>.
>>.+++.------.--------.>>+.
</pre>
</code>
To put this in polite terms: what in the $@#! is this?</p>
<p>This
is <tt><a href="http://en.wikipedia.org/wiki/Brainfuck">brainf*ck</a></tt>. If
we enter this in DrRacket, it runs. If we
use <a href="http://docs.racket-lang.org/raco/index.html">raco</a> on
it, we can create standalone executables.</p>
<p>What exactly is going on? All Racket programs start with
a <tt>#lang</tt> line, as we saw in the example above.
This <tt>#lang</tt> line is the hook we use to extend Racket toward
different programming languages. More specifically, the
<tt>planet dyoo/bf</tt> part of the <tt>#lang</tt> line names a
specific Racket module, which tells Racket how to do two things:
<ul>
<li>how to parse the surface syntax into abstract syntax trees</li>
<li>how to attach semantics to each of the phrases of a language</li>
</ul>
Both these pieces are not too mysterious: they're the
<a href="http://en.wikipedia.org/wiki/Compiler#The_structure_of_a_compiler">front-end</a>
of a traditional compiler, and one of the distinguishing features of
Racket is that, not only is its front-end programmable, but pleasingly
so: it's an afternoon's worth of time to implement
<tt>brainf*ck</tt> from scratch.
</p>
<p>Toward that end, I've written a self-contained tutorial
at <a href="http://hashcollision.org/brainfudge">http://hashcollision.org/brainfudge</a>
that shows the entire process, of how to write an implementation of
the <tt>brainf*ck</tt> language into Racket and how to deploy it on
<a href="http://planet.racket-lang.org/">PLaneT</a>. I'd love to hear
any comments or suggestions about the tutorial.
</p>
</body>
</html>