<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Firstly, do you suggest I remove the comments, in which case use
more blank lines or not? I don't mind, and only added them mainly
in the hopes it would be helpful to readers as the purpose of
Rosetta is to educate. But I agree that it also kind of thickens
the code.<br>
<br>
As for Pico being less thick, this is entirely true. Off the top of
my head, I suspect it has largely to do with PicoLisp's single data
structure and use of properly lists. I had originally directly
translated the PicoLisp code and came up with a comparable
solution. Then I replaced (cdars) and such with proper struct
references, requiring the corresponding lines of define-match or
match-let. Because these are found in lists, it requires additional
cons of the car of the cdr of the struct-x of the car type
statements where Pico just uses cdadadr. Which one is better is an
open question to me. What you lose in abstraction you gain in
concision. After all, we use car instead of first, and why? car is
shorter. It may happen to mean the first element, but it actually
means the car of a pair, and it fortunately happens that lists are
made of these pairs, so luckily the car for lists <i>happens</i> to
be the same as the car for pairs, which is an implementation detail
that every Scheme luckily shares (maybe it's explicitly in the
standard, but it's still in some sense a mistake of relying on an
implementation in the purest sense, at least within the scheme
itself).<br>
<br>
Also, for some reason Racket doesn't return values from mutations.
Why on earth (set! x 3) is void instead of 3 is a mystery, but it
leads to things like:<br>
<br>
(define-match (x ...) (heap-min heap))<br>
(now-remove-it!)<br>
<br>
and, in addition to verbose naming:<br>
<br>
(vector-set! v i 4)<br>
v<br>
<br>
which should ideally be:<br>
<br>
(vec! v i 3)<br>
<br>
Things that take 1 line tend to take 2-3 lines. The best example
is:<br>
<pre class="text highlighted_source">(unless (idx '*Hist (sort (copy *Boxes)) T)
</pre>
where idx goes through *Hist (a list) and, due to the #t flag at the
end, adds the sorted list of boxes if it's not found. The overall
purpose is it saves the current state to avoid duplicate searches.
The key is that, in addition to mutating history, it also <i>returns</i>
something. If the element was added, it returns either the element
or the list (I forget, but it's non-#f is the point). So this one
line continues the search by determining if the new state was added
to the history or not, based on whether it was already in the
history. Since I have to extract the minimum of a heap and then
mutate the heap, not only do I need at least 2 expressions to
accomplish that, but in general, this kind of pattern can take <i>three</i>
expressions. One to bind the result before it's deleted forever,
one to delete it, then the expression that uses it! It might not be
usable directly in the first line since it might recurse with what
should have been the deleted version of the structure. So one might
have to save the result, mutate, and <i>then</i> recurse!<br>
<br>
Pico also has property lists, so instead of vector-ref'ing
everything, the 'val of a symbol is obtained (e.g. a box on a goal
is the box with a goalified 'val property). Property access
function is a single character ":" when referencing the anaphoric
This. Pico has constructs like "make" which sets up a list building
environment where things can be added on the left and right sides of
a list, and then automatically returns the list. And since all list
functions can be run within make, it is immensely powerful,
essentially allowing arbitrary construction of the primary data
structure of the language, which, unlike most "real" schemes,
actually uses them directly for interpretation. One can thus build
"macros" out of expressions using the normal library functions,
instead of require-for-syntax functions that require fancy 300
character-length macro machinery like
define-syntax-transformer-for-syntax-parameterization to produce (I
do apologize for being harsh, but I like Racket and these things
sadden me).<br>
<br>
Finally, and this is more of a useless criticism since the language
is so far developed in this direction, so I apologize, but while
it's nice to have for, for/list, for*/list, for*/fold, match,
define-match, match-let, let-values-define-match*,
match-let-define-values*/fold/for (exaggerating), what tends to
happen is there's a huge mess of overlapping constructs, and a large
amount of (at least for me) programmer time wasted in deciding and
refactoring between nestings of let -> define -> cond -> or
-> if vs. match-let -> if -> match -> cond ->
for/fold -> not -> and -> named let (or whatever). In
PicoLisp, one simply calls a function on what must be a list, the
function names are short, and there are a huge number of library
functions. There is almost no decision to be made! You are
processing a list, and you need to do something, so you use the
corresponding library function. PicoLisp comes built in with
anaphoric stuff as well. I had to use my custom awhen to bind @
where that is often bound for free in Pico, not requiring a special
conditional with binding (and not requiring define-syntax-parameter
and syntax-parameterize and
make-transformer-syntax-binding-case-rules to implement it...).
Pico consistently has the shorter/shortest solutions and in all my
tests, has excellent run time performance. I dare say it's a
"better" language and it would be, in my opinion, for the reasons I
just gave.<br>
<br>
My intent wasn't to start some kind of flame war here. I do like
Racket, it's teaching languages, the assocated HTDP1&2, the
associated universe/image library (I used that to do Galton Box on
Rosetta), and the fact that it's very standardized and comes with
decent OpenGL bindings that I'm using to make a 3d game that I shall
one day post. But if I had to choose which language seems to
actually produce better code, I would have to side with PicoLisp.
Just beware dynamic scope.<br>
<br>
<div class="moz-cite-prefix">On 06/10/2013 12:42 PM, Matthias
Felleisen wrote:<br>
</div>
<blockquote
cite="mid:CC5A5369-DC08-419F-91B9-43B223DAF121@ccs.neu.edu"
type="cite">
<pre wrap="">
Thank you for this effort.
This is not a criticism of your code but I will say that Racket code looks dense and overbearing compared to PicoLisp, Python, and Tcl. Hmph.
On Jun 10, 2013, at 12:34 PM, Sean Kanaley wrote:
</pre>
<blockquote type="cite">
<pre wrap="">The rather empty page on Sokoban now has a Racket solution. The creator is proud to announce it's the fastest solution (though a couple didn't give run times) at ~0.1 seconds. My thanks to Ryan Culpepper for making the binary heap that made this possible.
<a class="moz-txt-link-freetext" href="http://rosettacode.org/wiki/Sokoban#Racket">http://rosettacode.org/wiki/Sokoban#Racket</a>
Also, Racket is one short of Python in popularity. If someone could do two more we'll defeat those lazy Python programmers, probably with less work!
____________________
Racket Users list:
<a class="moz-txt-link-freetext" href="http://lists.racket-lang.org/users">http://lists.racket-lang.org/users</a>
</pre>
</blockquote>
<pre wrap="">
</pre>
</blockquote>
<br>
</body>
</html>