5 ms·
I would love to read more about "code as data" in general. I would appreciate any resources you can provide. Thanks.
by ilteris 8y ago
I would love to read more about "code as data" in general. I would appreciate any resources you can provide. Thanks.
- vnorilo 8y agoHomoiconicity is the googlable term. The first Lisp book that blew my mind is SICP, nowadays free: https://sicp.me/sicp.pdf https://sicp.me/sicp.pdf I think you need a big picture to appreciate the depth of homoiconicism and meta-circularity. It's a big one, but well worth it IMO.
- kbp 8y agoI remember finding it pretty revelatory the first time I saw LET defined as a macro like (defmacro let (bindings &body body) `((lambda ,(mapcar #'first bindings) ,@body) ,@(mapcar #'second bindings))) Seeing it use MAPCAR like that just made something click for me for whatever reason.
- disconcision 8y agoTo add on, Racket in particular has some very slick syntax for writing these kinds of things: (define-syntax-rule (let ([id expr] ...) body ...) ((λ (id ...) body ...) expr ...))
- yomly 8y agoI definitely liked this about Racket but I did also find the elipses to be a bit magic to begin with...
- disconcision 8y agoAs with all things, the trick to chase the magic away is to implement them. I recently made a little term rewriting library using racket/match syntax but with the pattern/templates specifiable at runtime. Ellipses were a bit confusing to begin with but when you break list patterns down into cons pairs + a cons-like pattern binary combinator to represent ellipses, it started making sense. The unexpected thing for me was that I thought nested ellipses were going to be the tough part, but it turns out they actually just... work.
- taylorwood 8y agoStuart Sierra has an interesting talk on homoiconicity and its history: https://www.youtube.com/watch?v=o7zyGMcav3c https://www.youtube.com/watch?v=o7zyGMcav3c
- lvh 8y agoSibling comment provides a great resource, but I think a good place to start is explaining macros. At the end of the day, every line of code you write is some data in a bespoke data format. Most programming language implementations leverage this, and academic compiler courses make you do the same work. A program lexes, parses, modifies... that data structure and eventually rewrites it to some other programming language, usually something lower level. If you exposed that underlying structure to the programmer, you give them a lot of power! The simplest way to see this is that any time you write a highly repetitive bunch of code, wouldn't it be great if you could ... write some code that wrote the code for you? You know how to systematically express the thing you want: you can probably say it a lot more crisply in a few lines of (especially functional) programming languages. Once you get rid of simple repetitive stuff, you realize that you can do so much more with this. You want advanced pattern matching? Sure: you can go implement it as a library. async/await? Library. Type checker? Library. New convenient way of defining functions? Library. New syntax for matrix math? Library. Et cetera :-) People in other programming languages have figured this out too. That's why we have code generators. The difference is that code generators are far enough removed from what you're actually doing (because e.g. they're glorified string concatenation) to be quantumly less useful. Generally speaking advanced IDEs will do this sort of thing: actually parse the code you're working on and let you do fancy tricks with it. Lisp is like having that power, all of the time.
- travisoneill1 8y agoI messed around with Clojure for a couple of days to see what a Lisp is like but never got into any of the advanced features. What could I build that would illustrate the capability you are talking about?
- lvh 8y agoIt's hard for me to provide a good example without knowing some of the stuff you're in to but here's one of my favorite macros: https://github.com/lvh/caesium/blob/master/src/caesium/binding.clj#L484-L507 https://github.com/lvh/caesium/blob/master/src/caesium/bindi... It takes a symbol and figures out the name of a C function, how to most efficiently call it (with type hints for perf). If you screwed that up in one location it might have security consequences. But I _can't_ scre it up, because instead of copy pasting that code a gazillion times as I would have in Python, I just figured out what I want once and then use that functionality a gazillion times :)
- ced 8y agoOn Lisp? http://www.paulgraham.com/onlisp.html http://www.paulgraham.com/onlisp.html
- TheGrassyKnoll 8y agoDownload for free. Thank you Mr. Graham.
- chongli 8y agoI took a course in Racket in first year (required for all first year math/CS students at my school) and I've spent some time in the Clojure community as well. "Code as data" is an oft-repeated selling point of Lisp and Lisp-like languages. When you actually start using these languages, you find yourself tempted to leverage this property and try writing lots of macros. But then you go back to the community and everyone tells you "the first rule of macros is you don't write macros." It turns out that if you use macros all over the place then your code becomes impenetrable. The problem is that macros allow you to circumvent the expected order of evaluation and produce your own novel syntactic structures. This puts lie to the old claim "Lisp has no syntax." In reality, Lisp has tons of syntax, it's just informal and buried within the definitions of macros. It parallels the problem put forth in Jo Freeman's famous piece, "The Tyranny of Structurelessness" [1]. Any group that purports to adopt a structureless organization ends up having a hidden, informal structure. This is the way of Lisps as well. [1] https://www.jofreeman.com/joreen/tyranny.htm https://www.jofreeman.com/joreen/tyranny.htm
- moocowtruck 8y agoi think https://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf https://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.... 'why calculating is better than scheming' also makes this point too; i'm going to check out this jofreeman thing... never saw it before thanks!
- lvh 8y agoThe author is one of the principal folks behind Haskell. But I can’t help but point out that I promise you you’ve never heard of the five or so lanaguages he mentioned as an alternative approach, and somehow this Lisp thing is still around. I suppose that which is dead may never die :-)
- dragonwriter 8y ago> But I can’t help but point out that I promise you you’ve never heard of the five or so lanaguages he mentioned as an alternative approach I actually had heard of at least KRC and Miranda even before the first time I've read the paper, but even if I hadn't I would immediately be able to think of several languages with some or all of the additional features over the Lisps he was comparing them to for which he describes them as superior to Lisp for the purpose, including some modern Lisp derivatives. Pattern matching, mathematical notation, and static typing with use defined types are all features that have become more, not less, common in languages since the paper was written.
- jefffoster 8y agoParadigms of AI Programming by Peter Norvig is a beautiful illustration of code as data. I learnt loads translating the Lisp to Clojure.
- deleted 8y ago[deleted]
- 2_ghosts 8y agoThe concept of code as data became intuitive to me after reading "The Nature of Lisp". https://www.defmacro.org/ramblings/lisp.html https://www.defmacro.org/ramblings/lisp.html