libera/commonlisp - IRC Chatlog
Search
8:03:37
beach
I just discovered a bunch of Lisp-related videos on YouTube by Gavin Freeborn. Does Gavin hang out here?
12:52:48
mfiano
jmercouris: You can check out Monaspace for the "shiny-new font tech". I don't usually go running towards the light though...it gets pretty blinding
13:04:55
mfiano
jmercouris: That said, it doesn't look too bad and has a nice idea/gimmick, though my current recommendation for readable code is Iosevka, one of the Slab variants, specifically.
13:07:34
supercode
In https://www.lispworks.com/documentation/HyperSpec/Body/f_nconc.htm what does (nconc nil . lists) == (nconc . lists) mean?
13:10:15
supercode
I guess what I am unable to understand is what does (nconc . lists) mean on the right hand side.
13:11:12
supercode
I am trying to understand the behavior of (let ((a nil) (b (list 10 20 30))) (format t "~a~%" (nconc a b)) (format t "~a~%" a))
13:11:54
supercode
this prints (10 20 30) and NIL. which recursion rules there explains both outputs. that's what I am having trouble with.
13:13:35
supercode
If this invokes this rule: (nconc list-1 list-2) == (progn (rplacd (last list-1) list-2) list-1) then should I not get an error when it tries (rplacd (last nil)) ?
13:14:33
mfiano
the . is basically &rest, and both syntaxes can be used in destructuring-bind's destructuring-lambda-list's to test.
13:15:15
bike
it applies the second rule, (nconc nil . lists) = (nconc . lists). so (nconc nil (list 10 20 30)) = (nconc (list 10 20 30)).
13:15:38
supercode
(let ((a nil) (b (list 10 20 30))) (nconc a b)). will this perform (nconc nil b) == (progn (rplacd (last nil) b) nil)
13:17:17
supercode
bike: just saw your message. I think that is explaining the behavior. let me take a few more minutes to wrap my head around it.
13:18:32
supercode
bike: yes, that is it. so it does (nconc (list 10 20 30)) and returns (list 10 20 30) according to 3rd rule. And a remains unchanged as nil
13:19:01
supercode
I was expecting (let ((a nil) (b (list 10 20 30))) (nconc a b)) to set a to (10 20 30).
13:19:20
mfiano
Also note that nconc is pretty special, and may be the only function that guarantees destructive modifications. Usually it is up to the implementation to decide.
13:19:32
supercode
because (let ((a (list 1 2 3)) (b (list 10 20 30))) (nconc a b)) sets a to (1 2 3 10 20 30).
13:19:56
supercode
does it not bother anyone that nconc does not set a to (10 20 30) in the former case when a is nil?
13:20:45
supercode
would it have been trouble to implement nconc in such a way that (let ((a nil) (b (list 10 20 30))) (nconc a b)) would set a to (10 20 30)? why or why not?
13:21:35
supercode
I guess one problem is that the CDR of nil is also nil, so there is no place to set the 2nd list to.
13:22:17
bike
nconc is a function. it doesn't know anything about variable bindings. it just gets the lists as inputs.
13:22:57
supercode
so 'a' really needs to be a cons cell if I want to make 'a' grow with nconc calls.
13:28:02
mfiano
I would be curious to know if there is any code out there using ,. that is 'acceptable code'.
13:34:09
mfiano
ie; when is it useful to do such a thing at read time? it has only bitten me, by using comma in backquoted expressions that were variables beginning with a #\. in their name/
13:48:11
bike
it's never acceptable, because anyone looking at it will go "wait, what the heck is this syntax" and be lost
14:12:41
dnhester26
I'm declaring a variable in a let and getting a defined but never used warning from the compiler, however, **I am** declaring it ignorable beforehand, so why am I getting the warning? am I doing the declaration in the wrong place? Here's the code https://plaster.tymoon.eu/view/4082#4082
14:13:12
dnhester26
the clhs doesn't have any examples... https://www.lispworks.com/documentation/HyperSpec/Body/d_ignore.htm
14:13:36
dnhester26
can anyone please add examples and/or explanations?? https://lisp-docs.github.io/cl-language-reference/chap-3/d-i-dictionary/ignore_ignorable_declaration
14:18:46
dnhester26
in the macro: defjson-route-with-preflight-params I am definitely using json-params-name
14:19:21
dnhester26
only in the with-json-params macro it's possibly not being used, but it's declared ignorable beforehand. Or should I declare it ignorable in that with-json-params macro??
14:21:20
beach
If you have (let ((x 234)) (let ((x 345)) ...)) then the second X is not a use of the first one.
14:21:21
dnhester26
ah ok, that's what am not understanding between bound and set. Bound I thought was about slots in CLOS, set I thought was about any variable. How does that affect what am doing? Should I declare it ignorable in a different way or place in the code?
14:23:03
dnhester26
So in the let I am declaring a variable that is never used and that's why I get warning, but I declared it ignorable in the macro
14:26:01
beach
You are basically declaring as IGNORABLE a variable that is not in scope in the resulting expansion.
14:27:24
beach
Your macro defjson-... expands to (defpost... (declare (ignorable <some-name>)) But that variable no longer exists.
14:30:32
beach
Consider this simplified macro: (defmacro bla (x) `(let ((y 234)) (declare (ignorable x)) y))
14:31:26
beach
Consider this simplified macro: (defmacro bla (x) `(let ((y 234)) (declare (ignorable x)) y))
14:31:57
beach
,((defmacro bla (x) `(let ((y 234)) (declare (ignorable x)) y))) ,(macroexpand-1 '(bla 222))
14:32:03
dnhester26
in this simplified macro you are making the declaration inside the let, that's the point? because that's the context where the variable is defined?
14:32:17
beach
,(defmacro bla (x) `(let ((y 234)) (declare (ignorable x)) y)) ,(macroexpand-1 '(bla 222))
14:34:05
beach
,(defmacro bla (x) (declare (ignorable x)) `(let ((y 234)) y)) ,(macroexpand-1 '(bla 222))
14:35:58
beach
If I were to try to use the expansion of the first macro: ,(LET ((Y 234)) (DECLARE (IGNORABLE X)) Y)
14:38:59
beach
You can safely do (defmacro defjson... (...) (declare (ignore json-params-name)) `(defpost-rout...
14:39:48
dnhester26
ah outside the backquote, I was doing backquote and comma, but the point is to do it outside?
14:43:12
dnhester26
i am not really understanding. Is this basically what I'm doing (copy paste from your comment)? ,(LET ((Y 234)) (DECLARE (IGNORABLE X)) Y)
14:44:57
beach
But <some-name is not in scope, so you are declaring a variable ignorable that is not in scope.
14:45:37
bike
if this is the code in paste 4082, it looks like the ignorable doesn't even make it into the expansion
14:47:38
bike
defjson-route-with-preflight-params, right? the code is (defmacro ... (declare (ignorable ,json-params-name)) `(defpost-route-with-preflight ...))
14:47:39
beach
But in the expansion, there will be an IGNORABLE declaration of a variable that does not exist.
14:52:22
dnhester26
beach: sorry that was a typo later that I fixed in the editor and instead of just copy paste i tried editing the pastebin with the same changes, my bad
14:52:39
dnhester26
bike: can you please take a look at the new one? https://plaster.tymoon.eu/view/4083#4083
14:53:38
bike
if you want to declare a variable ignorable, you put the declaration where the variable is bound
14:54:18
bike
here, you're declaring the _macro parameter_ json-params-name ignorable. this parameter is a symbol, a variable _name_. and it's pointless, since you always use it, on line 17
14:54:35
bike
what you actually want to declare ignorable is the variable bound by with-json-params, right? or do i have that wrong?
14:54:36
dnhester26
in this new pastebin, I think the correct place is really line 15, not 13 as it is now, because that marcro is a progn with two lambda definitions and only the second one which is the body uses json-params-name
14:55:52
dnhester26
I get the compiler warning when calling defjson-route-with-preflight-params with some my-var saying it's unused
14:56:21
bike
and that'll be on line 18, in with-json-params. (with-json-params (,json-params-name ,@route-params) (declare (ignorable ,json-params-name)) ,@body)
14:57:04
bike
now say you have (json-route-with-preflight-params whatever myvar ...). The expansion will have (with-json-params (myvar ...) (declare (ignorable myvar)) ...)
14:57:28
bike
the with-json-params form then expands into (let* ((myvar ...) ...) (declare (ignorable myvar)) ...)
14:58:08
dnhester26
bike: what's the difference between line 18 and 3? or for that case between lines 7 and 8?
14:59:24
bike
line 3 would be inappropriate, because then you are, again, declaring the MACRO PARAMETER json-params ignorable
14:59:47
dnhester26
bike: finally, just did it between 7 and 8 and got rid of the warning. So the whole problem was that it had to be **inside** the let scope. correct? that's what I was trying to understand
15:00:45
dnhester26
got it, ok, I think this is prime material for the technical reference, at least examples, or maybe I'm just a bit tired today
15:01:10
beach
dnhester26: Again, in (LET ((X 234))... the variable X is not a reference, so declaring x ignorable outside the LET does not refer to that X.
15:02:17
dnhester26
the declaration is always after it's bound? or as long as it is in the same context it's OK? meaning could I do ,(let (declare (ignorable x))((x 24)))?
15:03:42
Colleen
Clhs: special operator let, let* https://www.lispworks.com/documentation/HyperSpec/Body/s_let_l.htm
15:05:01
dnhester26
thank you so much! I feel like my eyes have been opened a bit to notice the syntax better and understand this ignorable business
15:41:51
dnhester26
can anyone please proofread the examples for the ignore declaration I just added? https://lisp-docs.github.io/cl-language-reference/chap-3/d-i-dictionary/ignore_ignorable_declaration#expanded-reference-ignore-ignorable
15:42:11
dnhester26
are there any other examples that may be useful to know? or any other explanation that is good to write?
15:47:48
beach
dnhester26: The only mention of "statement" in the standard is in the equivalent of TAGBODY.
15:48:07
dnhester26
beach: what should I replace it with? the declaration and remove `declare`? saying the `declare` declaration sounds bad...
15:56:16
Alfr
dnhester26, not sure if above still complies with "declaration must be within the scope where the binding happens".
16:02:13
dnhester26
Alfr: thanks for the proofreading. Did you mean that since the defvar is outside of the locally form?
16:03:14
dnhester26
beach: maybe Alfr means that the way I wrote it implies there should be a warning, and the language has to be changed.
16:03:21
dnhester26
this is the sentence I wrote: "A key point to declaring variable bindings to be ignored is that the declaration must be *within* the scope where the binding happens."
16:04:42
beach
It is within the scope, but it is not a bound declaration, and it's iffy anyway to have special variable declared IGNORE.
16:05:03
dnhester26
beach: Oh, and I think I now understood what you said: since there is no warning anyway, there is no need for the declaration either
16:05:59
Alfr
dnhester26, in a sense it is, should be in the global environment. But, yeah, textually it isn't,
16:06:54
beach
In a LOCALLY, declarations are "free", but they are still in scope if the are in scope outside the LOCALLY.
16:07:44
beach
So in (locally (declare ignore *x*) ...) the declaration is free, but since the variable is bound in the global environment, the declaration is in scope.
16:08:42
beach
It also does not make much sense to me to have free IGNORE or IGNORABLE declarations.
16:14:05
beach
I mean, if you have (let ((x 234) (y 234)) (locally (declare (ignore x)) y)), then X is still unused in the (locally ...) form. And in fact, SBCL gives a style warning for a free IGNORE declaration.
16:15:12
beach
So I maintain that it doesn't make much sense to have free IGNORE or IGNORABLE declarations.
16:18:12
Alfr
beach, that's when you want to check that you used everything you introduced. But does make sense when you want a warning for using *x* with that scope.
16:21:27
beach
Well, here is how I see it. Special variables have dynamic scope, but declarations have lexical scope. So if you do (let ((*x* 234)) (declare (ignore *x*)) (foo)), then you won't know whether FOO uses *x*.
16:25:16
beach
So I think SBCL is doing the right thing here. Signal a style warning for free IGNORE and IGNORABLE declarations, and for IGNORE and IGNORABLE declarations of special variables.
16:26:11
Alfr
beach, fine ... in (let ((foo 21)) (list (locally (declare (ignore foo)) foo) (* 2 foo))) I want a warning for the foo producing the first list element.
16:26:59
Alfr
... and I see that sbcl complains that the ignore is about a variable from "outer scope". xD
16:28:39
Alfr
beach, and I don't know an answer to whether macros expanding to such should or should not trigger such a warning.