libera/#commonlisp - IRC Chatlog
Search
20:32:13
lisp123
Is there some sort of override on the last cdr being nil not being recognised as an element? Is this why some functions require proper lists as inputs?
20:35:23
aeth
list iteration for the most part is effectively doing MAPCAR with emphasis on CAR (well, in that case, MEMBER could be implemented with MAPLIST because it needs to return the sublist, but can't be implemented with MAPCAR, but it still mostly cares about the CAR)
20:40:18
aeth
A possible implementation of MEMBER (excluding the keyword arguments) could be something like: (defun member* (item list) (maplist (lambda (sublist) (if (eql (car sublist) item) (return-from member* sublist) nil)) list) nil)
20:43:42
aeth
'(1 2 3 NIL) would return (NIL) in our hypothetical, while '(1 2 3 . NIL) i.e. '(1 2 3) would still just be NIL
20:44:36
lisp123
and there is some check that the cdr is nil and then the function stops there (hence the requirement for list to a proper list)
20:44:48
aeth
it will error at some point: if it turns out that the last "sublist" is '(1 . 2) instead of '(1 . NIL)
20:45:21
aeth
MEMBER and the things that you could trivially implement MEMBER with (such as MAPLIST) check for a proper list at the very end, because it's more efficient that way.
20:45:48
lisp123
so basically because (car nil) is defined, it works --> but if the last item was 2 (as in your example), the error comes from (car 2)?
20:45:50
aeth
i.e. it's more efficient to assume that it's the correct input, and fail on the rare case when it's not, rather than slowing down the common path for the fast error path
20:46:23
aeth
lisp123: the error comes because '(1 . 2) isn't a proper list, so the sublist assumption is violated. You just won't find out until the final iteration
20:47:12
lisp123
aeth: (sorry to be obtuse), but that specific error occurs in the final iteration since car will no longer work on "2" as in your example?
20:47:55
_death
as an exercise, you can try to implement the basic MEMBER operation without using any of the existing mapping functions
20:48:28
aeth
lisp123: it doesn't work because list-iteration (or especially sequence-iteration that works on lists) tends to iterate until the CDR is NIL, so when that's not the case, the assumption has been violated. You usually have to work with dotted lists yourself.
20:48:51
aeth
worst case is actually infinite loop, never reaching the NIL. The built-ins are just friendly enough to fail with an error
20:49:09
aeth
although I guess you'd (cdr '(1 . 2)) treat 2 as a sublist, then try to take the car/cdr of it and error
20:49:48
lisp123
_death: I can now see the value of doing this, when I get time I'll try and re-implement the CL functions from scratch
20:50:32
aeth
right, what you'd want to do as an exercise (or for real, if you really need this behavior) is rewrite sequence/proper-list built-in functions on top of LOOP/DO/etc. to handle dotted lists
20:50:56
aeth
you lose elegance because now you're not sure that the CDR is a CONS-or-NIL, unlike a proper list.
20:51:41
lisp123
aeth: unfortunatley, there's a million and one ways to handle lists --> Indeed, it can get confusing at times. But at least today I finally learned WHY i needed to use proper lists (vs. just the standard says so)
20:51:49
aeth
oh, and you could also do tail recursion locally inside of LABELS (and arguably this is the most elegant way), it just won't be guaranteed to work, unlike in Scheme
20:52:10
_death
lisp123: actually it's very important that you do this and similar exercises if you plan on using Lisp, because they require you to learn and understand fundamental concepts
20:52:52
aeth
and sometimes abstractions do break down and you're just stuck working with raw sublists/CONSes inside of LOOP (or similar)
20:53:41
aeth
you might also want to write your own cons-like thing, in which case you don't get access to any of the built-ins, but the API is well-known (so, foo-car, foo-cdr, foo-cons, etc.)
20:54:32
lisp123
_death: so much to learn, so little time ;) I've decided to go down the path of build first, fix later - it optimises the process and IMO one learns more from making mistakes and fixing them. Otherwise I would be stuck with too many books and concepts to read, and then forget it all anyway
20:55:14
_death
lisp123: this is not a good approach when it comes to concepts fundamental to Lisp, such as conses and atoms
20:57:53
_death
lisp123: the book ANSI Common Lisp is not long and contains good exercises.. the two first chapters are available on Graham's site.. there are other basic sets of exercises on the internet, such as "ninty nine Lisp problems" or "Lisp koans", though it's been a long time since I checked them out and I'm not sure about their quality
20:57:53
lisp123
_death: you are probably right :) I'll try and do it (re-do all the basic functions to understand how they exactly work) sooner rather than later
21:04:06
lisp123
_death: thanks, I read that book. And I've been reading / re-reading CLTL2e a lot (have a hard copy on my desk :D). But this has been a very good discussion (thanks aeth in particular), since even the CLHS isn't 100% precise on the implementation details for MEMBER, a lot of it must be from other parts (quoting the CLHS: " each search list for item or for a top-level element that satisfies the test. The argument to the predicate function is
21:05:46
_death
lisp123: if you read ANSI Common Lisp but didn't do the exercises, my advice is to go back and do them
21:08:05
_death
(actually, the traversal rules link is not helpful.. but if you click on the "element" link to the glossary you can see what is meant)
5:11:39
beach
There are rumors that recent versions of the software produced by the Muse Group is spyware. Perhaps this is a good time, then, to consider a Common Lisp implementation of an editor for music scores. It is insane anyway to write such a program in C++. We can do much better.
5:18:03
beach
So the idea would be to create a CLIM/McCLIM-based interactive program that uses the new standard for music fonts, and the new (apparently excellent and free) implementation of that standard.
5:19:26
cjb
since it is TeX underneath, you can probably do something like this: https://castel.dev/post/lecture-notes-1/
5:20:04
ldb
I know someone who's writing a PDF lib from scratch, she says the ISO spec for the compression formats used in PDF along costs $9000
5:24:11
edgar-rft
right, lilypond uses GNU Guile as a preprocessor for TeX, plus some C++ hacking to extend Guile
5:26:55
edgar-rft
for example the current lilypond versions are still stuck with Guile 1.8 because all other Guile version afterwards make lilypond unbearably slow
5:29:15
beach
The rules of music engraving are completely different from those of typesetting text, so I don't see what TeX can contribute.
5:31:15
edgar-rft
The lilypond developers mainly work in the music or typesetting/printing business, I think they choosed TeX because they didn't want to write their own typesetting program and choosed Guile because it was said to become the "standard GNU scriptiung language". I can ask on the mailing list if somebody needs details.
5:32:55
beach
I think Common Lisp would be the ideal implementation language for an interactive score editor/engraving program.
5:33:50
beach
I did Gsharp some time ago, but made some wrong design decisions. Also, at the time, McCLIM was not as good as it is now. And the font technology was not available. Now is a good time to do something better.
5:34:35
beach
edgar-rft: I am not entirely ignorant. I have read up on all the rules of music engraving, and I have experience with Gsharp.
5:35:43
ldb
i'm getting interested, is there any reading I can do to start learning music engraving?
5:37:39
edgar-rft
ldb: there are papers from Werner Lemberg (main typesetter and music font designer of lilypond), gimme some seconds to look...
5:37:50
susam
Learnt about Gsharp now. Hadn't heard about it before. I have used LilyPond about 10 years ago and the PDFs it rendered looked very good. The Gsharp screenshots at https://common-lisp.net/project/gsharp/ don't look as good. I think I see a lot of aliasing.
5:37:52
beach
ldb: The trick is to encode those rules in software, while still allowing the user to tweak the layout when necessary.
5:40:00
edgar-rft
ldb: this is a description of the typesetting ideas behind lilypond -> https://lilypond.org/doc/v2.22/Documentation/essay/index.html
5:40:17
moon-child
cjb: side-by-side preview is not really 'interactive', particularly for tex which takes quite a while to render
5:40:22
beach
susam: Like I said, McCLIM is much better now. We also have Common Lisp support for OpenType fonts, and we have a free OpenType music font that is apparently excellent.
5:42:34
susam
beach: Yes. That makes sense. I agree, a very good music score system can be made with CL.
5:43:03
beach
This video is about the design of the new font: https://www.youtube.com/watch?v=XGo4PJd1lng
5:43:42
ldb
Btw, I just mentioned a lot of efforts need to be made to produce PDF. Any ideas on how to work on that with CL
7:27:41
beach
We already have 25 or so issues for WSCL: https://github.com/s-expressionists/wscl/tree/main/wscl-issues/proposed and if anybody feels like adding more, please do so.
8:08:57
pve
Hi, are there any examples of libraries or applications where, in order to compile the code, one needs to load the source code first (i.e. the lisp files) before compiling anything?
8:18:41
flip214
pve: if reader macros are in use, they're needed to read other source files. CL-INTERPOL (used eg. for CL-PPCRE), or NAMED-READTABLES, or similar stuff comes to my mind.
8:18:58
pjb
Well, some old application could have needed that. Basically, in Patchwork, which was developped in part in the image, had files with a lot of circular dependencies. Loading everything before compiling would have helped compiling without error or warning.
8:19:24
pjb
But this is not clear. The first thing I did of course was to sort that out and write an asd file to compile it normally.
8:20:05
beach
flip214: You would do that by making sure the compiled file containing reader macros was loaded before the others.
8:20:06
pjb
So you only need to load (compiled) files before compiling other files when the former contain functions or other definitions needed at read-time or compilation-time of the later (reader-macros, functions used by macros, macros, etc).
8:20:28
pve
yeah, I'm looking at "The Description of Large Systems" by Kent Pitman and get the impression that such code might exist
8:21:23
beach
pve: ASDF typically compiles and loads one file at a time, so as long as the order is respected, there should be no such issues.
8:22:53
pve
So I was curious to see if there's some case where doing things that way would be called for (maybe increased convenience..)