libera/#commonlisp - IRC Chatlog
Search
6:57:55
hayley
You didn't provide a variable name to set in the SETF forms that comprise the body of the last WHEN form.
7:24:20
abrahms
Is there a utility function that amounts to "Given <list>, replace the 4th element with <thing> and return it to me"? I've looked and I can't quite find one. rplacd is as close as I've come and it's a bit wonky of an API
7:27:12
abrahms
Close. It returns `50`. I tried playing around with setf in the repl, but it was very angry about replacing constant data.
9:51:42
mzan
beach: apart these "cosmetic" details, sadly: 1) the library series was not able to execute correctly the same code, but written in a slightly different way; 2) my code is not 100% stream-oriented, because it can not process a file of 30Mb. It is ok for 16Kb
10:13:06
beach
mzan: I did not study your code enough to understand what it does, nor the problem to understand what the code is supposed to do.
12:13:06
jcowan
hayley: a classic hacque for Unicode char classes is to keep a sorted sequence of ranges as a vector. Contains is binary search, where the index mod 2 tells you if the char is in or out. Union and intersection are O(number of ranges), and complement is O(1)
12:14:19
hayley
Interesting. I'm not sure if O(log n) for contains would be okay, but I've set myself unreasonably high standards for scanning performance so far, honestly.
12:16:16
hayley
I already have such a sorted sequence to represent sets, but I don't want to give the branch predictor a hard time. I guess I can do a binary search of fixed length branch-free though.
12:18:55
hayley
...or perhaps my two level table idea, which would allow reusing the same #*0101... subvector for each group of characters.
12:20:08
hayley
From memory, ALPHANUMERICP had some 550 ranges or so, thus 10 iterations of binary search. Not sure if that is too many.
12:34:23
pdietz
The distribution of inputs is likely highly nonuniform in practice, which would speed things up.
13:20:23
pjb
hayley: perhaps not, when dealing with random unicode characters. it can be optimized for the iso-8859-1 case. But instead of using a binary search, perhaps one could have an indexed search. Are those ranges very non-uniformly distributed?
15:02:00
mzan
beach: about my assertion "my code is not 100% stream-oriented, because it can not process a file of 30Mb. It is ok for 16Kb"
15:02:20
mzan
it is probably wrong, because I noticed that there are ways for instructing series to optimize the code.
16:51:29
_73
In SBCL when I try to compile my file with a `defpackage` clause that has an `import-from #:alexandria ...` clause I get an error "The name ALEXANDRIA does not designate any package". If I go to the repl and `(ql:quickload "alexandria")` then recompile the file everything works fine. Should I ensure that my libraries are loaded by editing my `~/.sbclrc` file, or is their a different way to load my dependencies? I have made a `.asd`
16:51:29
_73
for my project that mentions my dependencies but I don't know how to tell SBCL about it.
16:52:58
Bike
_73: packages are orthogonal to dependency resolution. to tell asdf about dependencies you should load your system via ASDF.
17:11:43
pjb
_73: you should ensure that your dependencies are loaded, indeed, but better do it by writing an asd file rather than in you rc file.
17:11:46
beach
_73: In your ASDF system definition, put :depends-on (#:alexandria), then load your system with (asdf:load-system '#:<your-system-name>)
17:13:54
White_Flame
if you put a symlink to your project directory from ~/quicklisp/local-projects/, then you can (ql:quickload "your-system") as well
17:14:31
beach
Am I the only one who finds it strange when people who are given advice don't even acknowledge having seen it?
17:16:14
Bike
well, if they don't say anything else they could just be off to lunch for a bit or something
17:16:52
beach
White_Flame: Sure, if it takes more than a few minutes to get any reaction, but if the advice is given almost immediately, one would think they would stick around.
17:17:20
_73
I have been here the entire time struggling through docs: When I try `(asdf:load-system :my-system)` I get an error `Component :MY-SYSTEM not found`. I understand from the docs that the problem is I do not have my code in a standard location like `~/common-lisp`. I am trying to modify the `asdf:*central-registry*` but can't seem to get it right.
17:18:20
White_Flame
QL wraps ASDF's functionality and adds download and a standard path (~/quicklisp/local-projects/)
17:18:52
pjb
_73: modifying asdf:*central-registry* is one way. Another is to put it in i~/quicklisp/local-projects/ (symlinks don't work with all implementations) another is to set ql:*local-project-directories* (similar to asdf:*central-registry*)
17:19:24
pjb
_73: (push #P"/path/to/the/directory/where/you/put/your/asd/file/" #| <--note the final / |# asdf:*central-registry*)
17:19:52
pjb
_73: the asd file should have the same name as the system (it's possible to be different, but it's easier if it's the same, without the ".asd" of course.
17:26:48
Bike
_73: if your asd is in /home/seventythree/code/my-system/my-system.asd, you want (push "/home/seventythree/code/my-system/" asdf:*central-registry*)
17:29:28
Bike
_73: if you're using quicklisp, another possibility is to put a symlink to my-system/ in quicklisp/local-projects, and then make sure it's synced with (ql:register-local-projects)
17:51:04
Catie
In C, it's possible to spawn a POSIX thread with a "detached" attribute, such that when the thread's function exits its resources are freed by the operating system; there's no need to join the thread. Is anyone aware of a way to spawn a "detached" thread in Common Lisp?
17:52:40
jackdaniel
if you are interested only in the final effect, then you could join in the finalizer
17:53:25
Catie
Register a finalize on the thread, all right! I'll give that a go and see if it'll work
17:53:31
Bike
i don't think implementations have this functionality much. clasp doesn't have it, doesn't look like sbcl does
17:54:03
jackdaniel
I've written recently a short piece about a certain gotcha with finalizers: http://turtleware.eu/posts/Selective-waste-collection.html
17:55:56
Catie
Bike: the issue I run into is that you can't join a thread from within itself, and threads execute in their own dynamic environment. Originally I was hoping to make this work by signalling a condition, but none of the handlers I establish in the thread-spawning context are in effect for the thread
17:56:23
Bike
i meant within the function itself. like, (make-thread (lambda () (unwind-protect (do-stuff) (clean-up))))
17:59:37
Catie
The system-reserved resource in this case is the thread itself. There's a limit along the lines of _POSIX_THREAD_MAX after which you get no more threads, and while it's incredibly unlikely that I'll run into that limit, ignoring it entirely just feels wrong
18:01:59
Catie
Yeah, it's a real weird one. The other idea I've got in my head is to have a dedicated thread-joining thread that responds to an asynchronous Unix-type signal and joins the thread, which would let my main loop continue uninterrupted
18:03:09
Catie
jackdaniel: Wouldn't establishing a finalizer on a thread object that calls join-thread on the object itself cause a cycle?
18:04:00
Bike
as he describes in the post, on some implementations (but not all, so there's a complication) the finalizer function receives the object as an argument
18:04:14
jackdaniel
some implementations (most notably _not_ sbcl and trivial-garbage) pass the object as an argument to the finalizer -this allows rehabilitation or joining the thread
18:04:22
Catie
Which is incredibly convenient! I just don't want to have to rely on a specific implementation
18:05:07
jackdaniel
well, trivial garbage is the smallest common denominator, so it will work everywhere
18:05:37
jackdaniel
the trick is to register a finalizer that closes over the resource for the single object that wraps over it (i.e (list resource))
18:06:33
jackdaniel
(let ((thread my-thread) (wrapper (list my-thread))) (set-finalizer wrapper (lambda () (join-thread thread))))
18:07:23
jackdaniel
that said, you will probably need to take care to keep wrapper alive until the thread is finished, I'm not sure how blocking finalizers behave in implementations
18:08:20
Catie
Guest74: Under FreeBSD it's aliased to __ULONG_MAX, which is probably 2^64 (but I don't feel like looking through sys/types.h)
18:09:02
Catie
jackdaniel: If the wrapper object is referencing an alive thread, could it still be garbage collected?
18:10:26
Guest74
(os:shell "cat /proc/sys/kernel/threads-max") works. 62424 on my machine. Probably not a problem for my purposes.
18:10:31
Catie
Guest74: I think PTHREAD_THREADS_MAX is compile-time, but there may be a separate runtime tunable that's less than or equal to it
18:10:42
jackdaniel
passing the wrapper to the thread's environment should suffice for that purpose I guess (because when the thread finishes then it will be referenced no more)
18:11:36
random-nick
wouldn't the implementation of detached threads just be calling the pthread function which detaches the thread on the pthread? the thread would have to unwind all the way (and run the handlers) in order to exit anyway, right?
18:17:03
Guest74
interesting max threads is determined by real memory, max threads per process by virtual memory on linux.
18:17:20
Bike
we can just have a separate thread object that keeps whatever info we want that we garbage collect normally
18:18:16
jackdaniel
yes, I didn't check on other implementaitons, but I have never actually thought that implementation might leave some linger resources when not joined
18:19:35
Catie
The SBCL thread struct has a result slot, which indicates to me that the thread is joined by the runtime somehow and the result is collected, and that calling the sb-thread join function just returns that value
18:19:55
jackdaniel
otoh I think that I remember that sbcl doesn't care for closing streams taht are garbage collected (and such leak may end with no more descriptors)
18:22:37
jackdaniel
you could have copied the file descriptor by using some internals, closing it on gc may give strange results (but well, you've copied it by using some internals :)
18:27:26
Catie
Okay, so working backwards a bit, SBCL has a global variable *joinable-threads* and a function join-pthread-joinables. When I run a thread and let it exit, it resides in *joinable-threads*. When I trigger a garbage collection, the thread is no longer in *joinable-threads*. So maybe SBCL does the convenient thing?
18:35:44
Catie
Ah, sure enough! I missed it because pauseless-threadstart isn't in my *features* anymore, so I skipped right over it
18:36:35
frgo
Oh-kay - I just booked my flights to Porto to ELS2022. Hope to see many of you there ...