freenode/lisp - IRC Chatlog
Search
17:27:44
elderK
So, I'm slowly managing to understand it. Just by reading it... Force of will and all that.
17:27:57
elderK
It's made harder because it seems that he's used tabs in his source. But, inconsistently.
17:34:59
elderK
I mean, it's nice code and all. The majority of it is pretty nice. Just, iono, it gives me something to think about. Like, now that I'm starting to understand the ins and outs of his define-binary-struct macro, I'm thinking: Could this be written in a way that is clearer or easier to read?
17:35:29
elderK
Over the past few months, I've been spending a lot of time reading code. I wouldn't say I've spent more time reading than writing but I've definitely upped the amount of time I spent reading "foreign" code.
17:36:20
elderK
:P I've started telling my tiny group of friends that they should try and read code as much as they write it so that they like... develop a sense of what's hard to read, and what isn't and so on.
17:36:44
elderK
I /should/ be working on sleep. But, iono, I feel oddly compelled to keep reading. :)
17:56:49
jebes
with the direction the IT industry is going, we just need to rebrand it as something else
18:26:38
jackdaniel
Java is a decent language. it is not CL, but isn't as bad as people try to shame it
18:27:59
jackdaniel
as of name of a common lisp for wide audience, we should call it "Not a Common Lisp" and claim that it has been developed by "The average Joe programmer"
18:30:21
jcowan
The R2RS report on Scheme was subtitled "An Uncommon Lisp". A stupid piece of snark IMAO, and I'm glad we dropped it.
18:31:44
elderK
Interesting. CLHS says that unless you specify :read-only nil as a defstruct slot option, it's implemention-defined whether or not there'll be a setf expander for it.
18:37:56
elderK
This really does seem kind of.. confusing: http://www.lispworks.com/documentation/lw70/CLHS/Body/m_defstr.htm
18:38:03
jcowan
The sentence "When this option is false or unsupplied, it is implementation-dependent whether the ability to write the slot is implemented by a setf function or a setf expander" has a bad ambiguity in it
18:38:09
elderK
Early in the description, it states that it creates readers for the slots, and they are setfable
18:38:38
elderK
Then later it says if you don't specify :read-only, or give it a falsey value for :read-only, it's implementation defined whether the slots are setfable.
18:38:58
jcowan
I read it as meaning that an implementation may use a setf function or a setf expander, whereas you are reading it as if it ended in "... or not".
18:39:43
elderK
I thought like, if you wanted to do (setf (something) value), you had to have a setf expansion?
18:40:13
pjb
elderK: setf can work in other ways than with a setf function or a defsetf or setf expander.
18:40:17
jcowan
On my reading, it doesn't say that setfability is optional, it says that the means of providing it (function or expander) is up to the implementation. But I agree that it's badly drafted.
18:40:50
pjb
elderK: this is a door open to let implementation optimize structures in very special ways.
18:41:26
pjb
Some old implementations took advantage of it. Modern implementations tend to define structures as subclasses of clos objects.
18:41:28
makomo
elderK: a "setf function" and a "setf expander" are just two ways of providing a "place" for SETF to operate on
18:43:52
elderK
So, as long as you are able to (setf (struct-slot ...) ...), it's just saying how you manage to provide that ability is open.
18:45:02
elderK
I have now learned that if you create a macro, you really should define the grammar of that somewhere so people can see exactly how it is to be used, just like CLHS does for say, defstruct or defclass. :D
18:45:40
elderK
It's not really doing anything all that complicated, not really. Just, very... clumped together.
18:45:46
makomo
or if the macro is simple enough, a couple of examples with their expansions or something
18:46:07
elderK
And ideally, you'd have all of those figured out before you started writing the macro, anyway.
18:46:29
elderK
I get the feeling that the binary-types stuff was intended to support more stuff originally, or in the future, but was never... fully completed.
18:48:09
elderK
Or rather, the goalpost changed. It is complete. But there are signs that it was meant to do more.
19:02:24
elderK
Question: If a macro is meant to evaluate one of its arguments, does it have to call eval on it?
19:03:11
makomo
elderK: good question. you're referring to evaluating the argument whilst computing the expansion, right?
19:03:39
makomo
(instead of arranging for the argument to be evaluated within the generated expansion)
19:03:49
elderK
I think so, yes. I'm not entirely 100% sure what I'm asking. I just know that some macros say "The argument is not evaluated" and others say "The argument is evaluated in the environment active at the time the macro was called."
19:04:01
pjb
elderK: no it doesn't have to evaluate, but ensure that the argument is evaluated at run-time.
19:04:26
makomo
elderK: you're thinking of the latter then. the former would be macroexpansion-time evaluation, which is a rare thing to do
19:04:29
pjb
elderK: in general it would be difficult to evaluate something at macroexpansion time, because EVAL doesn't take an environment argument.
19:05:32
elderK
Interesting. So, "argument is not evaluated", is that the same as just... splicing it directly into the expansion somehow? Or do you splice in the argument, quoted?
19:05:35
pjb
elderK: so the only case where you would "evaluate" something at macroexpansion time, would be when that something would be a macro or symbol-macro and you would 'evaluate" it by macroexpanding it.
19:06:34
pjb
(defmacro set-double (var expression) "evaluates the expressions and binds the resulting value to the variable var" `(setf ,var ,expression))
19:06:43
pjb
(defmacro set-double (var expression) "evaluates the expressions and binds the resulting value times 2 to the variable var" `(setf ,var (* 2 ,expression)))
19:06:56
elderK
Okay, and if the argument /is/ evaluated, you mentioned you'd arrange to /have/ it evaluated at the right time. How would you go about doing that? Would you create some gensymed variable somewhere and say, hey, evaluate this at whatever time, and use this gensym when referring to the "argument"?
19:07:36
makomo
what pjb just described is the case when the arguments /are/ evaluated (by arranging for them to be evaluated within the expansion)
19:07:44
pjb
Here, since ,var is in a place position in the setf form, it's not "evaluated" as such (it's evaluated as a place by setf). But since expression is expanded in a position that is evaluated by setf, then set-double has fulfilled its contract.
19:08:18
makomo
elderK: to "arrange for something to be evaluated" means to splice it into the proper places within the expansion
19:08:39
elderK
Okay, and to have it /not evaluated/ would mean to splice it in, but make sure it's quoted when spliced?
19:08:57
pjb
Basically, standard special operators and macros define what argument is evalauted and when, and what are not. And function calls evalutes all its arguments.
19:09:35
pjb
So macros can use their own parameters in those different ways, by putting them in forms using those special operators and macros or fucntion correspondingly.
19:10:51
elderK
Aye, but what's to stop them giving us some (make-symbol ....) thing? In that case, we are relying on LET not evaluating the names, right?
19:11:16
makomo
elderK: if they do so, the expansion will be incorrect, as the NAME will be the actual form (MAKE-SYMBOL ...)
19:11:35
elderK
For argument sake, let's assume LET itself is a macro and expands to something else, maybe a lambda or something, who knows. Then the name would be expanded into a lambda list. And that's where the error would be caught, no?
19:12:43
elderK
So, basically, whether or not something is evaluated or not, really depends on 1. We quote it when we create our expansion like ',name. OR it depends on what operators we use with that spliced argument.
19:13:09
pjb
(defmacro let ((&rest bindings) &body declarations-and-body) `((lambda ,@(mapcar (lambda (x) (if (listp x) (first x) x)) bindings) ,@declaration-and-body) ,@(mapcar (lambda (x) (if (listp x) (second x) nil))))) ; more or less
19:13:17
makomo
elderK: perhaps. what if you pass in an expression that is something like (&optional hi) and the LET macro splices its arguments? you might actually get a valid lambda list :-)
19:13:49
White_Flame
elderK: the way I normally state it is that macros take source code and return source code. If your macro foo is called as (foo a b (bar baz)), it gets the _source code_ forms A, B, (BAR BAZ). Any values associated to those probably don't exist, unless you're very particular in your build to assure some (usually global) values exist at compile-time
19:13:49
elderK
pjb: I appreciate you trying to help but code dumps like that in IRC are not all that helpful.
19:13:58
makomo
elderK: but yes, hopefully the error would be caught somewhere (either in the expansion (at run-time when the code is run) or the macro itself would catch it by doing some analysis)
19:14:05
pjb
(defmacro let. ((&rest bindings) &body declarations-and-body) `((lambda ,@(mapcar (lambda (x) (if (listp x) (first x) x)) bindings) ,@declarations-and-body) ,@(mapcar (lambda (x) (if (listp x) (second x) nil)) bindings))) (macroexpand-1 '(let. ((a 1) (b 2)) (+ a b))) #| --> ((lambda a b (+ a b)) 1 2) ; t |#
19:14:44
makomo
elderK: in the end, whether or not a macro argument is evaluated depends on the expansion produced. if the expansion evaluates an expression that was bound to a macro argument ARG, we say that the macro evaluates ARG
19:14:45
pjb
elderK: Sorry, I don't see the difference between 300 characters of english and 300 characters of lisp.
19:15:23
elderK
pjb: It's less the code that is the problem, tbh. It's more than in IRC, it's all squished into one or two lines and I'd need to copy it out, format it, so that I could understand it. The more code there is, the more I need to do that.
19:15:48
makomo
elderK: but saying that "the macro evaluates ARG" is technically incorrect, as it's not the macro that evaluates it (at macroexpansion time), it's the expansion that it produces
19:16:07
makomo
but evaluating at macroexpansion-time is so rare that we take that sentence to mean the conventional thing that everyone just described
19:16:12
pjb
emacs matches the parentheses so you don't have to copy and paste and indent in general. it's enough to move the cursor over the parentheses. emacs shows the structure autoamtically.
19:17:07
elderK
makomo: Thank you. And aye, I should be clearer. White_Flame, that's how I see macros too.
19:17:28
pjb
elderK: but don't you already have a command that does that automatically? I thought vim was scritable too.
19:18:00
elderK
pjb: Vim handles paren matching, etc, etc. But code in IRC still requires me to copy the stuff out of IRC, into Vim, then I have to do whatever to format it.
19:18:04
makomo
elderK: if you want to document that something actually gets evaluated at macroexpansion-time, then you would say "evaluates ARG at macroexpansion-time" (instead of just "evaluates ARG")
19:18:06
pjb
elderK: see for example: com.informatimago.common-lisp.cesarum.utility:define-structure-class
19:19:26
pjb
(defpackage "COM.INFORMATIMAGO.MY.CURRENT.PROGRAM" (:use "COMMON-LISP" "COM.INFORMATIMAGO.COMMON-LISP.CESARUM.UTILITY)) (in-package "COM.INFORMATIMAGO.MY.CURRENT.PROGRAM")
19:20:04
pjb
elderK: Since most of my code is written in libraries, it cannot use package nicknames.
19:22:16
elderK
I kind of want to reimplement binary-types as a learning exercise. I'd like to see if I can do it cleaner.
19:23:03
elderK
Which raises another question: Macro expansion is recursive, right? Like, if a macro's expansion has another macro in it, that macro will be expanded and do on until it's entirely expanded?
19:23:56
jcowan
Specifically, when a form is being macroexpanded, it is examined for the outermost macro(s) and they are expanded and plugged back into the form. This repeats until no more macroexpansion can be done.
19:24:08
elderK
It seems like it might be useful to have helper-macros then. Smaller macros that help implement the larger ones. Maybe that would have helped make define-binary-struct more understandable.
19:25:24
elderK
So, is there anything wrong with using macros as a way to conveniently destructure stuff?
19:28:40
pjb
quicklisp uses it to log the packages that are loaded and display the dots when compiling, I believe.
19:29:04
elderK
binary-types goes through a lot of effort to like, destructure it's input in a lot of ways. Is there anything against defining a macro to do that for you?
19:29:31
elderK
Probably best to write it as a normal function though, right? Maybe local to the macro itself.
19:29:58
pjb
again, macros are functions like other functions, So you can refactorize them as you wish and would do for other functions.
19:30:33
elderK
I guess this does raise an interesting question though, at least for me: How do you ensure that a macro, which has a ton of local functions, is understandable? Do you just ensure they are all small? Is there some conventional way to format it such that things are better... delineated?
19:30:39
pjb
And if you re-read my example substituting backquote with list and other abstract functions I gave yesterday, it more readable.
19:31:10
elderK
I would have broken the expansion process into a lot of little helper functions, that would be available at compile-time.
19:32:41
elderK
It's a lot easier for me to deal with lots of small functions, than one giant overnested one.
19:33:35
elderK
Although, there must be a way to format the code such that a bunch of local functions bound with flet, are jsut as understandable as a bunch of functions made with defun.
19:34:02
elderK
The deeper you are nested when you define your functions, the less space you have per line for the body of a function.
19:34:38
elderK
So, just because things are all in a list, doesn't mean they have to be rammed up together, you can insert whitespace and stuff where you please, if it helps. Cool :)
19:35:14
elderK
equwal: Longer vs Wider? :) I don't own the LoL book yet, I am unfamiliar with those macros.
19:36:12
equwal
I just mean if you want to have locally bound functions without using let-like forms you can use anaphors. https://letoverlambda.com/index.cl/toc
19:37:17
makomo
equwal: yeah, same. i read it already, but i wanted to have a deadtree copy as well :-D
19:38:35
equwal
makomo: I used to have paper copies of a bunch of books, but once I read them I found it is easier to have the HTML files stored locally from httrack.
19:39:05
makomo
say i have a "context macro" (i.e. WITH-SOMETHING) but it doesn't really take any arguments except for the body. should i still have an empty list as its 2nd argument just because of convention or not?
19:39:51
makomo
equwal: i also read all of my books in digital form most of the time, but this one i wanted to have irl :-)
19:40:12
equwal
I like to minimize parentheses even when it breaks convention. Anyone with slime can see the arglist in the minibuffer anyway, why not use it?
19:41:22
equwal
Personally I think COND is a bit of a mistake with the (cond (predicate result)) syntax. (cond predicate result) would have been better I think, for example.
19:42:29
pjb
(cond (condition1 expr11 expr12 … expr1n) (condition2 expr21 expr22 … expr2n) … (conditionp exprp1 exprp2 … exprpn)
19:43:00
pjb
also, there's no difference in memory and processing time between an a-list and a p-list.
19:43:18
elderK
equwal: I find electronic books to be a lot better than deadtree these days, mostly because of the ability to zoom :)
19:43:57
pjb
You can even define a macro (cond. test1 => a b c test2 => d e test3 => f g h else i j)
19:44:22
equwal
Well that is a place where I don't want a print copy. The locally stored hyperspec with slime is the best way to look at code docs I've ever used.
19:46:37
jackdaniel
I'm talking about his personal aesthetics, not yours, so you can't informely say nope (unless you are the same person)
19:47:17
pjb
or (if* condition then something else) if you prefer. or (if* condition else something) for unless
19:48:23
equwal
I think an example that supports my case is where you have a macro that calls another macro for every argument. Like if you have a unit test macro (deftest code result) you might have (deftests code1 result code2 result...) instead of (deftests (code1 result) (code2 result)).
19:52:19
NoNumber
Is PCL still a recommended text here in #lisp? Want to make sure I'm not wasting my time going through it.
19:52:30
pjb
and of course, with embedded ifs: (loop repeat 1 if (= a 1) then if (= b 1) do (something) else do (something-else) end else do (something-a/=1))
19:55:58
elderK
I spent a lot of time playing in Scheme. Lovely language. Great implementations with fantastic communities.
19:59:14
equwal
I don't know if I want that. I like scheme because it is a good simple, small language.
19:59:52
elderK
Silly subjective reasons, too. Like, I like define :) and the way predicates and things are denoted.
20:01:01
equwal
If you go back and look at the history you see that CL got stuck with bad design decisions in order to support old code. Great example is the separate namespaces.
20:01:47
elderK
How many times have you seen people contort the word "list" in an arglist just because they'd shadow the "list" function in Scheme code?
20:05:31
equwal
(defmacro y (lambda-list-args specific-args &rest code) `(labels ((f ,lambda-list-args . ,code)) (f ,@specific-args)))
20:19:00
aeth
CL has some concise/odd/unusual names accidentally because they're old and legacy names and CL is mostly compatible with those old versions. Some of these, like defun or mapcar or dolist seem fairly common. Others, like set or get or rplaca, are basically never used.
20:19:17
aeth
Both Arc and Clojure decided concise names were great and that everyone should save 3 keystrokes.
20:19:58
pjb
actually, you may be saving more keystrokes with the longer names, and emacs completion than with the short names, that are more ambiguous.
20:21:06
aeth
If you write "dofoo" instead of "do-foo" even though "dolist" exists, I don't like your code. Always hyphenate. And please don't abbreviate. Pretty much the only exceptions I can think of are (1) an accepted abbreviation like "id" that seems more right than the correct full form and (2) something like aref or + that's clearly designed to have potentially many on one line
20:22:40
aeth
Emacs will glaldy recognize do-foo as a new form of iteration and highlight it purple. It will *not* do so for dofoo. Are you going to make your users install a gigantic, messy .emacs file?
20:23:06
equwal
I think an immense line like (multiple-value-bind (the-first-thing the-second-thing) (long-names this-line-is-very-long)) is just hard to read. If you abbreviate you get a nice (mvbind (fn arg) (...))
20:23:07
aeth
There are edge cases where indentation simply won't work, but any random do-foo in particular should pretty much work for everyone, highlighting *and* indentation.
20:24:27
aeth
pjb: If Common Lisp were written from scratch using Common Lisp's newer naming standards and no backwards compatibility in names, it would be define-variable, not defvar. And it wouldn't matter because you shouldn't be using it often enough for it to matter, anyway.
20:24:48
aeth
Don't use old names as an example of what to do. That's how you get Clojure creating *new* ugly names in the 2000s
20:25:17
pjb
old names were short because 6 characters stood in a word (36-bit words, 6-bit per character).
20:25:53
aeth
Now, "defun" might be the one reasonable exception to "define-foo". Maybe "defmacro" and "defmethod" as well because they're the basic building blocks of your program. Honestly? define-class would make more sense. It's not like defclass is even built with conciseness in mind.
20:27:52
aeth
Although, really... I don't really have an issue with using define-function all over my code, though. I thought I might, but I don't. Turns out that when I'm adding functions, the extra second to type out 'define-function' doesn't really slow me down.
20:28:06
anamorphic
Hi, I'm a bit stumped with this expression from the defsetf docs at http://clhs.lisp.se/Body/m_defset.htm (defun xy (&key ((x x) 0) ((y y) 0)) (aref *xy* x y)) - I'm not sure what that keyword arg syntax does
20:32:00
anamorphic
Is there some reason in that example code for defsetf that they need to not export a keyword?
20:33:40
pjb
No. it's purely incidental. Perhaps they hadn't completed the specification of &key yet when the wrote the example.
20:34:10
pjb
Or perhaps the person who wrote the example was the promotor of being able to use normal symbols for &key arguments in addition to keywords.
20:37:11
makomo
elderK: regarding the named let, Let Over Lambda does exactly that :-) (implement it as a macro)
20:39:15
elderK
makomo: I imagine you could synthesize named-let with clever use of block or tagbody or something
20:41:39
equwal
Loop is pretty imperative. I like series but there are too many restrictions that make is difficult to know if something will work.
20:42:08
pjb
but you may want to transform the recursion into an interation to avoid using too much stack.
20:43:40
elderK
Well, I was thinking of something that... wouldn't use recursion unless it had to :)
20:44:40
equwal
Chapter 4 is great for getting into read macros. Doesn't require lots of experience.
20:48:24
equwal
Why not just read the first first six chapters? At your level you might not get much from the two non-free chapters anyway.
20:48:37
elderK
I might try writing once-only myself for fun - but I need to really understand /exactly/ what it's doing, first.
20:48:55
makomo
elderK: i would still try just reading it. LoL was the 2nd CL book i started reading
20:49:23
makomo
but as soon as i saw LoL, i had to read it. at that time i was very interested in macros and i wanted to see everything you could do with them
20:50:24
makomo
ONCE-ONLY is indeed a nice exercise, but yeah, you'll want to first start by defining the problem it's designed to solve
20:50:42
equwal
makomo: You'd like OnLisp. The whole book is about macros like LOL http://www.paulgraham.com/onlisp.html
20:52:45
makomo
elderK: to spice it up -- ONCE-ONLY is a macro that writes parts of other macros, i.e. it writes part of another macro's *expander* (the macro itself, the code which produces the expansion)
20:53:00
elderK
Create some gensyms, bind them to the result of evaluating whatever. Then rebind those names to the gensym'd ones. Have the rest of the expansion happen inside the form that creatse those bindings?
20:54:29
makomo
elderK: i guess that's correct, but it's a bit hard to describe in English without explicit reference to the various macroexpansion "levels"
20:55:05
makomo
so it might not be 100% correct, depending on the precise meaning you had in mind :-)
20:55:48
makomo
as ONCE-ONLY has to (1) be hygienic itself and (2) produce expanders which are hygienic
20:58:32
makomo
there are 2 things to learn, (1) the conceptual problem that ONCE-ONLY is designed to solve and (2) the backquote hackery that ONCE-ONLY relies on
20:59:54
makomo
LoL also implements ONCE-ONLY but in a much easier and neater, but sadly unportable way (nested backquotes are neat in their own way though :-))
21:03:42
equwal
I wonder how to understand triple or more backquotes. Like how can I understand what ``````(,@,,@,,,@thing) would do?
21:03:58
pjb
elderK: for example, let's write a macro that takes one argument x and builds a list where x is present twice: (list x x)
21:04:30
pjb
(defmacro double (x) `(list ,x ,x)) (double 42) #| --> (42 42) |# but (let ((x 41)) (double (incf x))) #| --> (42 43) |#
21:05:05
makomo
elderK: exactly as you said -- make sure that a macro argument is evaluated only once, but without doing it manually. usually you would (1) create a gensym, (2) bind the gensym within the expansion to the result of evaluating your ARG and (3) use the gensym instead of ARG everywhere within the expansion
21:05:19
pjb
So you must introduce a temp variable: (defmacro double (x) (let ((vx (gensym))) `(let ((,vx ,x)) (list ,vx ,vx)))) (let ((x 41)) (double (incf x))) #| --> (42 42) |#
21:05:44
makomo
elderK: ONCE-ONLY automates that, for an arbitrary number of symbols (known at compile-time)
21:05:48
pjb
once-only does this automatically, and use the same name for the temp variable, so you don't have to substitute it.
21:06:14
equwal
elderK: You don't have to announce every exit you make from an IRC. Most people come and go, and go long periods without answering.
21:06:35
pjb
Now, personnaly, I've never used once-only, On the rare enough occasions, I use gensym explicitely…
21:06:59
makomo
equwal: that's a good question. i have a writeup within my own notes somewhere which i've been meaning to publish if i ever get a blog or something
21:07:39
makomo
equwal: but the basic principle is the "ladder algorithm". the number of quotes indicates the number of times an expression will get evaluated (iteratively)
21:07:59
equwal
(defun interpol (obj lst) (shuffle lst (loop for #1=#.(gensym) in (cdr lst) collect obj)))
21:08:12
makomo
equwal: which of course assumes multiple (iterative) evaluations of the nested backquote form
21:08:13
elderK
makomo: I think you just touched on something I was meaning to ask: What's the deal with multiple levels of quoting and unquoting?
21:08:35
equwal
Basically I don't want to (length lst) when I could just throw things away with a readtime gensym.
21:08:46
makomo
` is a *reader macro* that reads in as some implementation-defined form that when evaluated produces a list according to a template
21:11:56
makomo
when using N nested backquotes it is expected that you will iteratively eval the form N times. to iteratively eval N times means to do (eval (eval ... (eval form)))
21:12:11
equwal
Read this paper and post-it note the clichés on your computer if you want: https://3e8.org/pub/scheme/doc/Quasiquotation%20in%20Lisp%20(Bawden).pdf fairly famous paper.
21:13:16
makomo
elderK: which means that the rightmost comma is the evaluation that'll be performed as part of evaluating the outermost backquote
21:14:00
makomo
so the ,',a idiom is basically "give me the result of evaluating A once, as part of the first evaluation"
21:14:45
makomo
err, "after 2 evaluations, give me the result of evaluating A as part of the first evaluation"
21:15:52
makomo
the quote in there makes the leftmost comma act as a no-op, which is the point of the idiom
21:17:10
elderK
makomo: Other than the linked PDF, are there any other sources of information on this particular topic that helped you understand multiple-level quotes and stuff?
21:18:31
makomo
elderK: only this really http://www.lispworks.com/documentation/HyperSpec/Body/02_df.htm
21:19:12
makomo
the books are only good for examples of backquote, not really for explaining how it *really* works
21:20:40
makomo
elderK: if you make it your goal to really understand backquote, i would suggest to study the formal rules in the CLHS
21:36:48
jmercouris
so, I'm working on S-XML-RPC with ambrevar on Gnu/Linux, here's what happens when he tries to receive a message in SBCL https://gist.github.com/jmercouris/756d0d10d4ca9aa0a1ebfe9261e9d1d2
21:42:56
jmercouris
if anyone does see something fascinating in the REPL output, please send me an email: john@atlas.engineer
22:56:21
didi
Hum, I think this is the first time I want to use a symbol that is locked to define a function (INTERSECTION).
0:12:42
equwal
They're important. Just make a package so you wont clobber cl-user and you're good to go.
0:14:43
didi
equwal: Ah, yes. I do it like that. I have some packages (and their systems). But I don't think I've played any advanced game yet.
0:20:54
equwal
If you are working from in a package you can make it external but not import it so you access it with package-name:intersection leaving the standard alone.
1:06:40
equwal
How can I change a regular character like #\f to a read macro without a dispatch character? This way I can call a read macro as if it were a function (fn...)?
1:09:56
no-defun-allowed
(defmacro brainfuck (code) `(lambda () (brainfuck-interpret ,(symbol-name code)))
1:10:21
equwal
I got it working like this: #defmacro/g! name (z) `(let ((,g!y ,z)) (list ,g!y ,g!y))
1:12:07
equwal
It does parentheses by just counting until there is an extra one on the right. I am trying to set it up such that it can be called with (defmacro/g!...) making #\d the macro-character. Unfortunately I can't do it without making it impossible to defun declare, etc.
1:13:09
Bike
putting a reader macro on d means when the reader sees a d, you take over parsing. you can't just do it halfway.
1:14:56
equwal
Well I could do that, but I was hoping to get it semantically the same as the book so I could send it to the production code repo.
1:15:45
Bike
there is no such thing as a fake function. i'm not sure where you got the idea that there was.
1:16:47
equwal
I could get it to work if, for example, I set the reader to activate a reader macro if it reads "DEFMACRO/G!"
1:18:03
Bike
as an example, if you had '(defmacro/g! ...), with your scheme funny things would happen.
1:23:19
no-defun-allowed
all i can suggest is to write a macro that takes the code as an argument, takes the SYMBOL-NAME of the symbol and uninterns it
1:40:58
no-defun-allowed
not a reader macro, just a normal macro which reads in your code as an an argument, eg (brainfuck [+.>])
1:43:11
equwal
I used the brainfuck because I though I was simplifying my question. I don't see why what I want to do should be impossible. I think I can do it if I save the original readtable and access it before reverting and the closing parenthesis.
1:44:56
no-defun-allowed
if you want to do a readtable thing, #f[code goes here] could work better for syntax i think
1:53:42
didi
I never used a read macro, but luv-slides has one that I might try some day: #L(if (oddp _) (* _ _) 0) -> (lambda (_) (if (oddp _) (* _ _) 0))
2:39:07
didi
Argh. Format's call function directive is not too hot; I've to use colons to call functions from packages, even if it's a symbol interned in the same package I'm in.
2:49:49
aeth
Any list/cons processing should directly or indirectly use destructuring-bind unless there's a built-in to handle it directly imo. Probably slows it down a bit but makes sure it is what you think it is.
2:51:09
aeth
(and if you actually don't care about the tail in a destructuring-bind it's not hard to do an ignored &rest rest)
2:52:59
aeth
In this particular case, most alternatives would probably work on NIL because (car nil) is NIL and (cdr nil) is NIL.
4:35:56
fiddlerwoaroof
elderK, equwal: LoL is a bit problematic because it doesn't restrict its macro definitions to things that are standards-compliant.
4:36:19
fiddlerwoaroof
So, in some cases, you might discover that implementations have implemented things in a way that breaks the examples.
4:37:21
fiddlerwoaroof
But, I learned the useful trick of expanding to a MACROLET in situations where one might otherwise try to write a codewalker from it.