freenode/#lisp - IRC Chatlog
Search
6:37:22
beach
Me? I'm doing fine. Progress is slow but steady. But I don't think that what I do is representative for #lisp.
6:42:27
elderK
I'm not quite sure how things are. They could be a lot worse, so at least there's that.
6:47:19
drmeister
Damn - ASDF appears to require fasl files to be files and doesn't allow them to be directories.
6:48:13
beach
ck_: A lot of discussion about which of several GUI libraries written in C or C++ to choose, is another.
6:48:22
elderK
beach: The problem might be with me. I'm not sure yet. I actually came here to ask advice: What have you guys done in the past when you needed to talk to like, I guess what you'd call an older-role-model. Someone who knows you, but isn't *too* close to you. Someone who's opinion you can trust, without it be influenced by the stuff you're talking about? You might say, talk to a senior colleague. That was my
6:48:23
elderK
first idea, but I haven't yet established strong enough connections with my colleagues to make that sufficiently safe.
6:49:19
ck_
beach: oh, the last point I hadn't witnessed yet. But you make it sound quite bleak in general.
6:52:39
beach
elderK: That seems quite off topic. Maybe try #lispcafe. I don't go there myself because I don't have time for random chat.
6:54:08
beach
ck_: But as I realized a few weeks ago, it's a perfect example of the prisoners dilemma.
6:56:41
beach
ck_: Ideally, Lispers should collaborate to fill the gaps in our collection of libraries and applications, but instead, everyone prefers to work on an immediate individual problem that needs to be solved. As a result, the collective effort is much higher than it could be.
6:59:58
ck_
I meant that as an attempt to nudge the focus towards doing that again. I know this channel isn't fertile ground for that, but one can hope.
7:01:34
fe[nl]ix
drmeister: you're better off going the JVM route: make your fasl a zip-encoded file which you can treat as a virtual file-system
7:03:48
drmeister
Could I generate a fasl inside of a zip-encoded file and then run dsymutil on it to generate a .dwarf file that also goes into the zip-encoded file?
7:07:01
lukego
Xach: Yeah clbuild. I think that worked as an "executable problem statement" i.e. a really quick and easy way to confirm that the latest version of everything is broken and incompatible. In those days I'd regularly "sit down to try some McCLIM hacking" and several hours later still be fighting with installation problems. Quicklisp is a hell of a better experience B)
7:07:26
drmeister
Yeah - and I get it. We talked about zip files. We thought directories would be less trouble. Now I'm not so sure.
7:08:31
fe[nl]ix
have compile-file output various intermediate files to a temp directory, call dsymutil, then package verything up in a zip fasl
7:08:53
drmeister
We are having a problem with multiple processes compiling the same asdf systems and clobbering each others builds. We need fasl generation to be atomic - so we are going to use rename-file as the atomic operation.
7:09:09
drmeister
The problem on macOS is building the fasl and debug info is two steps, not atomic.
7:10:26
fe[nl]ix
of course, as long as each compile-file a) creates a uniquely named temp dir b) creates the fasl in there and c) commits this "transaction" by an atomic rename-file
7:12:02
fe[nl]ix
if you do things right and ensure page-level alignment, you could even mmap directly from the zip file
7:12:07
drmeister
Sorry - I'm a bit disgusted at the moment. It's not just this - we found a bug in ld64 that is causing us grief with our compile-file-parallel.
8:03:28
earl-ducaine
I was just reading the SBCL style guide and noted that package prefexes were discouraged. Not a strong prohibition but I was surprised by it.
8:03:58
earl-ducaine
In my own code I tend to use them quite a bit, i.e. it makes it clear that a set of functons are from the same package and probably are documented there in how they work together.
8:04:47
pjb
earl-ducaine: when you are in the context of a local development, where you control the name of all the packages, you can choose short package names and be happy with qualified symbols.
8:05:20
earl-ducaine
I've noticed that there are a number of aspects to using package prefixes that are problematic.
8:05:47
pjb
earl-ducaine: but in the context of internet based development, where you use hundreds of libraries and dependencies, package names need to be unique and long, such as com.informatimago.common-lisp.cesarum.array etc, and then using qualified symbols is bad for readability.
8:06:17
pjb
earl-ducaine: note that it's the same problem with nicknames. If you want to publish your code, you cannot use shortnicknames.
8:06:36
pjb
earl-ducaine: Only the end-user that won't be publishing his code, can add short nicknames and use them.
8:07:39
pjb
earl-ducaine: one solution would be package-local nicknames or relative package names, but there's no complete portable solution yet.
8:09:57
earl-ducaine
Iterate is also a problematic example, it relies on a number of symbols being imported that are neither fuctions, macros or specials. Trying to prefix every one makes it an unreadable mess.
8:10:00
beach
earl-ducaine: I only ever :USE the CL package. So I use explicit package prefixes a lot.
8:11:21
beach
earl-ducaine: As pjb pointed out, using package-local nicknames would be the right thing, once they are widespread.
8:12:52
Shinmera
ECL,ABCL,CCL,SBCL is good enough coverage for me, and I hope pressure from libraries can convince the commercial implementations to catch up
8:13:48
Duuqnd
IIRC trivial-package-local-nicknames has support for Clasp too, so it's got almost everything but the commercial ones.
8:16:34
earl-ducaine
Shinmera: I saw you tweet regarding that a while back. I've been meaning to take a look at some of your projects to see how you're using them.
8:18:04
Shinmera
I just use the defpackage expression for it. That's portable across all implementations that support PLNs without needing a dependency.
8:33:32
jackdaniel
trivial-* libraries are usually portability layers which simply import symbols to a single package so the access to the protocol is uniform for the programmer
8:33:53
jackdaniel
so instead of writing #-sbcl ext:foo #+sbcl sb-ext:foo you may write trivial-foo:foo
8:34:32
jackdaniel
so if tpn s on the implementation than means this implementaiton have this extension\
8:34:46
Duuqnd
Oh, I see. Thanks for explaining! I'm not that experienced with the Common Lisp ecosystem yet.
8:47:26
phoe
pjb: package-local nicknames are cross-implementation enough now in the FLOSS Lisp world.
9:02:36
boeg
If I want to push to an empty list, how do I do that? I can easily do it with `push` if the list i initialized with something like `(list 1 2)` but if the list is empty, like `(list)`, I get the error the value nil is not of type cons
9:05:28
boeg
so... What I'm trying is that I run through a bunch of things, and if I find what I seek, I push the position of the thing I seek to a list of positions and then continue until I have a list containing all the positions. At the start, the list of positions is empty because I know no positions
9:05:54
phoe
I can push into a CAR of some cons, into a GETHASH of some hash table, into a SLOT-VALUE of some instance, et cetera, et cetera
9:06:17
boeg
beach: ah, what I'm doing right now is `(cdr (last positions))` as second argument to push
9:06:53
phoe
boeg: 1) this is not a place if LAST is not a cons, 2) pushing to the end of the list is inefficient
9:07:16
phoe
instead, push into the front of the list and nreverse it at the end if you want a reversed list
9:08:01
phoe
pjb: also, I've made https://gitlab.com/gnu-clisp/clisp/issues/20 and maybe someday some random phoe will implement it there
9:08:28
boeg
I guess I was just caught up in the mindset of "adding to the end of the list" when it really doesn't matter
9:09:27
phoe
boeg: adding to the end of the list only works if the end of the list exists as a place
9:15:52
pjb
boeg: first, you have a fundamental misconception here. One cannot "push ont a list" in lisp, since there is no list ADT in lisp! What we do, is to create a new lisp with a new element in the car of the new cons cell, and the old list in the cdr of the new cons cell. Then we rePLACE the binding of the PLACE considered with this new list.
9:16:37
pjb
boeg: we can as well push onto a PLACE that is not bound to a list! (let ((x 42)) (push 33 x) x) #| --> (33 . 42) |# this just create a new cons cell as said above.
9:18:29
pjb
boeg: Finally, I shall mention that while most lists are represented by cons cells which are potentially mutable (if they're not literal cons cells), the case of the empty list is special since it's represented by a SYMBOL which is essentially IMMUTABLE. This is why we cannot mutate lists (chains of cons cells OR the symbol NIL), since the symbol NIL cannot be changed, notably, cannot be changed into a cons cell.
9:19:02
pjb
boeg: hence delete, remove, etc having to return the new result, instead of mutating the argument value, and hence POP and PUSH working on places instead of lists.
9:19:30
pjb
boeg: a good exercise would be to implement a list ADT (eg. using CLOS standard-objects).
9:19:43
boeg
pjb: interesting - i'm still only trying to properly understand the specifics of cons cells, symbols and so on, so I shall keep that in mind
9:21:51
pjb
boeg: For more details on lists (cons cells) and exercises, you may have a look at: Common Lisp: A Gentle Introduction to Symbolic Computation http://www.cs.cmu.edu/~dst/LispBook/ http://www-cgi.cs.cmu.edu/afs/cs.cmu.edu/user/dst/www/LispBook/index.html and even at the Little Schemer (just do the exercises in CL instead of scheme).
9:22:29
phoe
pjb: I commented on that issue and mentioned that I have the background to perform the task. Thanks.
9:24:28
pjb
boeg: note that in practice (in actual programs), you can avoid NIL as a representant of the empty list, by storing your list in a cons cell (perhaps a temporary cons cell). Then you can work with the list by using cons cell MUTATION, since all the values are always cons cells.
9:25:25
phoe
that's a hack though - a list is always placed somewhere, and you can mutate that place
9:25:57
phoe
the only thing you do is standardize that the lists are going to reside in CDRs or CARS of conses
9:26:11
phoe
but CDRs and CARs of conses are places anyway, so literally nothing has changed from the technical point of view
9:26:53
pjb
Only the code is simplified because you deal only with cons cells. You don't have to special case for NIL anymore.
9:28:08
phoe
so it's like, implementing an alternate solution when for any reason we don't want to use the existing one
9:29:04
beach
Common Lisp lists are concrete. You need concrete data types to implement abstract ones.
9:29:53
beach
If you want to create a protocol for use by client code, usually you want an abstract data type.
9:31:01
pjb
For example, compare the two functions in https://pastebin.com/WaL0tTvw ; the first needs to test inside the loop for NIL; the second doesn't. It will be faster, if the consing of a temporary cons cell can be amortized.
9:35:42
pjb
It's when you need to mutate the list, ie. the actual cons cells, that the trick of using a prefix cons cell can be good, to avoid testing for nil.
9:36:35
jackdaniel
tracking the last cons is also beneficial if you want to push at the end of the list
9:37:22
phoe
since it doesn't really mutate the contents of any lists, other than NCONCing stuff onto them which doesn't change the tail
9:43:39
pjb
phoe: my point is that using a temp cons cell allows you to write a simplier loop body, with fewer tests.
10:45:58
phoe
My format call has three arguments - first, second (boolean), and third. I only want to print and process the third if the second one is true.
10:50:02
jdz
I always have to read the documentation of ~:[ at least three times — the double negativism trips me up.
10:53:54
phoe
_death: I had an instinct to s/with out/without/ but then I re-re-read and noticed that OUT is likely a formatlike library
10:59:11
phoe
_death: I saw and I'd do that myself, but there's a missing field or two in the ASDF file
10:59:16
pjb
phoe: (loop for b in '(b nil) collect (format nil "~A~@[ ~A ~A ~]" 'a b 'c)) #| --> ("a b c " "a") |#
11:00:12
pjb
(loop for b in '(b nil) collect (format nil "~A~:[ false~; true ~A~]" 'a b 'c)) #| --> ("a true c" "a false") |#
11:00:41
_death
phoe: I was referring to the not-for-public-consumption part.. but since it's been a decade, maybe it's ready for a little use
11:37:01
Xach
lukego: i wish there was a middle ground where things mostly work most of the time but you can hack on and sync upstream projects more easily
12:18:28
flip214
minion: memo for karlosz: we're scheduling right now... please tell us all topics and approx. time
12:20:57
lottaquestions
Hi all, I have a question based on one of the code examples in Practical Common Lisp
12:21:52
lottaquestions
(defmacro define-binary-class (name slots) `(defclass ,name () ,(mapcar #'slot->defclass-slot slots)))
12:22:50
lottaquestions
(macroexpand-1 '(define-binary-class id3-tag ((identifier (iso-8859-1-string :length 3)) (major-version u1) (revision u1) (flags u1) (size id3-tag-size) (frames (id3-frames :tag-size size)))))(DEFCLASS ID3-TAG NIL ((IDENTIFIER :INITARG :IDENTIFIER :ACCESSOR IDENTIFIER)
12:22:51
lottaquestions
(MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION) (REVISION :INITARG :REVISION :ACCESSOR REVISION) (FLAGS :INITARG :FLAGS :ACCESSOR FLAGS) (SIZE :INITARG :SIZE :ACCESSOR SIZE) (FRAMES :INITARG :FRAMES :ACCESSOR FRAMES)))T
12:24:13
lottaquestions
Is there something I should be doing to ensure the () does not get converted to a NIL?
12:28:35
lottaquestions
So does that mean that the code generated by the macro will run OK with the NIL
12:29:27
pjb
lottaquestions: it means that there's no difference! The object read when you read NIL or () with the default read-table is exactly the same symbol CL:NIL.
12:30:25
pjb
(mapcar 'read-from-string '("()" "( )" "NIL" "nil" "cl:nil" "CL:\Nil")) #| --> (nil nil nil nil nil nil) |#
12:31:09
pjb
lottaquestions: you should not confuse the textual representations from the actual lisp objects that are read to, or printed from.
12:42:25
kmeow
is there a built in function that produces a sequence from a sequence, but with elements meeting a condition removed?
12:49:03
drmeister
fe[nl]ix: the problem with the zip file idea is that macOS needs the dwarf file to be out in the open file system alongside the fast
13:33:26
drmeister
We get about a 2x speed increase and with our slow llvm based compiler i desire very much to get it online.
13:39:39
drmeister
So one source file generates multiple object files. That’s a problem on macOS - the ld64 linker will only reference one object file per source file.
14:10:06
drmeister
You compile to native code - right? If you had to describe how you do that in an elevator ride - how would you?
14:11:32
drmeister
When jupyterlab starts up - you can have several cando instances startup at once. They all start building asdf systems and stomp all over each other.
14:11:45
pjb
So you might solve it either by exchanging the order of generation, or by generating the fasl file under a different name and renaming it after the dwarf file is created.
14:12:41
pjb
drmeister: you will have to solve the cando problem in a different way, given 1- file generation is not atomic, and 2- you won't want to mix fasl files from different (versions of the) sources either.
14:14:07
drmeister
We thought we could use a directory as a fasl file. Then we can put whatever inside of it and rename the directory atomically.
14:14:08
pjb
drmeister: because asdf only tests and deals with the fasl file. It doesn't care about the other files.
14:14:28
froggey
for compile-file: forms are read, top-level form processing is performed (eval-when, etc), then anything that needs to be saved is fed into the compiler which produces a regular compiled-function (along with a set of relocations). compile-file accumlates the compiled functions until it finishes reading the input file, then writes out everything to the fasl
14:15:42
drmeister
Yes - so the two processes write to temporary directories and then each tries to rename its directory overwriting whatever target was there.
14:16:30
drmeister
And it works well enough for clasp - although I haven't tried multiple processes doing competitive compilation.
14:17:18
drmeister
ASDF explicitly checks that fasl files are files and not directories. I disabled that for clasp.
14:17:48
drmeister
Now I'm running into ASDF's own version of writing to a temporary fasl and then renaming it causing problems.
14:18:58
pjb
drmeister: The point here is to keep consistency. You may want to keep files consistent. But I'm saying that you will also want to keep whole directory hierarchies consistent. You don't want half the fasl files compiled by one instance of cando, and the rest by another, because then the fasl files can be inconsistent, either by way of the compilation process itself (assuming the sources are the same; eg. perhaps different optimi
14:19:19
drmeister
This is really just a problem on macOS. They do this thing where they separate out code from debug info. It's causing me grief.
14:19:25
pjb
drmeister: so you must manage it at this higher level, forbiding the two initializations to occur at the same time.
14:20:05
pjb
drmeister: this can be a problem everywhere. jupyterlab & tar xvf sources.tar && jupyterlabe
14:21:00
drmeister
Not two jupyterlab instances. One jupyterlab instance with multiple sessions running. That's very common.
14:21:39
pjb
ok. So the solution is to be solved in jupiterlab, which must prevent the launching of new session when the old ones are not finished initializing and compiling stuff.
14:21:54
drmeister
Much of the cando source code is written using ASDF systems and loaded using quicklisp.
14:22:26
drmeister
So if I edit the source code and start up jupyterlab I get like five cando instances starting up at the same time trying to build the same code. It's trample town.
14:23:01
drmeister
It works because they keep crashing and starting up again automatically and picking up where the whole mess left off. But it's not pretty.
14:27:19
drmeister
These are running in different unix processes - how would you do a lock like that?
14:35:59
pjb
drmeister: the alternative, is to compile your system before launching the cando instances!
15:34:47
boeg
A loop using :for, :with and such, what is it called? I see it used in some code, but I can't find documentation for it and don't really understand how its supposed to work
15:36:55
pfdietz
Some people prefer ITERATE, others do not. https://common-lisp.net/project/iterate/
15:37:51
pjb
a loop not using anything is a simple loop (there's an implicit block nil): (let ((i 0)) (loop (print 'hi) (when (< 3 (incf i)) (return 42)) (print 'lo)))
15:38:43
aeth
pjb: not really, LOOP is kind of a demo of what macros can do in Lisp rather than the Lispiest way to write such a macro
15:40:05
boeg
What I'm currently interested in is that is that I saw something like this somewhere: `(loop :with (a . b) = c ....` where I'm guessing that c, a list, get's "deconstructed" into the variables a and b, so a contains car and b cdr, to be used the loop, but I'm not succesful in looking that up in the documentation. I guess it'll be easier as I can more used to the customs of common lisp :D
15:40:08
aeth
pjb: If I had to implement LOOP, what I would do is I would make each of its clauses be its own s-expression and I would use plist tails to implement its vocabulary via DESTRUCTURING-BIND, which is common in macros. This would also mean that ordering within a clause wouldn't matter past the first. e.g. (:for x :from 1 :below 10) vs. (:for x :below 10 :from 1)
15:40:55
mhcat
Hi Lispers, does anyone have a recommended threading macro implementation for CL? I found alexandria's COMPOSE which solved one of my discomforts (I'm a habitual clojurist) but threading would be super useful for controlling my cascading indentation.
15:40:57
aeth
pjb: I have written something that does some limited parsing (for HTML generation), I guess sort of like what LOOP does, and it's its own thing and doesn't quite feel as right.
15:41:15
dlowe
boeg: http://www.lispworks.com/documentation/HyperSpec/Body/06_aag.htm explains the destructuring assignment
15:41:35
mhcat
If anyone has other pointers for useful utilities or other essentials, I'd be grateful
15:42:22
aeth
Josh_2: The most spirit-of-Lisp kind of thing to do is to write your own DO-FOO on top of DO (or on top of another macro that probably itself uses DO like DOLIST or DOTIMES)
15:44:46
aeth
dlowe: well, the other "right thing" that seems CLish is to use higher order functions like MAP and REDUCE
15:45:31
pjb
aeth: (defmacro loop (&rest stuff) (if (every (function consp) stuff) `(block nil (tagbody #1=#:loop ,@stuff (go #1#))) (parse-and-generate-extended-loop stuff)))
15:45:46
aeth
pjb: Having written macros where you have a "vocabulary" to parse like LOOP and macros where you just have a bunch of lists to DESTRUCTURING-BIND, I can definitely say that the latter is waaaaay easier because &key does most of your work for you
15:46:19
aeth
The only reason why D-B has some haters is because its condition is inconsistent across implementations so you can't really handle it, afaik.
15:46:44
pjb
aeth: Not only the extended loop is what you say, but it's an example of a generic macro, that dispatches to TWO different macros, depending on the arguments!!!
15:47:16
aeth
phoe: (destructuring-bind (a) (list)) ; [Condition of type SB-KERNEL::ARG-COUNT-ERROR]
15:48:16
aeth
phoe: The standard doesn't specify destructuring-bind conditions, so there's no way for you to handle them programmatically in a portable way.
15:49:26
aeth
phoe: oh, good solution, it looks like you eventually just generate a destructuring-bind so it shouldn't hurt efficiency
15:51:25
phoe
anyway, feel free to use this one and/or test it and/or file a bugticket if something is broken
15:53:35
pfdietz
Ah, it uses a flag to determine if the error comes from the destructuring or the body.
15:53:50
aeth
phoe: doesn't someone have a random tester for standard CL? you could run that but adding a * after destructuring-bind and see what comes up
15:54:57
pfdietz
Anyway, the random tester is limited to mostly integer valued forms, so it doesn't test destructuring-bind much.
16:03:24
aeth
pfdietz: that's unfortunate, I'm sure there are probably some nice, fun binding bugs out there, especially with the more advanced binding forms like destructuring-bind and defmacro
16:13:37
beach
Davd33: There are also a bunch of others that don't hang out here, like Didier Verna and Jim Newton. They are at EPITA.
16:24:01
pjb
Shinmera: it's faster than any plane, since you can work non-stop during 4 hours with your laptop. You cannot do that when you take a plane…
16:24:42
boeg
Right now i'm running my scripts with simply "sbcl --load file.lisp" but this current one is taking a looong time to finish when I use the real input to the program instead of just the test input. Can I tell sbcl to optimize the compilation - like remove debug info and so on - to run faster?
16:26:01
Xach
boeg: it is likely doing a pretty good job by default. if it takes a long time to do its work it may be the algorithm needs attention.
16:26:18
Xach
there are certainly settings to improve the margins after you have done lots of other low-hanging fruit
16:27:45
pjb
boeg: You can put (declaim (optimize (safety 3) (debug 3) (space 0) (speed 0) (compilation-speed 3))) in ~/.sbclrc
16:28:06
boeg
Xach: Well, it's surely my algorithm - I haven't optimized at all, just wanted to see if the real input gave the real output
16:28:33
pjb
boeg: and when you want to generate a binary, use (declaim (optimize (safety 3) (debug 0) (space 3) (speed 3) (compilation-speed 0))) in your generation script.
16:32:56
boeg
I have a list ((1 2 3) (5 3 6)) and I need to find the items in the two list that are in both lists. So that would be the `3` only. Right now, I just loop the first list and on each item loop the next, check if theres a match and collect the match if there is. This is probably why it takes so damn long with the real input.
16:38:00
boeg
Yeah, I was actually looking for a hash table in the beginning, but I'm pretty new to common lisp, doing advent of code to learn it, and couldn't find anything immediately, so just went with list
16:38:36
boeg
but I just confirmed that the algorithm works as it should, its just slow, so now i just need to optimize it
16:41:16
pjb
boeg: CL has no list. It has no set. But it has functions that work on lists built with cons cells, and on sets built with lists.
16:48:58
pjb
boeg: you can use a reader macro to read easily bit-vectors: https://pastebin.com/E0yfLGHS
16:50:01
arichiardi
Hi there, I have submitted an email patch to alexandria-cvs but I think it got stuck. I was wondering who I can reach out for un-stuck it :D
16:50:13
boeg
I have to go for a while, but i'll be back in a bit, optimizing my code with all of yalls suggestions cause its taking way to long right now :P
18:08:30
arichiardi
Hi all, I was wondering if I can ping someone for a patch to alexandria on common-lisp.net