When you get to be smart writing a macro
1–10 of 28 posts
Re: When you get to be smart writing a macro
#2Re: When you get to be smart writing a macro
#3Re: When you get to be smart writing a macro
#4 #p x
is one character less than (p x)
When code golfing Lisps you can remove all whitespace after a closing paren, but not after a symbol. So in the following fully golfed token sequences, #p loses its one character advantage: #p x y
(p x)y
I bring up code golfing because that's what this is about, presumably.But what if the argument is a parenthesized expression:
#p(x)
(p(x))
#p is back in the game with a 1 char lead.The thing is, we can make the printing operator take arguments and turn them into an expression. Suppose we make a cousin of p called q, such that:
(q x) -> (p (x))
(q x y z) -> (p (x y z))
q no longer loses to #p: (q x)
#p(x)Re: When you get to be smart writing a macro
#5#p x is one character less than (p x) When code golfing Lisps you can remove all whitespace after a closing paren, but not after a symbol. So in the following fully golfed token sequences, #p loses its one character advantage: #p x y (p x)y I bring up code golfing because that's what this is about, presumably. But what if the argument is a parenthesized expression: #p(x) (p(x)) #p is back in the game with a 1 char le…
Inserting parentheses requires moving your cursor around or invoking some shortcut in your editor if you use paredit, vim-surround, or a similar plugin. Applies equally for removing the invocation (although paredit makes that part easy).
Re: When you get to be smart writing a macro
#6But the #p in the post seems to me to be a dubious choice for writing a macro. Too specific, too easy to use something else, too much confusion, too little gain.
Re: When you get to be smart writing a macro
#7Re: When you get to be smart writing a macro
#8I've come to the conclusion that macros are NEVER the right choice for normal application developers and only RARELY the right choice for library authors.
I would pick function over macros every single time.
Even in libraries, I feel that most uses of macros are unjustified. Even in cases where macros enable something that wouldn't otherwise be possible, I question whether its really the best way. For example, its pretty cool that core.async could be implemented as macros, but I feel that core.async has rather poor developer ergonomics because of it and building it into the language itself would have lead to a much better system with a much better developer experience. I have a number of reasons, but I'll just mention the biggest here: macros cannot see into functions, so core.async requires its async functions to be called directly within a go block (eg you cannot wrap core.async/Sometimes using macros means that things can be optimised at compile time (eg expanding core.match or specter selectors), but I feel these cases are pretty rare.
I do like many of the macros in clojure.core (threading macro etc) but I see these as a language implementation detail -- they could have been built into the language grammar or compiler and the end user experience would be the exact same.
I do wish Gleam supported some limited form of macros to generate code based on annotating types (kind of like Rust's derive), but I very much agree with Gleam's logic for not including macros, and my experience with Clojure has basically solidified my feelings that macros are very rarely a good idea.
Re: When you get to be smart writing a macro
#9#p x is one character less than (p x) When code golfing Lisps you can remove all whitespace after a closing paren, but not after a symbol. So in the following fully golfed token sequences, #p loses its one character advantage: #p x y (p x)y I bring up code golfing because that's what this is about, presumably. But what if the argument is a parenthesized expression: #p(x) (p(x)) #p is back in the game with a 1 char le…
I think what's more important than the character count is the fact that you can add #p with two key strokes. Inserting parentheses requires moving your cursor around or invoking some shortcut in your editor if you use paredit, vim-surround, or a similar plugin. Applies equally for removing the invocation (although paredit makes that part easy).