freenode/#lisp - IRC Chatlog
Search
18:52:21
aeth
My quick review of what I read of Common Lisp Recipes: The author seems to go with the community consensus on everything where the consensus exists except preferring his own cl-fad over uiop for path/file-related things, but you can't really fault someone for prefering their own library.
18:53:03
aeth
The weakest part is probably if you're trying to make something graphical, but that's probably the weakest part of the CL ecosystem anyway, and that could definitely be enough material for its own book(s)... ideally after such libraries are more mature.
20:00:04
mfiano
There is also at least 1 thing that cl-fad does much better than UIOP, or at least until implementations such as SBCL update their ASDF
20:10:13
rpg
mfiano: That may be, but there are lots of things that CL-FAD does worse than current UIOP. In particular, the treatment of directories versus files in pathnames, in CL-FAD is very weak.
20:11:02
rpg
That's because Fare did a ton of hard work to figure out how much information he could squeeze out of the various implementations.
20:11:17
mfiano
I completely agree, but Fare fixed a major performance issue I reported a long time ago that has not propagated to all of the common implementations yet.
20:15:04
mfiano
Yup, I've been waiting a while for SBCL to update ASDF, which I hear is happening soon. With UIOP, listing files in a directory with thousands of files takes minutes, compared to near instantaneously with cl-fad.
20:37:07
osune
hoi, for StumpWM I want to write a 'one-shot' hook. stumpwm:add/remove hook both take a symbol. To realize the 'one-shot' ability I need to write a closure which will take a function, calls the function and calls stumpwm:remove-hook on its own symbol. I wrote following function for this: https://pastebin.com/QGaWVgxZ ; It does what i expect: returning a new symbol which binds the closure. But the stumpwm:remove-hook call doesn't work
20:42:27
osune
Bike: after triggering the hook, which executes the supplied function correctly, the stumpwm:remove-hook call doesn't seem to affect the supplied hook list (a list with function binding symbols). The hook list still contains the gensym binding the closure.
20:45:38
osune
stumpwm:remove-hook is a macro expanding to (setf hook (remove fn hook)) https://github.com/stumpwm/stumpwm/blob/aa8f9560461b5e0010db417a1224c911ba705563/primitives.lisp#L691 ;
20:47:29
osune
currently my guess is that it has to do with the (gensym) call; but I'm not sure and I don't know where I could find a discussion about the differences of interned and uninterned symbols
20:51:50
Bike
it's basic. (defvar *foo* 9) (defun test (x) (setf x 3)) (test *foo*), then *foo* is still 9.
20:54:06
osune
but that means I can not evaluate *foo*; which means I need a macro for that. Is this correct?
20:55:27
osune
thanks. just to be sure, is there anything which would achieve the same without using a macro here?
21:41:29
Walex
drmeister: in most LISPs the two things are confused, but they are actually quite different, like in most other languages. Because of 'nconc' and 'eq' vs. 'equal'.
21:50:46
Xach
No. I'd be a bit wary of vague advice from someone who never participates and who spells it "LISP".
21:56:10
Walex
Bike: technically you did not fuck up, for unintuitive meanings of "mutating" and "binding".
21:58:59
Bike
a binding is a pair of a name and a value, bound together. mutating means changing it. seems reasonable to me.
21:59:44
koenig
This is a genuine question, but the distinction has to do with the "lexical scope", doesn't it?
22:00:11
Ober
as a general view among cl folks, are there any other languages that qualify for the lisp label of the original intent. e.g. elisp
22:00:15
jasom
koenig: you can bind dynamic variables in lisp, and binding and assignment were different even before lisp had lexical bindings.
22:00:38
Walex
koenig: the difference has to do with the difference between the environment made of atoms and the environment made of references.
22:00:43
TMA
drmeister: to bind === to associate a name with a place capable of holding value ; assignment is changing the value but not the place
22:00:59
drmeister
So I tossed out the question - what is the difference between "Binding" and "Assignment".
22:01:18
aeth
Someone should make a pc-cl-ppcre, or perl compatible common lisp portable perl compatible regular expressions... A reader macro on top of cl-ppcre for Perl regex syntax. Well, I guess more than one because there's e.g. /.../ and s/.../ etc.
22:02:18
jasom
drmeister: to be common-lisp specific, let &c. and function entry establishes bindings and setf, setq &c. performs assignment
22:04:19
Walex
jasom: that is correct but not terribly helpful because "LISP" does assignment "conceptually" in a way that is very close to binding.
22:04:20
jasom
TMA: I don't like any definition that involves the phrase "changing the value" since that is ambiguous
22:04:59
Bike
it's a quote from olin shivers, a CS bigwig who does tons of scheme. if you have something to say that isn't a rejection please hurry along to that part.
22:05:16
aeth
drmeister: Afaik it has to do with lexical environments (when working with lexical variables), i.e. binding establishes something in an environment and setting sets the first value it sees as it climbs up the environments
22:05:17
Walex
drmeister: the quote you provided actually uses "parameter binding" to mean "one time assignment".
22:07:02
Walex
jasom: actually 'rplacd' does perform assignment, otherwise it is incomprehensible. If it did not there would not be any difference between 'eq' and 'equal'
22:07:53
jasom
drmeister: also note that both terms have different meanings in different contexts, just like all scientific terms
22:08:16
Walex
jasom: it is precisely the difference between 'set' and 'rplacd' that is confusing in LISP-like languages.
22:08:49
Walex
jasom: without assignment there cannot be a difference between 'eq' and 'equal'. Indeed the very notion of 'eq' ceases to have meaning.
22:10:41
jasom
Without mutation (which is a distinct concept from assignment) then it would be valid to make all equal things eq
22:11:41
Walex
jasom: 'cons' in most LISP dialects implies assignment, because 'rplacd' is possible.
22:11:58
TMA
jsnell: a binding does not require a place yet it does require something to store it which might as well be isomorphic to a place
22:12:26
Walex
jasom: in a pure functional language without assignment. '(eq (cons 1 2) (cons 1 2))' is always 't'.
22:13:00
jasom
Walex: it *may* be true, it is certainly to create a pure functional languge without assignment for which it is not
22:15:22
jasom
Walex: except for when object identity could be used to improve performance because the simple implementation isn't helping you out
22:15:55
jsnell
TMA: nonsense. (defun foo() (let ((a 1)) (1+ a))) ;; I am definitely establishing a binding A => 1 there. but it is totally reasonable for an implementation to not have "1" stored anywhere during the actual execution
22:15:59
Walex
jasom: if there is no 'rplacd' having the 'eq' operator that can return a value different from 't' has no sense, because there is no way to act on that.
22:16:34
Walex
jsnell: that '(let ((a 1))' is really an assignment in the general sense of the word.
22:16:53
jasom
Walex: there is a cost to comparing structure, and you have to compare structure if you don't make the work to ensure that storage is identical for objects with identical structure
22:17:16
Walex
jasom: the only purpose of 'eq' is for asking: will 'rplacd' change both or just one?
22:17:54
jasom
Walex: or "This is a really large object to compare and I want to save cpu cycles because I know in this limited case that object identity is what I care about"
22:19:18
Walex
jasom: but object identity does not matter if there is no 'rplacd'. If the *implementation* has object identity, then the first thing in 'equal' is to compare object identity, it is an implementation dependent optimization.
22:19:47
jasom
Walex: yup, and I make implementation dependent optimizations all the time because I live in a place known as "the real world"
22:20:14
aeth
Instead of s/certainly/certainly possible/ people should say this: (regex-replace "certainly" * "certainly possible")
22:20:16
Walex
jasom: if there is no way to modify objects, is is certain that if two list heads are identically the same then the lists are the same list.
22:20:55
jasom
even in an immutable language it is not certain that two non-identical list heads are the same list
22:21:00
jasom
even in an immutable language it is not certain that two non-identical list heads are not the same list
22:21:37
TMA
jsnell: in what sense does the binding exists at runtime then? isn't the whole binding elided and nonexistent at runtime?
22:22:04
Walex
jasom: the issue here is that in a purely functional language having 'eq' only tells the user something about the implementation, not the computation possible in the language.
22:23:28
aeth
Is this what people are arguing about? This is a purely functional CL subset, and I get NIL. It's possible that I'd still get NIL in a REPL specifically designed for only that purely functional subset. (eq "Hello" "Hello")
22:24:17
Walex
jasom: it is not faster. It has the exact same speed as 'equal', if 'equal' is implemented reasonably.
22:24:23
jasom
aeth: Walex is saying that there is no need for eq in a purely functional CL subset because there is no case in which eq gives you more information than equal.
22:26:13
jasom
Walex: but what about (equal '(1 2 3 4 ... X) '(1 2 3 4 ... Y)) that is much slower than eq
22:28:15
Walex
aeth: suppose that '(id ...)' returned a unique integer associated with a value, then 'eq' would be pretty much '(equal (id ...) (id ...))'. Then the question becomes what's the point of 'id'... In a purely functional language there is no point to it.
22:29:29
Walex
jasom: sure, but functional languages are designed to abstract from implementation details, and let the comiler sort out them.
22:29:30
jasom
implementation details can make a difference even in asymptotic complexity of algorithms, so even to a theorist they should matter
22:30:30
Walex
jasom: you seem to have a reasonable apporach, so if you want I can explain what I think you (and 95% of compsci professors...) miss about this discussion.
22:31:18
jasom
Walex: Pretty much all high-level languages abstract implementation details. Even C. But in C I have rewritten pointer-loops to be array-indexed loops (and vice-versa) because compilers generate much worse code for one than the other.
22:32:37
jasom
Walex: even worse, some compilers generate much better loop code if you switch from incrementing to decrementing your loop variable!
22:32:39
Walex
jasom: as to functional abstraction, functional languages are designed to "abstract away" precisely the complexities of assignment.
22:32:51
sjl
aeth: just implement a reader macro for #s/certainly/certainly possible/ :) https://letoverlambda.com/index.cl/guest/chap4.html
22:34:09
jasom
though I sense that you use assignment ant mutation interchangably, whereas the common use I've seen they are distinct, but related, terms
22:35:32
Walex
jasom: the OP was asking about concepts, and "LISP" like languages are a bad context because of that, because for legacy reasonsĀ 'set'/'let' and 'rplacd' are *explained* in different terms even if tehy are actually the same.
22:37:36
jasom
Walex: seeing that this channel is specifically about common lisp, the most obvious answer is to assume the lisp definitions of those terms. This discussion started long before he mentioned the Shivers paper, so I had no other context to go on.
22:39:20
Walex
jasom: and in Common Lisp there is that unfortunate confusion, that's why I mentioned that as to 'Bike's answer
22:40:29
jasom
I would say that binding establishes a new mapping between a name and a value, while assignment modifies an existing mapping between a name and a value.
22:40:39
Walex
just found in a web search a paper addressing some of the issues: https://www.dreamsongs.com/Separation.html
22:41:07
aeth
Walex: LISP fell out of popularity by the early 1980s and almost completely vanished by 1990, at least in my amateur examining of historical documents. Afaik, it's now almost exclusively used by certain niche Lisps that happened to keep the old style in their name, e.g. AutoLISP, ISLISP, and newLISP (actually, perhaps just those three)
22:41:54
Walex
jasom: that has a few holes and from my point of view the big difference is the kind of value involved.
22:43:35
aeth
Yes, but these days "LISP" is generally only used to indicate the general Lisp family by (1) users of AutoLISP, ISLISP and newLISP (all quite niche) and (2) people who never use a Lisp and probably only read about it in a textbook written in 1980
22:44:47
aeth
In fact, scratch ISLISP from that list. The ISLISP website calls it the Lisp family. http://www.islisp.info/
22:45:50
jasom
Walex: though binding is tied very closely to scopes, since the same symbol in two different scopes is logically not the same variable
22:46:57
jasom
If a variable (which I'll use as "name + scope" pair) ever maps to two different values, then there has been assignment.
22:47:49
Walex
jasom: the problem with that, which getting close to my favourite understanding, is that "scope" is not a runtime entity.
22:48:51
Walex
jasom: so the same atom can be bound to two different variables in different scopes, and the same variable can be assigned different values at different times.
22:49:00
jasom
Walex: scope is an abstract concept. One could redefine an impure language as a pure one by merely saying each assignment creates a new scope (and the inverse transformation happens when pure languages are compiled to run on real hardware).
22:49:43
Walex
jasom: so the same atom can be bound to two different variables in different scopes, and the same variable can be assigned different values at different times. Can I get you to agree to that? :-)
22:50:16
aeth
s/newLISP mixes conventions./newLISP mostly uses the LISP convention to refer to the Lisp language family./
22:50:58
jasom
Walex: is a cons cell still the same value after a rplacd? This will become very important soon.
22:52:00
jasom
lisp has so many equalities because of different interpretations of the phrase "same value"
22:52:26
Walex
jasom: I am asking questions :-). When one uses 'rplacd' does the 'CDR' "variable" of a CONS cell get assigned a new value?
22:53:07
jasom
I would say it's not a variable because variables are not anonymous and cons cells can be anonymous
22:54:41
jasom
And I could tell you would think it a variable because you seemed to be using mutation and assignment interchangably, which is true if all "places" are "variables"
22:54:57
Walex
jasom: but we tentatively agreed that "the same atom can be bound to two different variables in different scopes", and idf that is true, if you remove the atom bond to it, what is the name of those variables?
22:56:27
jasom
I claimed a variable was a (name, scope) pair, so a variable without a name is ill-defined in my ontology.
22:57:30
jasom
There is a natural isomorphism between assignment and mutation not by any coincidence, but becaus assignment is a very specific type of mutation.
22:58:14
Walex
jasom: I rephrased that as "the same atom can be bound to two different variables in different scopes" to make clear that difference between the two bindings is not the scope, it is the "variable" bit....
22:59:49
Walex
IIRC (and not sure here about Common Lisp) you can have two atoms name the same "variable" in the same scope.
23:07:34
Walex
Zhivago: "locatives" were r-values to r-values, that is the equivalent of C's "*" types
23:09:50
Walex
Zhivago: the point is that binding is in most languages (in LISP there is a twist) an immutable association between a symbol and a value, whether it be an l-value or an r-value; assignment creates a mutable
23:10:27
Walex
Zhivago: ooops, sorrym, I means in the previous lines "C-concept "l-value"" and "were l-values to l-values"
23:10:55
Walex
Zhivago: the point is that binding is in most languages (in LISP there is a twist) an immutable association between a symbol and a value, whether it be an l-value or an r-value; assignment creates a mutable association between an l-value and an r-value.
23:11:57
Walex
Zhivago: the point is that an l-value ("anonymous variable") both *is* a value (and that cannot bchange) and *has* a value (and that can change).
23:13:12
Walex
Zhivago: in C an l-value *is* a value in its own right, and can have a value *or not*.
23:13:27
dwts
hey guys, since most of you suggest using emacs with slime to evaluate code as you go, I was asking myself if there's an easy way to pipe output of a lisp program to an external program
23:14:27
Xach
dwts: i sometimes turn lisp programs into command-line programs to do that, but then that means there is no emacs or slime involved.
23:14:51
Xach
dwts: another option is to have your lisp program output to a file, and then pipe the file into something else
23:15:09
Walex
Zhivago: well, you seem very confused as not only C works, but also as how to "[Cvariables work even in "LISP" and Common Lisp.
23:15:16
Xach
dwts: you can also use run-program to pipe to another program. i think. i haven't done that much, or maybe at all.
23:16:37
dwts
Xach: I was trying to do the cli program approach but a few active users at the point I asked the question adviced me against doing that until my program is "ready". My program isn't "ready" but it's close to a point that I want to start see if I can use it with other programs that's why I asked if there's a way to combine the two
23:17:10
Xach
dwts: out of curiosity, what is the thing your lisp program generates that is consumed by another program?
23:17:26
Walex
Well, if you have ever used 'rplacd' Zhivago should understand how 'l-value's work (the Common Lisp equivalent that is).
23:18:43
dwts
Xach: I'm using lisp to search through an API that returns a json ouput. And I would like to see my output pretty printed. I was thinking to pass that to jq
23:19:03
Xach
dwts: oh. well, there is a lisp json pretty-printer, too. but i understand the general idea.
23:19:42
dwts
Xach: I'm sure there is, but until I write the code that does that in lisp, I need to see the ouptut pretty-printed
23:23:08
dwts
jasom: when I try to select the output, output disappears after trying to change buffer so I can't select anything. I'm getting the output through C-x C-e, if that helps.
23:25:17
dwts
maybe writing that to a file is easier as Xach suggested. But I was curious if there was a more elegant way when you go the non-cli route
23:29:36
dwts
Xach: I would prefer the compiling approach as well. But I followed the C-x C-e route as suggested here
0:15:44
Walex
Zhivago: in the discussion above you have referred to "cell". In Common Lisp that is a "slot", which maps pretty closely to the C notion of 'l-value' (and indeed it is as a rule implemented as an 'l-value'). The "value" slot of a symbol, or the "CAR" and "CDR" slots of "CONS" values, are all "slots", that is have the same semantics as l-values, or "anonymous variables". Because of legacy reasons the relevant sections of CLHS are written with poor terminology an
0:55:38
aeth
(it's a design flaw of IRC to (1) cut off at an arbitrary point that depends on your nick and the IRC server and (2) not provide any way of knowing that it cut off)
0:58:44
aeth
You're correct that the terminology in CLHS is odd at points. That's not particularly specific to CL, though. Every language has its own, incompatible terminology quirks and it's easy to say the wrong thing if you talk about it to a different language community. Even Scheme uses different words for almost identical concepts as CL (and Scheme is as close as you're going to CL in mainstream languages except elisp)
1:01:16
Zhivago
I don't know -- he was going on in some confused fashion about variable bindings earlier.