freenode/#lisp - IRC Chatlog
Search
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
12:45:01
jdz
Because you're probably reading the line from a stream, and the stream should not be always open, and you should be using WITH-OPEN-FILE (or at least WITH-OPEN-STREAM).
12:47:41
jdz
But you probably don't want to push single-element lists, just (push (read-line ...) *user-input*).
12:48:08
no-defun-allowed
FIlystyn: have you written any other Lisp? That's not valid Lisp syntax, nor does it look very nice.
12:49:17
no-defun-allowed
Right, that's better. Now, you can remove the spaces between parens and names.
12:50:32
no-defun-allowed
Yeah, you should never have any space between names and their closest parens basically.
12:51:12
no-defun-allowed
And you will probably get better responses on #clschool, even if there's less participants.
13:11:25
pfdietz
A problem that LOOP or ITERATE (or any complex macro) should address: how can code walkers descend into this without expanding the macro?
13:14:22
pfdietz
The general problem is: do something to all the forms in a piece of program text. So, how do you find all those forms?
13:16:00
pfdietz
The old example I keep looking at is Waters' COVER package. It adds coverage annotations at all the branch points in code (inside a DEFUN or whatever).
13:16:22
pfdietz
And it has to cheat a bit to do that. And as a result, it doesn't work with code that uses ITERATE.
13:17:56
Bike
shivers's loop involves some kind of "low level" macros; skimmed the paper, don't really get it, still has something called syntax-rules
13:18:05
chris4197
I am really liking lisp so far. Even though I just know the basics of the basics so far.
13:29:30
jackdaniel
if you like melding with CL implementations I can suggest ECL, if you like clos-ology I can suggest McCLIM (I'm working on both projects so I will be able to help)
13:29:56
jackdaniel
if you look for some other bits and pieces you may look at projects at sharplispers group on github and try to fix issues in them
14:21:33
pfdietz
chris4107: there are json and xml parsers in CL already. Best to just use an existing one. If you feel the need to hack on one, improving test suites is always welcome.
14:28:22
Xach
I think it would be easier than xml but not as easy as json processing, and also when you're done you'd have something useful
14:29:23
Xach
cl-ppcre source code is also very interesting to read and worth studying to learn CL features
14:32:45
Xach
jdz: i would use it to decide how to process network data without first converting it to strings, which is costly in both time and space on my favorite CL (sbcl)
14:33:46
Xach
but if the data is utf-8 or ascii or whatever, being able to find interesting subsequences and doing targeted conversion would be handy
14:35:50
Xach
Here's the thinking. Converting 100mb to strings to search for the string "foobar" is more wasteful than converting the string "foobar" to octets and searching without conversion.
14:37:12
Xach
This comes up when parsing binary data in structured formats, whether on disk or over the network or whatever.
14:37:46
jdz
Xach: In my case I'm also looking for interesting bits in binary blobs, but then sometimes the blobs are UTF-16 encoded strings, and such thing would not help much, so I'm always converting.
14:39:11
jdz
Well, every other octet is 0. If I was looking for a specific string, then yes. But I'm looking for patterns.
14:40:21
jdz
Xach: Yes. I understand that such patterns can be translated from string into binary form.
14:44:25
Xach
Oh, and it's incomplete to say it only comes up in binary contexts. A text file is a binary file on disk. Writing grep with cl-ppcre loses because the conversion is expensive. If you matched without converting it would lose less.
14:45:03
jdz
I still have not proved to myself that this change https://github.com/jdz/cl-ppcre/commit/89d89c8477841d83ff7d83b26cdf51aaea9ce76e should be merged upstream, but it works for me.
14:45:41
jdz
But then, I think that not confusing octets with characters is a really great feature of CL (just look at all the Python2 vs. Python3 mess0.
14:47:43
Xach
chris4197: cl-ppcre is a really fun read and shows a cool way to handle stuff like that.