freenode/#lisp - IRC Chatlog
Search
0:10:49
aeth
pjb: (1) alexandria has some macros to simplify that and (2) I think Common Lisp can run on a real time machine
0:11:59
dialectic
seok: Helpful hint. Only write your program using functions. When you find yourself repeating the same thing over and over, then you can reach for defmacro.
4:04:05
vsync
dialectic: though I find it handy to (partly) write in the language I wish I had... or is that an advanced technique?
4:06:04
vsync
and I would say as well, when you do write macros, write them in terms of functions as much as possible... that tripped me up earlier on when I first got really into macros
4:08:26
vsync
problems I ran into were: 1) doing too much restructuring or especially building of code constructs "inline" in the macro rather than factoring out; 2) having all the generated code be inline even when it could be factored out into a function call
4:09:13
vsync
helps debugging to have my macro call functions to do its work and the generated code sometimes call functions to do its work... and found the resulting code clearer as well
4:09:31
aeth
Basically never write macros. Eventually you'll find some boilerplate that will frustrate you enough that you'll break that rule. Some exceptions could be made for ones that fit established patterns like define-foo, with-foo, and do-foo
4:10:51
aeth
And, yes, if you're writing functions, put most of the generation work into functions or at least LET variable bindings and have the actual quasiquoted macro look like this: `(let ,(generate-bindings foo bar) ,@(pre-body bar baz) ,@body ,@post-body)
4:11:17
vsync
aeth: would you support those constructs being recognized as first-class things with language support, e.g., DEFDEFINER, DEFWITHER?
4:12:19
aeth
A define-define that covers 90% of the cases when you want to make a defun or global defparameter/defvar/defconstant, as well as a define-with that covers the basic with-pattern of unwind-protect, would help a lot
4:12:36
aeth
define-do would be harder since you could base your do-foo on loop, do, tagbody/go, or even higher order functions like map
4:14:16
aeth
vsync: DO is structurally an extremely simple TAGBODY with GO and a LET binding around it
4:15:00
aeth
vsync: You can just use the implicit tagbody in DO and confuse people (and probably tools like Emacs)
4:15:23
aeth
dialectic: people only hate DO because they never use it... you can do amazing things with it
4:15:56
aeth
the thing DO gets you is the ability to MACROEXPAND-1 it and see how it is implemented, and how it is probably implemented with only a few differences in other implementations
4:16:26
dialectic
I am an open minded person. I let DO into my life. DO let me down. I no longer use DO.
4:16:56
dialectic
Any macro which makes me commit to memory a totally arbitrary syntax is a design failure.
4:17:12
aeth
The best DOs are zero-body DOs. If you have a body (that's more than just declarations) you're probably doing something that would be clearer with some other iteration form (or defining your own)
4:18:28
dialectic
A DO that has no body is almost always clearer as a LOOP anyway. And in a loop I have the option of splitting the initialization and iteration.
4:19:14
dialectic
And... I can also throw in arbitrary body forms, interspersed with the iteration code. It is just so much more readable, but I get this is preference.
4:19:35
aeth
dialectic: A DO is only clearer as a LOOP if you don't think that you should use the simplest iteration that accomplishes the task
4:20:19
aeth
LdBeth: map/mapcar is extremely clear... if the thing you're iterating with is a function, like (mapcar #'first list)
4:22:02
aeth
dialectic: the only simple iteration that works fine in DO that I think is clearer in LOOP is something like where you're reading because there you have (foo (read-whatever ...) (read-whatever ...)) vs. :for foo := (read-whatever ...)
4:23:19
aeth
LOOP could give you a deleting unreachable code note/warning if the ":for foo := (read-whatever ...)" is only run once since it's technically generating two things, too.
4:24:29
aeth
dialectic: because I want my editor to highlight it like a keyword, and, as an added benefit, I get a pseudo-Pascal :=
4:25:30
aeth
LOOP is a mini-ALGOL-like language where e.g. "for" is a keyword (in non-Lisp terms) but by making it ":for" it's also a keyword in Lisp terms and is highlighted specially
4:26:41
aeth
dialectic: and besides, the first time I used the LOOP example with keywords, I didn't put "s around it or otherwise distinguish it, but it was immediately clear that the "for" wasn't prose
4:32:45
aeth
LdBeth: I love messing with lots of parentheses, and as much as I've gotten used to LOOP, I don't like that it's :for foo :in bar instead of (:for foo :in bar)
4:41:44
aeth
LdBeth: which is why it would use a plist... it would be mostly loop compatible but order wouldn't matter
4:46:11
aeth
There might be some LOOP forms where it can't be represented as unique keys, though. Not sure.
4:47:00
aeth
The only reason I haven't done this yet is because reimplementing LOOP would be a lot of work, even if I might be able to get away with implementing a lot of it IN loop
4:47:29
aeth
stylewarning: I don't dislike LOOP, I literally just want LOOP with parentheses for more Lispiness, and ITERATE fans pitch it as that, but it's not
4:48:06
aeth
my biggest loops have been implementing numeric algorithms, and the :of-type double-float all over the place doesn't help keep it brief
4:50:21
aeth
stylewarning: that probably counts too since it's the same principle just a different domain (translating massive algorithms)
4:51:30
stylewarning
Lots of loops here https://github.com/rigetti/quilc/blob/master/src/addresser/temporal-addresser.lisp
4:52:24
stylewarning
phat loop here https://github.com/rigetti/quilc/blob/master/src/addresser/astar-rewiring-search.lisp
11:31:56
luis
aeth: LOOP is useful for many things besides collect. Parallel iteration, for instance. Also, iterating over sequences. And of course, it shines when you want to do all of those things at once.
11:35:29
luis
ck_: you can probably hack slime to make it always show the macroexpansion of loop inline using macrostep-expand. That way you could see the true way at all times.
11:36:12
jackdaniel
luis: is it possible to make slime inline macroexpand things put under macrolet?
11:46:49
luis
jackdaniel: looking at swank-macrostep::enclose-form-in-context, it looks like the mechanism can sometimes fail, so you might have come across one of those scenarios. Also, it doesn't work for slime-expand-1 (C-c RET)
11:48:36
ck_
luis: there's slime-trace-dialog-autofollow-mode, which was maybe originally intended to do something like we discussed (?), but it is acting pretty weird when I set it. Do you have any experience with that?
11:56:03
ck_
depending on [mysteries of the universe], it opens the inspector on the thing below the point