Hacker News new | past | comments | ask | show | jobs | submit login
CHIP-8 in Common Lisp: Graphics (stevelosh.com)
91 points by stevelosh on Dec 21, 2016 | hide | past | favorite | 12 comments



This has been a good intro to Common Lisp, as I've been comparing things to my JavaScript implementation of CHIP-8 (cough http://mrspeaker.github.io/CHIMP-8/ cough) - but I'm having a difficult time parsing the `iterate` and `repeat` and `for` statements in there: what's the difference between them - and how does `for` relate to a C/JavaScript `for`?


If you've never done Common Lisp before, it's better to start by looking at `loop`, which is a built-in macro that provides a bunch of different ways to loop/iterate: http://www.gigamonkeys.com/book/loop-for-black-belts.html

iterate is a Common Lisp library that aims to be a replacement for loop, being cleaner (subjectively) and portably extensible: https://common-lisp.net/project/iterate/

`repeat` is an iterate clause that tells iterate to perform N iterations of the loop:

    (iterate (repeat 3) (print 'beep))
    BEEP
    BEEP
    BEEP
As for this particular `for`, it's an iterate clause that handles numeric iteration (among other things). So:

    (iterate (for x :from 0)
             (for y :from 10 :downto 7)
             (print (list x y)))
Would give you:

    (0 10)
    (1 9)
    (2 8)
    (3 7)
iterate will terminate the loop the first time any one of its clauses runs out of values/iterations. So in the post I had something like

    (iterate (repeat N)
             (for x :from start)
             ...)
You could write this as

    (iterate (for x :from start :below (+ start N))
             ...)
But manually calculating the ending value seems ugly to me. I know I want the loop to happen N times so I just say `(repeat N)` and let the computer figure out when it's time to be done.


I cant remember the original or who I'm almost quoting but it goes something like this :

> `loop` is so complex, LISP programmers invented functional style so they didn't have to learn how to use it


I cannot answer your question the way you probably intended, but, for self learning:

ITERATE is an attempt at providing a generic LOOP, which is built into CL and is somewhat specified in the standard. REPEAT is part of the ITERATE package. ITERATE is extensible and can deal with lists and vectors uniformly (whereas with LOOP you "LOOP FOR x IN LIST" or "LOOP FOR x ACROSS VECTOR"; i.e. you have to change code when changing the type of sequence). Having said that: You can read LOOP/ITERATE in CL roughly like you can read FOR in JS. For details, see the Common Lisp HyperSpec[3].

If it is just for understanding the code: Just read it like natural language with indentation read like in python (i.e. something indented always belongs to the parent, which is one indentation level below - as an example see REPEAT and ITERATE, the indentation shows the relation between the two).

[1] https://common-lisp.net/project/iterate/

[2] http://www.lispworks.com/documentation/HyperSpec/Body/m_loop...

[3] http://www.lispworks.com/documentation/HyperSpec/Front/index...


This, more than any advocacy from CLers, has shown me why I might prefer CL over Scheme.


Please elaborate


Certainly.

Scheme is inarguably a more elegant language than CL (for the most part: dynamic variables are an ugly hack). However, CL has tremendous practical benefits: The condition system, the large language, and so on.

CLers usually push the elegance and the cleanness of their language as a major benefit. And it is: a clean language makes programming easier. but Scheme is far cleaner than CL. And thus where CL beats Scheme is practicality, which most CL advocates don't discuss.

OTOH, this article discusses some of the features of CL that make it immediately practical: a type system that lets you specify sizes if you want to, so that you can do low-level bit hacking if necessary, a standard lowlevel macro system (not as nice as synclos, but what can you do...), and a wealth of useful libraries. This is something that, as of yet, Scheme cannot match, and may never.



That's an earlier post in the same series.


What a thing to downvote someone over though, posting something useful but with a minor mistake like this (not saying you downvoted him of course)


Please just give a corrective upvote and move on. That nearly always works (as it has above).


Good to know the practice of corrective upvotes is recognized by the mods :).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: