freenode/#lisp - IRC Chatlog
Search
12:50:16
phoe
I'd translate one of the solutions from https://rosettacode.org/wiki/Stable_marriage_problem since the problem is well-documented there.
12:53:32
phoe
No, I just guess nobody ended up doing it for any reason. Things in the programming world appear only if someone writes them.
12:53:47
phoe
The algorithm seems to be four functions in total. Translating it from any other language would be pretty simple.
12:55:23
phoe
You have both a very good explanation of the problem and the algorithms AND solutions in multiple other languages. Translating this to CL is nothing that I'd call complicated.
12:56:35
nirved
looks too simple to bother, almost same number of lines as the pseudo-code here https://en.wikipedia.org/wiki/Stable_marriage_problem#Algorithm
12:57:02
phoe
wxie: first you translate it from another programming language, and then fix up the code so it's a bit more idiomatic CL.
12:58:02
phoe
I've seen CL being used to write object-oriented code, functional code, imperative code, linear code, declarative code, asynchronous code and a few of other lesser known paradigms. Hard to say that any of these were "unlispy".
12:59:11
phoe
The part of what I'd call "lispiness" is that a person X comes up and say "hey, I just invented this new programming paradigm!" and Common Lisp is all like "come at me bro"
13:00:55
wxie
for example, I come up with (push (cons (car pair) (cadr pair)) where pair is ((w1 . m1) (w2 . m2)). I am thinking if there is other ways to do it.
13:02:11
phoe
so basically, you have a two-element list, and you want to make a cons from that list, and push that cons to some kind of place called pairs.
13:05:00
_death
(defun repair (list) (cons (first list) (second list))) (push (repair couple) pairs)
13:07:36
phoe
wxie: maybe a better question: what is your definition of "lispiness" that you speak of?
13:08:52
_death
wxie: but here's an old snippet https://gist.github.com/death/d88bc1331902da52b7c2d08c4ec093d6
13:08:53
phoe
that's an option, yes - especially if your inner loop will or may evolve into something bigger.
13:10:40
wxie
phoe: I am not so sure about my idea of lispness because I have limited experience anyway.
13:12:21
phoe
And I'm just wondering whether and how much this idea matches actual CL and how it's used.
13:13:38
wxie
Right, for me lispiness means using list as much as possible, using setf or the like as little as possible.
13:13:49
phoe
And it's going to be interesting regarding the "how it's used" part because _death just showed some code that I wouldn't have written because I have a completely different coding style and, for example, I wouldn't have used fset.
13:14:11
phoe
That sounds pretty Scheme-like. They have a focus on functional programming and preference for immutability.
13:14:46
phoe
Common Lisp tends to not favorize functional programming, and it embraces mutability as a standard and expected feature for the language and its users.
13:33:37
wxie
phoe: Yes, it prints. I need spend sometime on it. Just want to know how do you know that you need fset?
13:34:01
phoe
wxie: the package definition on top of this file shadowing-imports-from the FSET package.
13:35:15
wxie
I know. But when you have the problem, you need think over it, and then you know need some packages that are already there.
13:35:59
phoe
Yep. I bet that this problem can be solved without FSET, but the solution is much clearer when using FSET.
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.