SICP: The LFE Edition

124 views
Skip to first unread message

Duncan McGreggor

unread,
Feb 6, 2015, 11:46:47 AM2/6/15
to lisp-flavo...@googlegroups.com
Hey all,

As was leaked on Reddit earlier this year by an enthusiastic reader, an LFE edition of the classic work Structure and Interpretation of Computer Programs is underway. Last night I finished the first draft of Chapter 1:
 * http://lfe.gitbooks.io/sicp/

Some notes:
 * All of the mathematical notation and equations have been converted to LaTeX; these don't show up in the ebook formats, sadly -- only the web version. (KaTeX may help with this, but that project is early and doesn't support some of the syntax I'm using.)
 * There are subsections in the LFE edition that don't exist in the original SICP; these are being added when topically pertinent
 * I need to confirm with Robert the bits about the LFE interpreter and how its internals might differ from Scheme's
 * Links to other sections in the book haven't been added yet
 * The original errata reported for SICP have not been corrected yet

This is a long-term project, as I have time to work on it in my evenings. It is, however, an enormous amount of fun to be converting this wonderful book to LFE :-)

My hope is that we are able to provide new LFE users with additional reading material to get them jump-started into (and excited about!) the language. I've got some other projects (both started as well as those that are only an idea) in the works that share this goal as well.

If you have feedback, it would be most helpful if you could record your thoughts in a ticket:
 * https://github.com/lfe/sicp/issues/new

Thanks in advance for any contributions!

d



arpunk

unread,
Feb 7, 2015, 11:53:01 AM2/7/15
to lisp-flavo...@googlegroups.com
On Fri, 6 Feb 2015 at 11:46:46 COT,
Duncan McGreggor wrote:
>
> Hey all,
>
> As was leaked on Reddit earlier this year by an enthusiastic reader,
> an LFE edition of the classic work Structure and Interpretation of
> Computer Programs is underway. Last night I finished the first draft
> of Chapter 1:  * http://lfe.gitbooks.io/sicp/

Sorry, couldn't resist :>

I've been enjoying all the gitbooks the community is starting to write
for LFE to the point I've been able to start rewritting some Erlang
applications I have currently in production in LFE.

Duncan McGreggor

unread,
Feb 7, 2015, 2:00:20 PM2/7/15
to lisp-flavo...@googlegroups.com
On Sat, Feb 7, 2015 at 7:58 AM, arpunk <arp...@cryptolab.net> wrote:
On Fri,  6 Feb 2015 at 11:46:46 COT,
Duncan McGreggor wrote:
>
> Hey all,
>
> As was leaked on Reddit earlier this year by an enthusiastic reader,
> an LFE edition of the classic work Structure and Interpretation of
> Computer Programs is underway. Last night I finished the first draft
> of Chapter 1:  * http://lfe.gitbooks.io/sicp/

Sorry, couldn't resist :>

Not a worry in the least -- it was pretty fun! I used the term "leaked" in the most playful sense possible :-)
 
I've been enjoying all the gitbooks the community is starting to write
for LFE

That's so great to hear!
 
to the point I've been able to start rewritting some Erlang
applications I have currently in production in LFE.

That's FANTASTIC :-)

You've probably already seen it, but there is a "Casting SPELs in Lisp (LFE Edition)" currently being worked on. It's still in pretty rough shape, because it essentially had to be rewritten from scratch do to using records and managing state safely ... and then creating a "server" so that every command didn't spit game state back at the player  ... ! Anyway, what it's shaping up to be is a very fun crash course on some of the basic build-an-application-in-LFE patterns. You know, the basic elements that would be used regardless of whether the app was OTP or not.

I wish we could commission Conrad to do more cartoons, 'cause I could see adding about 6 more chapters to this puppy. Games are the *absolute* most fun to write about, and they have all of the elements necessary to demonstrate the design decisions and architecture of extremely robust distributed applications. Besides, if you're learning, and it's not fun, something's very wrong :-)

Regardless of additional cartoons, I think it may already be too late: in my afternoon walks over the past couple of days, I've been (without even realizing  it), planning:

1) how to add more basic chapters to the LFE "Casting SPELs in Lisp" book, to help folks warm up to their game more quickly, but providing a good foundation for the more hairy topics to come
2) cover more of the functional tricks and tips along the way (I'm currently writing a section on the use of lists:map and lists:fold)
3) convert the game to basic OTP
4) discuss how to create a custom shell in LFE -- one that you can SSH into
5) tackle issues of shared and distributed data (start with Mnesia, then maybe hit Riak in a later chapter)
6) provide a new spin on the classic "chat app", as part of the game
7) add more features and take the game into MUD/MUSH territory
...
x) share data with other games (I was thinking of a classroom scenario where kids/students are creating their own "rooms" in their own servers, and these could be broadcast as available to other games on the local network, so kids could integrate each others' creations into their own game/server)

The whole focus, though, is practical: make the right decision for the given context and constraints. Not every service in production has the same needs; each chapter can provide notes on "when to use" or "when not to use", etc. Ideally, by the end, you would have an amazing multiplayer MUD to share with your friends, and you would have all the skills necessary to create the WhatsApp company, or get hired by the Secret Lisp Division in Ericsson ;-)

As you might guess, my afternoon walks have been a LOT of fun lately :-)

d
 

--
You received this message because you are subscribed to the Google Groups "Lisp Flavoured Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.
To post to this group, send email to lisp-flavo...@googlegroups.com.
Visit this group at http://groups.google.com/group/lisp-flavoured-erlang.
For more options, visit https://groups.google.com/d/optout.

Duncan McGreggor

unread,
Feb 17, 2015, 2:21:23 AM2/17/15
to lisp-flavo...@googlegroups.com
I'm hip-deep into Chapter 2 now, and LFE is *really* starting to shine ... I'm quite surprised, really. Not because LFE is awesome :-) but rather because this course and book were designed around Scheme, playing to its strengths, and I expected to find a bit of a handicap with LFE. It's actually been quite the reverse for the past few sections: pattern matching (esp. cons'ing in the function heads) is really blowing the Scheme away. It's probably a bit harder for the new-comer to adjust to, and so may make for a steeper learning curve, but the sort of curve that a TA or professor office hours could sort out ... just like any other subject worth studying :-)

There are bits further on in the book where LFE will be at a disadvantage (image processing, etc.), but I'll think of ways around that -- and if not, I'll be asking for ideas/suggestions ...

Overall, though, this is turning out to be quite the experience. As much as I love text adventure games, I find that I'm having more fun on SICP than I did on Casting SPELs ... and that's saying a *lot* :-)

'night all,

d


Nelson Milian

unread,
Feb 17, 2015, 9:23:36 AM2/17/15
to lisp-flavo...@googlegroups.com
Maybe for the bits where lfe struggles, you could give the SICP treatment to distributed computing. I don't know if you've seen the website composingprograms.com but the professor merged SICP and python together. In the last chapter he introduces distributed computing, distributed data processing, and parallel computing. http://composingprograms.com/pages/46-distributed-computing.html.

Another suggestion could be introducing transducers? http://clojure.org/transducers Though, it's still beyond my level of comprehension, so I don't know if it will be a good fit.

Nelson

d
 
To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-erlang+unsub...@googlegroups.com.

Duncan McGreggor

unread,
Feb 17, 2015, 12:16:38 PM2/17/15
to lisp-flavo...@googlegroups.com
These are good suggestions. It probably goes without saying how much care and thought would need to be taken ... the character of SICP is quite unlike that "how-to" style of most programming materials on the market today. It's more of "here is the logic which underlays these various implementations." That would make for an *amazing* chapter on distributed systems ... but it might take me three years to write :-) Something to ponder, anyway ...

I'll be checking out the links you sent -- thanks!

d

To unsubscribe from this group and stop receiving emails from it, send an email to lisp-flavoured-e...@googlegroups.com.

Duncan McGreggor

unread,
Feb 17, 2015, 10:54:14 PM2/17/15
to lisp-flavo...@googlegroups.com
Here's a great example from tonight's work ...

Scheme:

(define (count-leaves x)
  (cond ((null? x) 0)  
        ((not (pair? x)) 1)
        (else (+ (count-leaves (car x))
                 (count-leaves (cdr x))))))

LFE:

(defun count-leaves
  (('()) 0)
  (((cons head tail))
    (+ (count-leaves head)
       (count-leaves tail)))
  ((_) 1))

Totally not bashing on Scheme (which I do love); just really appreciating the elegance of LFE :-)

d

Mário Guimarães

unread,
Feb 18, 2015, 6:07:34 AM2/18/15
to lisp-flavo...@googlegroups.com
humm ... can't this Syntax stuff be improved? For example:

(defun count-leaves
  ('() 0)
  ((cons head tail)
    (+ (count-leaves head)
       (count-leaves tail)))
  (_ 1))

Now is much better to the eyes :-)

Cheers
Mário 

Robert Virding

unread,
Feb 18, 2015, 6:31:54 AM2/18/15
to lisp-flavo...@googlegroups.com
No, that does work. Each of the "clauses" of the defun is a list where the first argument is a *list of arguments* for the function while the rest of the list is the body of that clause. So this syntax works for functions of any number of arguments. So these are equivalent:

(defun foo (x y) (cons x y))

and

(defun foo
  ((x y) (cons x y)))


Though in this case you are not using the pattern matching. This is the *only* way to get pattern matching function level, in the more "standard" defun form the arguments must be variable names. This is no great loss as it is seldom you use pattern matching at the function level and only have one clause. A convention is to use [ ... ] to mark the argument list:

(defun count-leaves
  ([()] 0)
  ([(cons head tail)]

    (+ (count-leaves head)
       (count-leaves tail)))
  ([_] 1))

[ ... ] is exactly equivalent to ( ... ) and is useful in cases like this. It is taken from scheme.

Note that in the clause version of defun all the clauses must have the same number of arguments. Functions have a fixed number of arguments and if you want to define multiple functions with the same name but different number of arguments (perfectly legal) you must use multiple defuns. This is consistent with that they are different functions and I will not change it, though you could always write your own defun macro. :-)

Robert

Fred Hebert

unread,
Feb 19, 2015, 9:05:58 AM2/19/15
to lisp-flavo...@googlegroups.com
On 02/18, Robert Virding wrote:
> (defun count-leaves
> ([()] 0)
> ([(cons head tail)]
> (+ (count-leaves head)
> (count-leaves tail)))
> ([_] 1))
>

I'm not familiar with LFE, mostly reading the mailing list and lurking
around, but did LFE decide to consider () + (cons head tail) to be different
from _ as match for a list?

Coming from Erlang, I would expect all lists to be the union of (cons
head tail) and () (the empty list I assume) -- [H|T] vs. []. How is the
last clause ever matching?

Regards,
Fred.

Robert Virding

unread,
Feb 19, 2015, 9:41:14 AM2/19/15
to lisp-flavo...@googlegroups.com
Yes you are right, the () and (cons head tail) will match all the parts of a list. But this function works on a list treee and counts the number of leaves, everything which is not a cons or a (). That is what the _ is for, it matches everything which is NOT a cons or nil and returns 1. We then sum all the non-list parts and return that. So:

(count-leaves 'a) ==> 1
(count-leaves '(a b)) ==> 2
(count-leaves '(a . b)) ==> 2
(count-leaves '((a . b) ((c d) e))) ==> 5

Robert
Reply all
Reply to author
Forward
0 new messages