IRC channel logs

2023-09-06.log

back to list of logs

<haugh>I do not understand the difference between lexical and dynamic scope. After read Parameters, I thought `parameterize' would let me modify a location enclosed by a continuation, but that proves to be false. Now I see and acknowledge the conveniences provided to the top level by make-parameter, I'm just confused about what `parameterize' does different from `let'.
<haugh>The manual says "re-entering [a parameterize body] (through a saved continuation will again use the new locations." This is how `let' works, no?
<haugh>Is it fair to say that parameters are simply thread-safe closures?
<haugh>That doesn't make any sense because lexical scope is already thread-safe. I guess you use a parameter when you want to keep a default at the top level without having changes propagate to other threads, but can't I already do that with let?
<haugh>It's still convenient.
<daviid>haugh: the doc is prety good, don't you think? 6.11.12 Parameters
<haugh>Okay is this correct? "Guile's call/cc passes a continuation which, upon invocation, reinstates the dynamic scope at the time of call/cc's invocation."
<haugh>daviid, yes I've read it a few times, I'm just trying to see if there's some functionality in here that I can't achieve with `set!' and `let'
<haugh>Because if not, cool, still convenient, I just got thrown by the comparison to "global variables"
<daviid>haugh: parameterize is for situations where 'on one end' you need to 'temporarily' set its value, so that elsewhere, 'on the other end', a call to parameter will evaluate the form using the 'temporarily' set value ... you definitely can't acheive this sing let ...
<daviid>and you always ewant to avoid global variables :)
<rlb>haugh: parameters are different from let because they change values during the modifications for the current call-stack down, not globally, and not for any references "above/outside" the parameterize *dynamic* extent, not lexical.
<rlb>s/not lexical/not the lexical extent/. They're similar to clojure's "binding"s if you know those at all. Assuming I understand them correctly myself :)
<rlb>Oh, and they're distinct per-thread as per clojure's.
<rlb>(and I'm sure guile/scheme's came first :) )
<RhodiumToad>daviid: any function with an inout parameter passed as double* should exhibit the issue, I was using goo_canvas_convert_from_item_space
<RhodiumToad>daviid: my fix was https://dpaste.org/Yj9FU
<daviid>RhodiumToad: sure, but i so far never called any ... hence i always thanks when someone reports a bug or missing 'soething', to point me to the call i can use to check ... thANKS
<daviid>[ sorry i did hit the capslock while typing by mistake :) ]
<daviid>thanks for the paste
<RhodiumToad>dunno if it's the best way but it seemed to be the simplest.
<daviid>RhodiumToad: it is a good patch yes, i was working on something very similar - i don't think we should include boolean though (?)
<RhodiumToad>possibly not
<RhodiumToad>I didn't test (or even look for) any examples of that
<RhodiumToad>I included it because gi-type-tag->bv-acc did
<haugh>daviid, what do you mean by 'the other end'? If a parameter setting is bound by the parameterize body and it cannot escape the thread, isn't any "other end" by definition also in lexical scope?
<RhodiumToad>no
<daviid>haugh: the procedures/methods that sets and call are different ... how would you do that with a let?
<daviid>haugh: let me point a real example
<haugh>please and thank you
<RhodiumToad>(define (f1) (... do stuff with (param) ...)) (define (f2) (parameterize ((param 1)) (f1)))
<haugh>rlb I appreciate you as well
<RhodiumToad>f1 and f2 are separate lexical scopes, but f1 when called from f2 sees the value 1
<haugh>AH
<RhodiumToad>the key distinction is that lexical scope is about the structure of the source code, while dynamic scope is about the flow of control at run time
<haugh>Thank you very much for the simple example.
<haugh>daviid, rlb: thank you
<RhodiumToad>(on a slightly related note, is there some reason we don't have syntax-parameter-value ?)
<daviid>haugh: here - https://git.savannah.gnu.org/cgit/g-golf.git/tree/g-golf/hl-api/gtype.scm?h=devel#n363 [line 366 - i set the parameter, because elsewhere i need to 'who called' g-inst-construct [is it the user, making a <gtype-instance>, or g-golf core, because of a composite derived class created by a template] - and here i check if ... - https://git.savannah.gnu.org/cgit/g-golf.git/tree/g-golf/hl-api/gobject.scm?h=devel#n430 line 443 -
<daviid>if i wouldnt do this, then, without going into too much detail, (make class #:g-inst g-inst) would be called twice, which would be a disaster ...
<haugh>(define s 0) (define (f1) s) (define (f2) (let ((ss s)) (set! s 1) (let ((r (f1))) (set! s ss) r)))
<haugh>I'm not defending this approach or anything, but the idea is that parameters make this functionality 1) thread-safe and 2) convenient
<haugh>right?
<RhodiumToad>_mostly_ thread safe.
<RhodiumToad>also dynamic scope is properly handled by continuations without needing to dynamic-wind everything
<haugh>Okay that explains the continuations part. Very good.
<RhodiumToad>the part that's not thread safe is that new threads inherit parameter values from their creators, so values can end up being shared between threads that way.
<haugh>Got it
<RhodiumToad>(you can create thread-local parameters which inherit the default value rather than the current value on thread creation)
<RhodiumToad>(the default value can still end up shared, so you need to make it something trivial like #f)
<rlb>ACTION had to try to understand that more clearly when using it to implement lokke's "binding" form, etc. and clojure's "thread conveyance" (provided for some common cases in that world)... https://clojure.org/reference/vars#conveyance (fwiw)
<rlb>(iirc, conveyance may have been added later, but not sure)
<haugh>Are the terms "top level definition" and "global variable" interchangeable? I recall that reader macros are considered evil partly because they are "global" in the sense that they can't be bound by the module system.
<haugh>s/reader macros/reader extensions/
<RhodiumToad>depends how global you mean :-) top-level declarations are part of the current module
<RhodiumToad>but they're global in the sense that they represent a single location throughout the life of the program, unless you dig into module internals
<rlb>...second(?) call for any suggestions for tests that might exercise the utf-8 branch (regarding performance or correctness). No worries if nothing comes to mind. (Preference for scheme-side code since the (internal at least) api has changed a good bit).
<RhodiumToad>are you being properly strict when getting data that is claimed to already be in utf8?
<rlb>I hope so, but if not, we can fix it. i.e. everything should be either constructed from parts we already know are correct, or validated one way or another. (found an existing bug or so on that front too...)
<rlb>(I think)
<rlb>The domain, and guile are complicated enough, though, that I'd be surprised if everything's exactly right yet.
<rlb>I've also started adding some randomized test strings, to help increase coverage.
<rlb>Though still need to add the code to print the seed during the tests to make reproduction feasible.
<mwette>haugh: maybe run this to illustrate: https://paste.debian.net/1291085/
<mwette>rlb: sorry, lost track of your repo with the branch; can you repeat? Maybe I can try my nyacc (parser generator, C parser, ffi generator) which hammers on character processing a lot (but mostly if not all ascii)
<rlb>Heh, proving the value of the ping :) https://codeberg.org/rlb/guile-utf8-tmp I do have some pending enhancements (to migrate string-ref use int string-fold, string-fold-right, string-count, etc. to bulk utf-8 operations), but nothing major.
<rlb>s/int/in/
<rlb>...and I've optimized a good number of the ascii paths, so definitely be curious to see how that fares.
<rlb>i.e. special cased them.
<rlb>If the code does a lot of string-set!, though, that's just going to be more expensive.
<rlb>(...and would need, where possible, to shift to other approaches)
<daviid>RhodiumToad: can you patch guile, i mean did you sign 'the fsf papers' to be able to?
<daviid>though it recently changed for guile, but i am curious if you did sign the papers ...
<rlb>Hmm, what changed, or rather, is it documented somewhere?
<rlb>ACTION is in a renewal process right now...
<daviid>rlb: guile would accept patches, large patches, even if you do not sign the ṕapers, iiuc
<rlb>Hmm, interesting.
<daviid>but i haven't done that for g-golf, nor guile-cv [and foliot, which i need to completely re-write using g-golf ...]
<daviid>and i am a very bad 'admin maintainer', not only do i know very little about all this, i also use a 'questionable' terminology ... bah ... and then, if someone did sign for guile, would that apply for g-golf [ i guess so, i did sign the paper and made patches for guile-gnome ... ]
<daviid>rlb: so one has to 'redo' the signing? or you didn't have signed the papers in the past?
<rlb>It's entirely up to the specific agreement, and while mine has been generous wrt scope for the past number iterations, it's also been time-limited, so I have to renew it ever so often.
<rlb>"every"
<daviid>the thing is, i don't remember what mine is, but hope it is ethernal :)
<rlb>Heh, might be - imagine you could badger the relevant fsf address for a copy if you wanted to pursue it.
<RhodiumToad>daviid: no, I haven't done any fsf paperwork
<daviid>RhodiumToad: ok - we'd need to get you 'in' to patch g-golf ... but hopefully, you'd do it for guile, and that would apply for guile projects as well, iirc, that is what i did to patch guile-gnome ...
<daviid>rlb: you are doing this 'on your own', with the fsf people, or our maintainers have to somehow 'accompany' the procedure?
<daviid>RhodiumToad: but meanwhile, i'll get you the honour of the callable patch you pasted :)
<rlb>You mean wrt assignment? If so, I've just tried to keep track of it myself, though I'd assumed that someone might check my current status during submissions.
<daviid>rlb: ok, tx
<daviid>RhodiumToad: if you'd like to do so let me know
<daviid>RhodiumToad: i'll add boolean and gtype, for symmetry with all other similar callable 'situation' - it could very well be that some 'misterious' GI typelib would 'use' one of those ...
<mwette> rlb: I assume utf8 branch
<daviid>RhodiumToad: pushed, let me know if everything is ok, thanks
<RhodiumToad>daviid: looks good to me
<daviid>ok great
<daviid>RhodiumToad: are you planning to port your app(s) to libadwaita/gtk-4?
<RhodiumToad>is there any usable canvas widget for gtk4? I didn't find one on a cursory look
<daviid>fwiw, it seems goocanvas is unmainained, the recommeded way is to use GtkWidget [claimed to be 'a canvas', and lightweight, unlike GtkWidget in Gtk-3], the snapshot vfunc and if necessary call gtk_snapshot_append_cairo ... - https://www.reddit.com/r/GTK/comments/wknfad/interactive_2d_graphics_with_gtk4/ and https://docs.gtk.org/gtk4/migrating-3to4.html
<daviid>maybe ask for some guidance in #gtk ... it seems to me they wish to even abvandon cairo, in the long run ...
<daviid>but the current situation is a bit 'strange', just like with clutter, abandonned but nothing, till recently, libadwait is experimenting an animation api ...
<daviid>i think the snapshot vfunc will gain 'full support' in mid/long term, meanwhile, append-cairo ...
<RhodiumToad>cairo is too low-level for this purpose
<daviid>RhodiumToad: yes, meant to be called for unsupoorted similar functionality in the snapshot interface(s), iiuc ... to use gtkwidget, css and the snapshot vfunc for everything one used to do with goocavnacs ..
<RhodiumToad>that's just not a reasonable approach
<daviid>i wonder why there is no clear 'steps' proposed by the gnome team wrt this - but there is a music app, quite sophisticated, ported to gtk-4 - https://www.zrythm.org/en/index.html - that uses 'all the above'
<RhodiumToad>I've seen a couple of cases where apps have literally implemented their entire own canvas library just because of this issue
<RhodiumToad>and I'm not going to waste my time on that
<RhodiumToad>Tk remains the only GUI ever to get this right
<daviid>not familiar with tk
<daviid>i wonder what gcompris (for example) devs will do, can't get stuck in gtk-3/goocanvas for ever ...
<RhodiumToad>tk is basically tied to tcl too closely to be usable anywhere else unfortunately
<daviid>or if someone will come with the next killer canvas
<RhodiumToad>for a rough comparison, it seems to take on average maybe 3-4x as many lines of code to do equivalent GUI things with guile and g-golf as with tcl/tk
<RhodiumToad>(obviously it depends on what you're doing; but the equivalent of hello-world.scm in tcl/tk is exactly 3 lines long)
<daviid>yes, though i added a box, a label, a button ... a signal callback ... and due to GI, the import code takes a few lines :) ...
<RhodiumToad>in tcl/tk, the label takes 1 line, the button 1 line, and 1 line to add them to the toplevel window, and you're done
<daviid>i could get it down to a couple of lines as well, but anyway ... things are getting terribly complicated ... but not g-golf's fault :)
<daviid>if you look at the number of files involved, sum the number of lines of code, all ui files and the scm code [and yet i can use sxml, each helps a lot], just to get the adw1-demo ... it is scary :)
<daviid>but with this said, if you want/have to use GNOME libs, adwaita and gtk4 for the backbone, then what ever you need for your app, it still is quite a lot more fun to develop using guile/g-golf then say, rust :)
<rlb>sneek: later tell mwette oh, right - forgot to include that; yes, utf8 branch
<sneek>Will do.
<mwette> rlb: not sure if my message got through; I ran into problems with your utf8 branch, but I think I had some modules compiled from the base 3.0.9; lemme try again
<sneek>Welcome back mwette, you have 1 message!
<sneek>mwette, rlb says: oh, right - forgot to include that; yes, utf8 branch
<mwette>sneek: later tell rlb, I'm definitely seeing problems
<sneek>Okay.
<dsmith>sneek, botsnack
<sneek>:)
<mwette>sneek: later tell rlb, but might be pretty-print issues (is that included too?)
<sneek>Okay.
<mwette>sneek: later tell wingo, I'm working on rlb's utf8 port, which has your prett-print updates and I think you forgot to add port to (newline) at end of pp-if
<sneek>Will do.
<wingo>mwette: thanks!!
<sneek>Welcome back wingo, you have 1 message!
<sneek>wingo, mwette says: I'm working on rlb's utf8 port, which has your prett-print updates and I think you forgot to add port to (newline) at end of pp-if
<rlb>mwette: sorry, I forgot to mention, you'll need a full "make clean" and/or clearing of the ~ ccache because it changes the some of the data formats. I should put that in the https://codeberg.org/rlb/guile-utf8-tmp/src/branch/utf8/README-utf8-conversion
<sneek>rlb, you have 2 messages!
<sneek>rlb, mwette says: I'm definitely seeing problems
<sneek>rlb, mwette says: but might be pretty-print issues (is that included too?)
<mwette>rlb: definitily ran into broken build for ffi-helper. Somewhere parsing glib-2.0 headers.
<mwette>I found the pretty-print issue and reported to wingo.
<mwette>I think in glib-2.0/glib/gmacros.h, for which `file' says: C source, Unicode text, UTF-8 text
<apteryx>is there a (make-string n some-char) equivalent in (ice-9 format) ?
<mwette>sneek: later tell rlb, maybe check reverse-list->string
<sneek>Got it.
<mwette>rlb: have been cleaning old .go's out (in cache) for this
<haugh>apteryx, kind of a hack but you can iterate over a null list with no consumer and a MAXREPS parameter: (format #f "~12@{c~}" '()) => "cccccccccccc"
<dsmith>apteryx, No
<dsmith>apteryx, You would think something like (format #t "~10c" #\x) would do it, but that makes a newline.
<dsmith>Though ~10_ will make 10 spaces, and ~10/ 10 tabs
<dsmith>haugh, Ah cool. Didn't think of that.
<haugh>idk it's pretty questionable. I would just provide a make-string output as a format argument
<dsmith>Yeah, that's much more reasonable
<apteryx>haugh: that's what I did in the end; thanks for the ideas :-)
<apteryx>It's the first thing I've found I could *not* do with (ice-9 format) ;-)
<apteryx>it's quite powerful (and cryptic), just like good old Perl
<mwette>sneek: later tell rlb It looks to me like reverse-string->list is broken; it needs to efficiently do '(#\a #\b #\c) => "cba", but currently does => "abc", I think
<sneek>Will do.
<rekado>I sometimes wish for more string-specific procedures that already exist in the srfi-1 for lists
<rekado>something like PARTITION but for strings, for example
<rekado>I often want to process strings like I would process lists, but without converting to and from lists.
<haugh>rekado, is it just the inconvenience of the conversion or is there a performance or functionality limitation?
<rekado>it just feels inelegant to convert
<rekado>it’s really just about convenience for me. I keep remembering procedures for the wrong type.
<haugh>tricky to compose around it since the list procedures aren't consistently data-left or data-right
<haugh>rekado, http://0x0.st/HfH1.txt
<lampilelo>rekado: what about transducers?
<sneek>Welcome back lampilelo, you have 3 messages!
<sneek>lampilelo, old says: that overhead improvement of semaphore on future seem marginal without the dispatching. But that's only for a simple benchmark
<sneek>lampilelo, old says: guile-parallel 10% faster than guile-fibers with a hashed double-ended queue. Without work stealing!
<sneek>lampilelo, old says: that work stealing seems to introduce more overhead on my benchmark. Without it I get 33% faster than fibers now. Maybe the benchmark scenario is not a good case?
<lampilelo>hm, these are some pretty old messages, i haven't been here for a while
<old>yup
<old>at least 3-4 months
<old>if not 5
<lampilelo>kinda forgot about irc
<lampilelo>old: so have you used your library in any actual projects? how does it fare?
<old>lampilelo: I put guile-parallel on hold. I had much higher priority
<old>But the scheduler is quite close to fibers in term of performance and memory usage. I suspect that my limited understanding of Guile internal is the reason
<old>that or perhaps my implementation of channel