6 ms·
Why Lisp macros are cool, a Perl perspective (2005)
- db48x 5y agoThe key line is “In Lisp, source filters never break.” On a related note, https://www.youtube.com/watch?v=e1T7WbKox6s https://www.youtube.com/watch?v=e1T7WbKox6s is very much worth watching.
- jdougan 5y agoThree little words: Just Use Lisp. Having written a skeletal macro system for a Smalltalk, I do have a lot of sympathy for the effort he had to go through.
- db48x 5y agoHe definitely used a significant amount of elbow grease on this project. I’m sure that it was at least a year’s worth of work for him, but he actually gave this same talk several times that year so I bet he came out ahead. On the other hand, Regex::Debugger is something I really miss when I am working in any other language. I think Perl is unique in having a real debugger for regexes. The closest analogue is re-builder in Emacs, which lets you type a regex and see how it matches against a bunch of sample text. Very useful, but not the same as stepping through the regex.
- drekipus 5y agoI made sure to bookmark this same come back to it. I'm glad I did! Great watch, and I don't even know Perl
- db48x 5y agoI’m glad you enjoyed it! I definitely think that it has value over and above its Perl content.
- G3rn0ti 5y agoThe author wrote „Higher Order Perl“ which — to my knowledge — is one of the best books on programming ever written. While it’s got Perl in its title it is really an exhaustive introduction to the functional programming paradigm while being refreshingly non-academic about the subject. BTW: In general, I think there were many great Perl book authors having written very insightful introductory text books. They were mostly fun too read and taught me more about computer science than most computer science text books I had access too.
- marttt 5y ago> ... many great Perl book authors ... Would you mind listing a few of these? I would add "Modern Perl" by chromatic: https://pragprog.com/titles/swperl/modern-perl-fourth-edition/ https://pragprog.com/titles/swperl/modern-perl-fourth-editio... With lots of elegant examples, this book really shows that perl is not a write-only language.
- chungus 5y agoDamian Conway's book Perl Best Practices. And here's the reason why I thought of it: at a previous job where we were stuck with a million lines of less-than-optimal perl code, and the original developers who only knew perl, we had to make a decision. Rewrite it in a more gentle language that suited our new developers too, or try to write better perl. Initially we went with better perl, we used a linter called perl critic that would refer you to specific sections of Damian Conway's book Perl Best Practices. We managed to write very nice code that pleased all the new FP enthousiasts present, and were able to onboard non perl developers (incl. myself) fairly easily. It didn't work out though. The problem? Our original perl developers were unable to work with our "flashy" new perl code. It might as well have been an entirely different language to them. As it often is, this was not a coding problem but a people problem.
- TurboHaskal 5y agoThis one is really good. I no longer work with Perl but it's one of the books that had the most impact on me. There are many things to take away from it no matter the language you code in.
- mst 5y agoWorth looking at e.g. http://p3rl.org/Keyword::Declare http://p3rl.org/Keyword::Declare for perlish macros mjd rocks but 2005 was before I made custom keywords in perl "work" on CPAN, and even further before people who were competent to do so obsoleted my horrific proof of concept hack with perl core features in 5.14/5.16 - which have since allowed many cool things such as http://p3rl.org/Future::AsyncAwait http://p3rl.org/Future::AsyncAwait Lisp macros are, of course, still cool, and this is why I got into this sort of hackery in the first place.
- dfee 5y ago> A few years ago I gave a conference talk in which I asserted that the C++ macro system blows goat dick. This remark has since become somewhat notorious, and the C++ fans hate me for it. But I did not think at the time that this would be controversial. I was sure that even the most rabid C++ fans would agree with me that the C++ macro system blows goat dick, for the reasons I have just described. A voice from a simpler time. Had me laughing.
- mjd 5y agoOriginal source: https://perl.plover.com/yak/design/samples/slide006.html https://perl.plover.com/yak/design/samples/slide006.html
- ggeorgovassilis 5y ago> One obvious advantage is that there hardly is any syntax. You can learn enough Lisp syntax to write useful programs in about ten minutes Perl encourages idiomatic programming styles which make collaboration difficult. I'm the eng mgr of a team which writes (among other things) Perl for big data processing applications and none of our programmers understand code the others have written without extensive (measured in weeks rather than days) analysis. I've never encountered the problem to this extent on Java code bases.
- scrapheap 5y agoCode can be written in all programming languages that is hard for other programmers to understand (including the original programmer a few weeks later). I find that Test Driven Development helps to tackle that issue as you get a set of tests that show what the code should be doing and the Refactor step reminds the programmer to restructure the code so that it's easier to understand.
- mst 5y agoI'd be happy to help solve that - email mdk@shadowcat.co.uk to get an NDÀ signed and I'd be delighted to spend a few hours gratis helping your team not have that problem anymore.
- sillysaurusx 5y agoI ended up writing the equivalent of lisp macros in C++, of all languages. One thing that helped greatly with that is the “defer” statement. It lets you defer a section of code to the end of the current scope. Which means you now have compile time access to the entire current scope. We’re writing a compiler for custom ML hardware using MLIR. MLIR has the concept of a current insertion point when you’re building an AST. emacs users will know where I’m going with this. We now have a save_excursion macro which stores the current cursor, then resets it at the end of the scope automatically. So when you’re building a loop or an if statement, you normally have to call (pseudocode): make loop set cursor to loop body make statements inside the loop set cursor to “after loop body” Now it’s make loop save_excursion(); make statements inside the loop Notice that the work decreased by 25% (three lines instead of four). In C++ land especially, this is a big win. The “make loop” part is actually so long that our linter breaks it onto several lines. But after making a macro for it, it looks like: affine_for(loop, idx, 0, n, 1); make statements inside the loop And the statements in the loop can of course reference “idx”, the iteration variable, or “loop” (a first class object representing a for loop). Boom, now the work is cut by 50%. Two lines of code. Technically it went from three to one, and it’s far more readable. The usual lisp disciplinary rules apply. You need to be familiar with variable capture, and how to make variable names at compile time. (In C++ I use a UNIQ(x) macro, which gives me a unique name for x. You can capture it into a #define by making a second #define and passing UNIQ(x) into it. So in practice most macros like save_excursion become two #defines, since you have to reference the unique name of the variable to store the cursor.) I don’t know if it’s common. I assume not. Most lispers are rightly allergic to C++. But most lispers also lose the benefits of working in a team setting — so in practice, porting as much benefit from lisp to other languages is the biggest win of all. And that requires you to learn lisp. (Interested readers should look up the Blub Paradox, then move on to studying On Lisp.)
- dinom 5y agoI'd like to point out that the strange occurrences of the "=3D" string are due to the fact that the message was originally a "quoted-printable" encoded email and for whatever reason this artifact wasn't removed when posted to the web. Perhaps this was pipermail's fault? Anyway, when reading the code, you're safe in assuming "=3D" is just a single plain old equal sign. In the "quoted-printable" encoding scheme the two characters following an equal sign are the hex value of the intended character. In effect, equal signs need to be escaped using the "=3D" sequence. This drove me a little nuts as I was reading and trying to code switch between the assorted languages used in the examples.
- ngcc_hk 5y agoThanks. Totally confused by that. Quite sad btw that many lisp book are old. And wonder if those Perl book can they be rewritten at least just GitHub source code only for study purpose.
- infogrind 5y agoAnd I thought it was ascii for “goat dick”
- stevelosh 5y agoAlternate source, with fixed formatting: https://gist.github.com/mjdominus/3841427 https://gist.github.com/mjdominus/3841427
- TurboHaskal 5y agoLisp macros are really cool. Programming is not satisfying to me without a similar feature. But, most people are happy with just typing and copy pasting stuff around. They don't care. I've shown them before and after macro refactoring code comparisons and they just stare blankly, they don't see the point. They code stuff like this on a daily basis: Var stuff() As Stuff stuff.Add(New Stuff("foo")) stuff.Add(New Stuff("bar")) stuff.Add(New Stuff("baz")) And they really don't have a problem with it :)
- zasdffaa 5y agoThis isn't even a macro thing, it just needs trivial use of procedures/methods, and I too have worked with people that are fine copying much larger chunks of code around rather than make a new function, and I just don't understand it. It's neater, safer and faster to encapsulate it, and they still don't.
- dgb23 5y agoThere are so many things I usually have to do before code organization and abstraction. Figure out how to go from A to B, find out if I really want B, find out if I need to pull this apart into more steps, try variations, read docs to see if there are things that might help me etc. I find it almost always better to write dumb code like this until I it does what it needs doing. It's much more straight forward, in a very literal sense, to find suitable abstraction and compression from there. DRY is about knowledge representation, not about repetition or boilerplate. Solving the former first in a good way lays the foundation for solving the latter, which can then be done with more powerful abstraction tools such as macros.
- tangjurine 5y agoI liked abstractions until I had to keep undoing them partially because I didn't perfectly understand the problem I was trying to solve... That's when I would feel the dumbest programming - undoing what was supposed to be me being smart. I think I read somewhere that the worst code comes from the wrong abstractions.
- innocentoldguy 5y agoLisp macros are cool because the source code is written directly as a low-level AST. Elixir macros are cool for the same reason.
- rurban 5y agoI guess he doesn't really know the parts when lisp macros are uncool. He even had the breaking example in his slide. The x++ part also breaks in lisp and only works in scheme, or when you have to introduce gensym into your macro. scheme macros are the real thing, but are not as simple and homomorph as lisp macros. they are more like constexpr matchers. if only we would have structural matching in our languages. and then do that at compile-time.
- dreamcompiler 5y agoUsing gensyms for single evaluation is normal for experienced Common Lisp macro writers. If you find it awkward, you can always write a macro to make it look cleaner :-)
- rurban 5y agoI'm fine with gensym and prefer it over scheme macros. But schemers have a lot to criticize on unhygienic macros.
- cryptonector 5y agoWell, to regurgitate from On Lisp, Lisp macros let you create new languages in Lisp, and they let you refactor quickly, etc. And, it's true.
- dunefox 5y agoI love the idea of Lisp, but every time I have a look at CL I feel it needs a fresh reboot without a lot of the... strange, ugly, or opaque stuff I guess. For example, some things are in-place, some aren't, and I'm usually running into strange problems that are difficult to debug. Granted, I'm a layman, but it makes learning quite difficult.