IRC channel logs

2024-01-29.log

back to list of logs

<wingo>aaah good morning
<wingo>running into a funny problem, collisions in top-level introduced identifiers...
<wingo>to recall, this is like (define-syntax-rule (define-thunk f x) (begin (define %f x) (define (f) %f)))
<wingo>where the %f is introduced by the macro. in a lexical context this produces a unique binding. however at top-level it's only approximately unique. this is because the names end up forming part of the ABI of the module, and you want compilation to be idempotent
<wingo>so what we do is take the name of the introduced id and append a truncated hash of the original form, in this case the (define-thunk) invocation
<wingo>usually works! however *sob* our hash function over pairs stops descending at some point, faster than you would think. basically it has an effort limit, and if it sees a pair and the limit is 8, it will visit the car and the cdr each with effort 4
<wingo>which, if the original term only differs in something deep in the car or cdr, means that it's easy to make collisions
<wingo>this is a correctness bug. i think i will patch psyntax to ensure that introduced id's in the same expansion are unique. doesn't help the define-module kind of module, but it will work for r6rs libraries, and library groups (i have something working here in hoot)
<wingo>civodul: good morning :) a funny problem in the scrollback
<wingo>library-group expander: https://gitlab.com/spritely/guile-hoot/-/blob/main/module/hoot/library-group.scm?ref_type=heads
<civodul>hey wingo!
<wingo>lol, happy new year
<wingo>still january ;)
<civodul>right :-)
<civodul>what’s the funny problem in here?
<wingo> https://logs.guix.gnu.org/guile/2024-01-29.log#092002
<civodul>wingo: ooh, i see
<civodul>we’ve had a hard time finding a way to make identifiers “unique”
<civodul>and actually we’re not done yet (it still fails occasionally)
<wingo>well in this case we can do so programmatically. the ribcage holds already-defined identifiers
<wingo>so we can check if one is already there, and if so, append a counter
<civodul>right, though maybe you also want them to be “unguessable”
<wingo>that is less robust from an ABI point of view -- inserting or deleting a definition can cause collisions if the user doesn't recompile everything that uses the uniquified definition
<civodul>so one cannot just write ‘f2’ and know they’ll get to the “hidden” definition
<civodul>indeed
<civodul>you mention pairs; which pairs are being hashed here?
<civodul>(i forgot the details)
<wingo>fwiw right now they are close to unguessable, they have a fixnum-bits hash appended to them
<wingo>you can guess if you are doing so on purpose but it won't happen by accident
<wingo>the pairs being hashed come from the orignal expression, e.g. '(begin (define %f x) (define (f) %f)'
<wingo>but after substituting in f and x
<wingo>here is a reproducer:
<wingo> (begin
<wingo> (define-syntax-rule (defconst f val)
<wingo> (begin
<wingo> (define t (begin 0 0 0 0 0 0 0 0 0 val))
<wingo> (define (f) t)))
<wingo> (defconst a 42)
<wingo> (defconst b 69)
<wingo> (list (a) (b)))
<civodul>oh, got it
<civodul>that’s a problem indeed
<wingo>scheme@(guile-user)> (hash '(0 0 0 0 0 42) most-positive-fixnum)
<wingo>$4 = 2158324264573792932
<wingo>scheme@(guile-user)> (hash '(0 0 0 0 0 0 42) most-positive-fixnum)
<wingo>$5 = 2158324264573792932
<wingo>i have a fix and a test, will push
<wingo>btw that library-group expander is fun, it lets us do whole-program compilation
<civodul>yes, i read your blog post and it looks pretty fun!
<wingo>does guix spend much time in psyntax?
<wingo>there are some things that could be optimized when it comes to variable lookup in large expressions, but perhaps that is not a bottleneck
<civodul>yes, it spends a lot of time in psyntax
<civodul>and yes, i suspect part of it is due to variable lookups in those alists
<civodul>the other part is eval
<wingo>civodul: regarding default-frame-width: can we change it from being a fluid to being a parameter ?
<wingo>we should mostly be moving away from raw fluids i think
<civodul>wingo: sure i don’t mind; i used a fluid because related code used fluids already
<civodul>i agree with moving away from fluids
<civodul>i wasn’t sure whether to favor consistency here :-)
<wingo>:)
<wingo>i can fix it now if that is ok for you
<wingo>done
<allana>Hi #guile! Coming from using the "partial" function from Python's functools for partial application of functions, is there a recommended way to do something similar in guile scheme? I am thinking this could be "cut" from srfi-26, but are there other options that I should consider?
<rekado>allana: There’s also https://srfi.schemers.org/srfi-232/srfi-232.html, but srfi-26 seems to be much more common.
<allana>rekado: Thanks
<jpoiret>one thing I don't like with cut is that it's not deep
<rekado>jpoiret: same
<wingo>yaargh i borked the tests, fixing
<civodul>fun, RMS emailing me: “A Lilypond developer asks for this cooperation from Guile. Could you please help them out?”
<civodul>sure we can, but it’s still not the way it works
<janneke>ACTION could imagine a world where GNU (society?) had resources to just go help them out
<civodul>heh
<apteryx>I think Lilypond dev had patches sent to guile-devel some time ago
<civodul>yes, applied
<apteryx>ok, that's great. what else do they need?
<civodul>in the end i’m reinforcing the idea that talking to rms speed things up, argh
<civodul>anyway, it’s applied, and that’s what matters
<civodul>lots of great patches sitting on guile-devel actually!
<janneke>yeah, rms should open up some resources for "the GNU extension language" already
<apteryx>yes, I was wondering if we should change the practice of sending patches there to guile-bugs, in the hope they are more easily found after a while
<janneke>(esp for integrating it into emacs *grin*)
<apteryx>to bug-guile*, actually
<civodul>bug-guile works better for me, though it doesn’t solve the “available time” problem
<apteryx>right
<mwette>To implement unique identifiers, could each module have a counter and the id's have module-counter part and global-counter part, and on load guile picks a number for a module and fills in the global part (like ld reloc processing)?
<qookie>hmm i think there's a bug in how match throws errors? if i try to `catch` it, the handler is called with the wrong number of parameters, and the format string doesn't make sense (format args are provided, but there are no format specifiers in format string)
<qookie>scheme@(guile-user)> (catch #t
<qookie>... (λ () (match 1 ['() 2]))
<qookie>... (λ args (write args)(newline)))
<qookie>(match-error "match" "no matching pattern" 1)
<qookie>afaicu the handler should be given 5 params, the first being the key and the last 4 corresponding to the last 4 arguments of display-error
<morenonatural>hey, y'all... is `future` incompatible with `open-input-pipe`? I'm using them together and I look only one process at a time
<old>morenonatural: do you block with close-pipe in the future?
<morenonatural>old, through `call-with-port`, yes
<old>I do not think they are incompatible, but pay attention to blocking behavior in futures
<old>it is easy to reach a no forwarding behavior
<old>forwarding -> progression