Here’s an example of something difficult to do in Python. lazy, stateless and minimize are custom macros.
(lazy
(stateless x float)
(stateless y (* x x))
(minimize y) // nothing has been calculated yet
(print y) // 0.0 ― this is where the first calculation occurs
(print y) // 0.0 ― the second evaluation of y just reads from the cache
(print x)) // 0.0 ― this is read from the cache too
The stateless macro caches results locally, backs up everything to a remote server in a background process and reads from the remote cache whenever possible.
And I would like to know where you learned that sort of meta-programming.
Any decent Lisp book will cover how to write a macro. The real challenge is knowing what to write, not how to write it.
I know of no good books on this subject. In my experience, you have to understand what it’s like to use many different software paradigms and how they are implemented. Then you can just steal their most relevant features as you need them. This particular system took inspiration from Haskell, R and applied mathematics. Under the hood, it makes heavy use of syntax trees, hash-based lookups, lazy evaluation and Bayesian optimization.
How to practice meta-programming commercially is an even harder question. Most companies don’t use a meta-enough language like Lisp and those which do may not need meta-software at all. The only place I can think of where this has net positive commercial value would is a tiny startup working on a very hard problem. Small data comes to mind, but not much else.
This is very, very cool. Having come from the functional programming world, I frequently miss these features when doing machine learning in Python, and haven’t been able to easily replicate them. I think there’s a lot of easy optimization that could happen in day-to-day exploratory machine learning code that bog standard pandas/scikit-learn doesn’t do.
This is encouraging to hear. When I talk about this stuff to ML engineers, some instantly get it, especially when they come from a functional programming background. Others don’t and it feels like there’s a wall between me and them.
I think I can replicate a lot of this in Python, even if it’s a little clunky. It’s just easier to start in Hy and then write a wrapper to port it to Python.
I know of no good books on this subject. In my experience, you have to understand what it’s like to use many different software paradigms and how they are implemented.
The real challenge is knowing what to write, not how to write it.
Yeah, this is the difficult thing for me. I’ve written extensions of basic forms like cond. But I haven’t yet had an insight like: ‘this is a problem I can solve much more elegantly with macros than with plain functional code’.
I liked Chapters 1 and 2 of On Lisp. After that, I felt like it degenerated into a design patterns book. The design patterns Paul Graham need 27 years ago aren’t the design patterns I need right now. I prefer Practical Common Lisp as a textbook. Ironically, Practical Common Lisp book is extremely impractical in 2020 but I feel it demonstrates high-level Lisp programming better through its use of extremely dense code.
I’ve never read Let Over Lambda. Judging by the table of contents, it looks like an exceptionally good book on how to write a macro but—once again—not when to write a macro.
Instead of diving back into your Lisp textbooks, I recommend this advice from Paul Graham’s Rarely-Asked Questons:
How can I become really good at Lisp programming?
Write an application big enough that you can make the lower levels into a language layer. Embedded languages (or as they now seem to be called, DSLs) are the essence of Lisp hacking.
I thought if I read enough examples of macros and practice writing powerful ones (not just that custom cond I mentioned), I will start seeing possible applications. You appear to have a different opinion. Anyway, I think I would get your point if I explored more more real world macro-enabled code.
Practical Common Lisp book is extremely impractical in 2020 but I feel it demonstrates high-level Lisp programming better through its use of extremely dense code.
I have read The Joy of Clojure, which imbued me with some good Lisp spirit. And I’ve moved Practical Common Lisp up on my reading list above On Lisp and Let Over Lambda, thanks to your brief review.
Here’s an example of something difficult to do in Python.
lazy
,stateless
andminimize
are custom macros.The
stateless
macro caches results locally, backs up everything to a remote server in a background process and reads from the remote cache whenever possible.Any decent Lisp book will cover how to write a macro. The real challenge is knowing what to write, not how to write it.
I know of no good books on this subject. In my experience, you have to understand what it’s like to use many different software paradigms and how they are implemented. Then you can just steal their most relevant features as you need them. This particular system took inspiration from Haskell, R and applied mathematics. Under the hood, it makes heavy use of syntax trees, hash-based lookups, lazy evaluation and Bayesian optimization.
How to practice meta-programming commercially is an even harder question. Most companies don’t use a meta-enough language like Lisp and those which do may not need meta-software at all. The only place I can think of where this has net positive commercial value would is a tiny startup working on a very hard problem. Small data comes to mind, but not much else.
This is very, very cool. Having come from the functional programming world, I frequently miss these features when doing machine learning in Python, and haven’t been able to easily replicate them. I think there’s a lot of easy optimization that could happen in day-to-day exploratory machine learning code that bog standard pandas/scikit-learn doesn’t do.
This is encouraging to hear. When I talk about this stuff to ML engineers, some instantly get it, especially when they come from a functional programming background. Others don’t and it feels like there’s a wall between me and them.
I think I can replicate a lot of this in Python, even if it’s a little clunky. It’s just easier to start in Hy and then write a wrapper to port it to Python.
Maybe Concepts, Techniques, and Models of Computer Programming? I haven’t finished that one, but the first part was good.
Thanks for the detailed reply!
Yeah, this is the difficult thing for me. I’ve written extensions of basic forms like
cond
. But I haven’t yet had an insight like: ‘this is a problem I can solve much more elegantly with macros than with plain functional code’.Maybe a way to get there would be to dive back into On Lisp (http://www.paulgraham.com/onlisp.html) or Let Over Lambda (https://letoverlambda.com/). Although, if you know of no good books, maybe these don’t suffice either. :-)
I liked Chapters 1 and 2 of On Lisp. After that, I felt like it degenerated into a design patterns book. The design patterns Paul Graham need 27 years ago aren’t the design patterns I need right now. I prefer Practical Common Lisp as a textbook. Ironically, Practical Common Lisp book is extremely impractical in 2020 but I feel it demonstrates high-level Lisp programming better through its use of extremely dense code.
I’ve never read Let Over Lambda. Judging by the table of contents, it looks like an exceptionally good book on how to write a macro but—once again—not when to write a macro.
Instead of diving back into your Lisp textbooks, I recommend this advice from Paul Graham’s Rarely-Asked Questons:
I thought if I read enough examples of macros and practice writing powerful ones (not just that custom
cond
I mentioned), I will start seeing possible applications. You appear to have a different opinion. Anyway, I think I would get your point if I explored more more real world macro-enabled code.I have read The Joy of Clojure, which imbued me with some good Lisp spirit. And I’ve moved Practical Common Lisp up on my reading list above On Lisp and Let Over Lambda, thanks to your brief review.
Good reminder. I think I’ve done something like that here: https://github.com/rmoehn/jursey/blob/master/test/clarification-swallows.repl