libera/commonlisp - IRC Chatlog
Search
12:35:01
flip214
https://gitlab.common-lisp.net/alexandria/alexandria/-/pipelines/5874 shows that 4 implementations were okay with (EQUAL #C(0.0 0.0) 0.0)
12:36:09
flip214
pjb: http://www.lispworks.com/documentation/HyperSpec/Body/f_eql.htm#eql has the example (eql 3.0 3.0) => true
12:36:45
flip214
http://www.lispworks.com/documentation/HyperSpec/Body/f_equal.htm says if they are numbers that are eql,
12:38:42
pjb
This is precised in the Note: Two complex numbers are considered to be eql if their real parts are eql and their imaginary parts are eql. For example, (eql #C(4 5) #C(4 5)) is true and (eql #C(4 5) #C(4.0 5.0)) is false. Note that while (eql #C(5.0 0.0) 5.0) is false, (eql #C(5 0) 5) is true. In the case of (eql #C(5.0 0.0) 5.0) the two arguments are of different types, and so cannot satisfy eql. In the case of (eql #C(5 0) 5), #C(5 0)
12:45:01
neominimum
beach: ah yes, that was intentional. removing `(atom (caar form))` prints (1 2 3)
12:45:32
beach
neominimum: The form (and root (print (car form))) is better written as (when root (print (car form)))
12:48:07
beach
neominimum: I also don't understand what ROOT is there for. It is only true for the top-level expression.
12:49:34
yitzi
beach: Lots of non-interesting real life distractions. Trying to get back into the groove though. I am still seeing that SICL issue I mentioned about a month ago, but I made some progress on isolating it. I'll bug you when I have something useful and you have time. :)
12:49:45
neominimum
I was stumped trying to print the root of the tree in the same recursive function that returns the first elements of all sub-lists
12:50:01
beach
neominimum: And I think (and form (listp form)) is just (consp form) which has the additional advantage of not using arbitrary lists as Boolean values.
12:52:15
beach
neominimum: Also, it would be better to return a list of the objects you want, rather than printing them. That way, client code can print them, or do something else with them. Right now, they are useless.
12:54:39
neominimum
beach: sure, I was only printing them so that I could tell that the appropriate elements were being isolated.
12:54:50
beach
neominimum: And I think you should be able to have the base case of the recursion be simpler.
12:56:03
beach
So I don't understand why you omitted (1 2 3) because that was not part of your specification.
12:56:54
beach
Is the specification to "return/print the first element of each sublist, provided it is an atom"?
12:57:32
beach
Er, "return/print the first element of each non-empty sublist, provided that element is an atom"
13:03:07
beach
The recursion on the CDR is fundamentally different from the recursion on the CAR it seems. So I would either use different functions for the two, or use LOOP instead of recursion on the CDR.
13:13:17
beach
(defun tt (thing) (if (atom thing) '() (append (if (atom (car thing)) (list (car thing)) '()) (loop for element in thing append (tt thing)))))
13:22:18
neominimum
Oh nice, thanks beach for the example. It's good to see how you approach the solution.
15:05:31
lagash
Would anyone know of a Common Lisp ANSI escape codes parser? Not bindings to say Curses or anything like that.
15:10:02
Josh_2
Well if you know the characters you want you can probably knock something together easily using LASS
15:10:25
phoe
I am curious what's your idea for turning terminal escape codes for something that is meaningfully understandable by browsers - escape codes can include stuff like colors that is trivially CSSable, but also things like query-terminal-size and set-cursor-position
15:14:16
Josh_2
Because you can just use (char-code <char>) you can quickly generate colours for the ascii character codes using LASS
15:30:25
neominimum
beach: You were right about the CAR and CDR recursion representing different objectives, I didn't fully understand what you meant by that at first, but it clicked and I have something I'm happy with now. https://pastebin.com/raw/bxJxX9wp
15:30:43
neominimum
I tried to implement something different to your solution as an exercise. It uses recursion still + a simple switch to indicate whether a sub-list has been found before attempting to get the atom at the head of the list.
15:49:27
beach
neominimum: WHEN should be used only in a context where the value is not needed. If the value is needed, use and IF with an explicit `else' branch.
15:53:18
neominimum
Ah okay, I suppose it makes sense to make the return values explicit. Is that what you intended?
15:54:07
beach
Yes, the message you send to a person reading your code when you use WHEN or UNLESS, is that the body has only side effects, and the value is not used, like in a PROGN when it is not the last form.
15:57:57
beach
neominimum: You might want to join #clschool. This channel is not really for help with simple stuff, though some amount of that is tolerated.
17:30:06
mzan
neominimum: I'm a newbie too. In CL recursive functions are not used as much as in Haskell. It favours explicit loop/iterate.
17:30:46
mzan
The CL standard does not guarantee tail call optimizations, so there can be problems for some compilers, if you recurse on a big list.
17:31:38
beach
More precisely, iteration is preferable on linear structures, because it is more efficient, and with recursion on linear structures, there is a risk to blow the stack.
17:31:42
mzan
I'm using the "iterate" macro, and I like it a lot. https://common-lisp.net/~loliveira/tmp/iterate-manual/iterate.html#Control-Flow
17:32:20
beach
Recursion is fine on tree-like structures when the depth is limited to (say) logarithmic.
17:33:20
beach
mzan: I would not recommend an external library over a standard operator to a newbie. It is fine if that's your choice, but I would be more careful with recommending it to others.
17:35:39
mzan
neominimum: you are using recursion. Use Scheme because it supports tail call recursion directly in the standard :-)
17:46:45
mzan
beach: in any case I disagree. LOOP is a macro, so it must be studied apart. "Iterate" is a very similar macro, but better. "Iterate" is used a lot, so it is not standard, but for sure not esoteric. It is nearly standard. In case he had to read legacy code, if he knows "iterate" macro, he can understood LOOP macro.
17:51:48
_death
some thoughts I had about iterate a while ago https://old.reddit.com/r/adventofcode/comments/e92jm2/2019_day_11_solutions/faht58g/?context=3 ... since then the breaking change was committed btw
17:56:59
mzan
_death: ah ah, funny enough I discovered that if I try to optimize the code with "iterate", SBCL complains because variables like "x1", "x2" in your example can be "nil" and not only "fixnum" or something of similar. But probably there are sane workarounds, and it is also my fault in specifying typing constraints.
17:58:35
_death
according to its source code iterate existed since 1989, and perhaps made into a library in 2003.. so when a breaking change is introduced in 2021 I think it's a good argument for LOOP
17:59:46
mzan
And to be fair, if you "iterate" on an empty data-structure, then the returned "x1" can be nil, and the code must take in account this. So SBCL is right.
18:07:30
_death
probably beach's point had a different rationale, btw.. a CL newbie should learn to read and write CL proper well before getting too comfortable with (reliant on) external libraries purporting to replace or improve upon some CL counterpart
18:08:10
mzan
_death: I read better now. Yes. Probably in a perfect world, one should change the version of "iterate" and other macro, every time there is a breaking change. So one can import something like "iterate_v2", and this will not break code using "iterate_v1".
18:09:11
_death
in a perfect world one would not need to create new versions, since everything would be perfect already ;)
18:09:18
mzan
LOOP for sure is more stable, because it is part of the standard. And then there are also "mapcar" & C. that are more standards and more direct.
18:09:53
mzan
Probably a newbie should first exsercise with mapcar & C. Then study LOOP and/or "iterate".
18:11:57
Alfr
The problem with loop is, imho, that it has non-obvious rules regarding clause placement.
18:12:09
didi
Puzzle: How to print "X A\nX B\nX C\n" from (X A B C) using only format? i.e., without transforming (X A B C) into something more suitable. I think, if at all possible, it might involve ~? and ~*.
18:12:15
edgar-rft
the only reason why there is no edgar-v2 is because I'm already perfect? probably no...
18:14:03
mzan
_death: "probably beach's point had a different rationale, btw.. a CL newbie should learn to read and write CL proper". Yes. If one is serious, it should start from the bases, and then build up.
18:14:26
Alfr
Bike, also many things are considered harmful, and I guess manually writing tagbodies may actually be unhealthy.
18:14:30
mzan
BTW I studied a little of CL basic (but not too much), and then I started playing with macro and other powerful features, for discovering the funny/powerful parts of CL.
18:18:23
Bike
not because dijkstra decreed it, but rather because his reasons make sense. better to use higher level constructs in almost all cases.
18:18:59
ck_
doesn't PCL use it as an example for how awesome a direct translation of one of Knuths algorithms can be done using tagbody, as a first step for refacoring it
18:20:19
_death
to get better context for Dijkstra, imagine (tagbody <your whole program here, using go to jump around>)
18:20:26
Bike
the context of dijkstra's paper was that people were regularly using goto when they could have used better control constructs. nowadays that's not really a problem with tagbody
18:21:16
Bike
people rarely use tagbody, and when they do use it it's for some weird shit that's hard or impossible to express with higher level constructs. like in eclector off the top of my head
18:22:47
Bike
dijkstra was also writing when "structured programming" was new, instead of now where it's so basic people don't remember it had to be invented
18:29:16
yottabyte
I'm not too knowledgeable about namespaces, but when I quickload a library, how do I add it to my namespace so I don't have to call functions from it with the name? like instead of library:function just call function. I guess this can become a problem if the library contains a function that's already defined in your namespace? but yeah.
18:29:52
didi
Oh, well, I can't solve my format puzzle. I'll transform the argument. /me likes format "puzzles"
18:30:37
_death
Bike: aside from tagbody being useful for state machines and such, it may also be useful to expand to in macros..
18:33:20
_death
yottabyte: (defpackage :yottabyte (:use :cl :arrow-macros)) (in-package :yottabyte) (-> "Hello" write-line)
18:35:49
_death
in a real program, consider using (:import-from :arrow-macros :->) instead of :use, to explicitly import the symbols you care about
18:37:11
didi
phoe: Sorry, but what's the name of the library which has literal tabs inside strings again?
20:35:22
pjb
yottabyte: you must read the documentation of the system, to know what packages it defines, and from what package it exports the names of the functions you want to use.
20:36:00
pjb
yottabyte: note: systems are named by lower case strings such as "foo"; while packages are usually named by uppercase string like "FOO".
21:35:53
_death
Josh_2: I actually stopped pulling changes from iterate because some library that used it broke, iirc
0:30:11
neominimum
mzan: I'm a perpetual newbie even though I've been casually using CL for a few years, my style suck-- I mean, my style is unconventional due my solitary practice. I'm trying now to be more conventional, so it's been great to get some specific feedback. Thanks for your suggestions. I wonder what is the reason why TCO needs to be supported by the standard, I mistakenly thought it was an implementation detail. I think I get it though... If the
0:30:11
neominimum
standard doesn't require it then implementations may not implement it. Does that make recursive code non-portable? Although my understanding is the standard doesn't require compilers to be optimising, professional users would not consider using one that lacked that facility. Like wise, I am interested to know if there is anyone that would consider a compiler that lacks support for TCO to be "Not Sufficiently Smart (tm)". I'm genuinely
0:33:45
jasom
first you need to define "what is tail position" (defun foo () (let ((*bar* 3)) (baz)) ; <-- the call to baz here will likely *not* be tail optimized on any CL compiler due to the dynamic binding of *bar*