IRC channel logs

2025-06-18.log

back to list of logs

<wingo>current status: all internal use of smobs gone. a couple of port types to work on tho
<wingo>probably we will be able to add smob descriptors, saying how many words an object has, and which words are gc-managed. same with ports and their "stream" objects
<wingo>these sort of auxiliary data structures can be untagged if they are pointerless, otherwise they need to be tagged. if a smob type is declared without a descriptor, we would have to assume conservative tracing and disable all evacuation from that point on
<wingo>so, that is an ok upgrade story
<dsmith>ACTION sobs for the missing smobs
<wingo>you mean for those that you maintain ? :)
<wingo>they won't break
<dsmith>ok
<dsmith>Whew
<wingo>yeah i hope to not break anything that anybody is using, and smobs are definitely a thing
<wingo>that said, if this new GC works out, then using a module that defines smobs without descriptors would put Guile into a slower mode
<old>wingo: maybe emit a warning if that's the case?
<identity>old: if you mean a runtime warning, that would likely generate a lot of pointless noise for the users, i guess that would make more sense for some static analysis tool like a linter...
<old>identity: warning during compilation?
<old>AFAIK, no Guile linter exists yet
<identity>old: maybe so. i do not think i have seen any Scheme linters in general, though there is, at least, one for Clojure
<old>the thing is for smob, I'm not sure a linter will be able to detect that
<old>that is: a module that defines smobs without descriptors
<old>Great if that can be detect statically, but I suppose it might need actual runtime detection here
<old>As for a linter, I guess one way of making one is to simply re-purpose `compile-file' and discard the resulting .go, only printing the warnings/errors
<mwette>wingo: Can guile get a version of make-bytevector that includes pointers? It would be used for C-data passed to, returned from, foreign functions.
<dthompson>that sounds... dangerous
<dsmith>What is a smob descriptor?
<old>mwette: I would not rely on that. The C side could copy your pointer someplace not known to the GC
<identity>old: we would need more compile warnings, then
<identity>for the linting, i mean
<old>identity: true
<old>Actually, there is warning that are always disabled because they are too verbose and looks like false positive
<old>so these could be used as well for the linter
<mwette>dthompson: so what to do about C funtions that take structs with pointers as arguments?
<mwette>One might set the pointer field to another bytevector address. Currently, user would have to have a reference (or guardian) for that bytevector.
<mwette>What is the danger? That the pointer references a C-library malloced object?
<mwette>Ah, I see old mentions a case. So, any C-based pointers have to be managed by hand, I guess.
<old>mwette: well usualy what I do is that I keep in an srfi-9 record the bytevector and its pointer
<old>that way, I protect the bv from GC, until I am sure that the C side has finished with the pointer
<old>and I keep the pointer to avoid making repeat allocations
<old>suprisingly, bytevector->pointer is a heap allocation
<old>what could be tho is to have the GC follow allocated pointer
<old>AFAIK, that's not the case right now
<mwette>It's tough to add records when everything is laid out in C headers.
<mwette>In https://paste.centos.org/view/aaf784f1 for `attr' generated at line 72, what choice to I have besides stuffing `attr' in a guardian? Here I'm creating a new class for gtk2.
<old>that's from nyacc?
<old>I have no experience with it. I rolled my own FFI
<old>but basically the rule is that you need to keep the allocated object alive in Scheme as long as the pointer that reference it is available in the C side
<old>there is many way to achieve that
<old>but in all cases, you need to know the life cycle of the objects used on the C side
<mwette>exactly: it's the hard part of pulling in C lib's
<old>I would argue that is because C libraries does not document very well the lifetime of the objects at the boundaries
<old>My C library, libpatch, only returns handles (number).
<old>whenever there is a pointer, it is always stack-allocated and the lifetime is controlled by the caller
<old>there is very few exceptions to that, and they are very well documented in the man page
<old>and I've used Guile to write all my tests succesfully that way
<old>ofc, it's way smaller than GTK and I know all of the internals so that helps .. but still. C libraries tend to not have clear object lifetime
<dariqq>hello, is there an easy way to run an input port through a decompressor? I am dealing with multiple different compression types and i dont really want to depend on all the different guile-zlib, guile-zstd,etc
<dsmith>dariqq, You want to pipe through an external command to decompress?
<rlb>pipeline?
<rlb>ACTION hasn't used it yet...
<dariqq>basically something like make-zlib-input-port but using gzip -dc for decompressing
<dariqq>in guix they have a decompressed-port procedure which hooks up a subprocess , ill try adapting it to my use case
<dsmith>dariqq, Check out pipeline: https://www.gnu.org/software/guile/manual/html_node/Pipes.html#index-pipeline
<dariqq>dsmith: thanks, will check it out
<wingo>hellllllllllo
<noe>helllooooo!!!!!
<dthompson>hey wingo
<noe>dthompson, did you receive my patches for haunt?
<dthompson>noe: I did and I'm really sorry I haven't gotten back to you about it.
<wingo>ahahaha yesss sickos.jpg
<dthompson>I've had approximately 0 time for hobby dev projects lately
<wingo>other maintainers being delinquent, solidarity forever but also sickos.jpg
<dthompson>you need to watch out when a wingo is doing this ^
<noe>hahahaha
<dthompson>and yes, I'm just as bad as everyone else at this
<wingo>so. is there a more cringeworthy sentence than "Guile’s core language is Scheme, and a lot can be achieved simply by using Guile to write and run Scheme programs — as opposed to having to dive into C code. "
<wingo>from https://www.gnu.org/software/guile/manual/html_node/Programming-in-Scheme.html
<wingo>guile's manual ffs
<noe>dthompson, its very okay, take your time to review it
<dthompson>noe: the review probably won't take me very long... it's just getting into a state where I *can* review it has been tough
<noe>but beware with every month without review a weird workaround is made in my haunt.scm!
<dthompson>uh oh!
<noe>also, I was wondering for guile-sdl3. Should it be made as an update to GNU guile-sdl or your guile-sdl2 ?
<ieure>What can you write with haunt, a daemon you can't kill?
<dthompson>noe: omg is this patch showing that I forgot an outer <html> tag on something? oof.mp3
<dthompson>okay this is an easy merge. squeaky wheel, meet grease.
<noe>LMAO yes
<noe>I wonder on how many sites the error is
<dthompson>I don't think anyone uses the default them in practice, I made it ugly on purpose.
<dthompson>but it's good for it to be correct!!
<noe>Well, you still copy paste it to make your own
<dariqq>dsmith: it works great (and a lot simpler than theother thing) but i have not figured yet out how to setup the port i want as the input to the pipeline
<dthompson>noe: regarding sdl. guile-sdl is for sdl 1 and was written by ttn (rip) mostly in C. guile-sdl2 is mine, a separate library. I have a guile-sdl3 project going but it hasn't been released yet.
<dthompson>each major iteration of sdl has a number of incompatible changes that makes them essentially a new library. they even name the shared libraries differently.
<dthompson>getting sdl3 bindings working required a huge subproject that culminated in my newish guile-bstructs library, particularly for the new gpu api
<dthompson>but there's a number of things that need fixing before guile-sdl3 0.1.0 is ready
<dthompson>wingo: lol was that sentence written back in the <= 1.8 days?
<wingo>there are so many of them
<wingo>"Like AWK, Perl, or any shell, Guile can interpret script files."
<dthompson>feels like the author is feeling sheepish about recommending scheme.
<dthompson>did you scheme is also for programs?
<dthompson>did you know*
<noe>guile-bstructs looks very cool, I was wondering if something like this existed when touching guile-gnunet. You should upstream it so that no one has to deal with make-c-struct ever again
<dthompson>gonna start calling guile a shell when people ask me what it is
<wingo>dthompson: do you not have guile commit access
<wingo>you could make bstructs my problem
<dthompson>noe: if it stands the test of time I might. there are still things I'm not sure about...
<dthompson>sometimes you punt on scary problems and make a decision that works for the projects you know about. those sorts of things.
<dthompson>wingo: I do not have commit access
<wingo>if i remember how to log into savannah this can be fixed
<dthompson>that's a big ask ;)
<dthompson>move it to codeberg ;)
<dthompson>I would certainly appreciate commit access
<dthompson>and I would not let such power corrupt me
<noe>I would never hide a cute spritely creature in the source code!
<wingo>guile on codeberg sounds great
<wingo>will let guix settle down a bit and maybe we can con guix people into helping us move
<dthompson>we seemed to agree at guix days that following guix's lead would be good ;)
<dthompson>wingo: +1 to that
<noe>very good idea!
<cwebber>Guile should 100% move to Codeberg
<noe>wingo: this one is pretty good “Guile also comes with a growing number of command-line utilities: a compiler, a disassembler, some module inspectors, and in the future, a system to install Guile packages from the internet.”
<cwebber>and dthompson should 1000% have commit access
<cwebber>and yes we did say at Guix Days that Guile would follow suit re: codeberg or whatever forge of what Guix does
<dthompson>noe: lol
<cwebber>so
<cwebber>we should do it!
<wingo>i suspect that the general structure of the manual is more or less fine. should probably have minor changes in structure. but most of the intro sections need a complete rewrite in terms of content
<wingo>if anyone feels like they would like to have a crack at one of these sections, lmk :)
<rlb>wingo: do you know of a way, offhand, that I might more cleanly share bindings between read.scm and (ice-9 exceptions) and (srfi ...) without adding more bindings to the default module? My current hack was to use a "private" %foo hash table in boot-9.scm for the bindings, but of course that's "less than ideal".
<wingo>ACTION was looking at the manual from a gc perspective, to see what sorts of stories we were telling about gc
<dthompson>yeah do we have someone in the community that really enjoys technical writing?
<dthompson>or do we all do it because we have to sometimes? ;)
<rlb>...and agreed that the manual could use some refreshing.
<wingo>rlb: that specific situation is gnarly. no concrete recommendation.
<rlb>OK, thanks.
<rlb>The "private hash table" does "work"...
<wingo>rlb: in the worst case, we could just remove that private hash table from the module once things are booted.
<rlb>(Whole underlying reason was that I though bytestring-error should be a new-style exception.)
<wingo>we do that for some other bindings. but i sympathise with the feeling that it's ugly :)
<wingo>ah yes. converting more things to be new-style exceptions should also be a 4.0 goal
<wingo>s/more/all/
<rlb>I'm "fine" with it -- I think it's much better than further default module pollution, but just wanted to make sure I wasn't doing something too offensive :)
<wingo>it sounds fine for the time being!
<rlb>I still don't know if we (for appropriate version of we) want srfi-207, but I suppose that means it's probably ready.
<rlb>and thanks
<rlb>(gives us base64 too)
<rlb>fwtw
<dthompson>wingo: yes to new-style exceptions! if we were on codeberg we could put such a task in a milestone where we wouldn't forget :)
<wingo>yasss
<wingo>wtf is srfi-207 :)
<wingo>ACTION looks
<rlb>wingo: I'm also wondering how much change I may need to accommodate eventually wrt utf8 and the gc on the C side -- let me know if you like when you think your branch might be to the point that I might want to investigate further.
<rlb>Hah -- it's "bytestrings".
<rlb>I'm sure that clears it all up.
<wingo>rlb: #u8"foo" sgtm in the read syntax.
<wingo>if all other procedures are in a module, great
<wingo>if something needs to be in the default env, let's talk about it
<wingo>do bytestrings do something for us for file names etc?
<rlb>wingo: if you want to see what I have atm (on current main) -- https://codeberg.org/rlb/guile/commits/branch/tmp/srfi-207
<rlb>should build/test fine
<rlb>Nothing needs to be in the default envt -- I did add a read-enable as suggested (generally) bby the srfi.
<rlb>sorry
<rlb>print-enable
<rlb>Currently it unconditionally supports *reading* them.
<rlb>And they could certainly be useful wrt "binary system data", say if we do eventually allow bytevectors *somehow* with calls like getenv/setenv, paths, etc.
<rlb>(I'd love to settle on *how* we want to do that, and then I'd probably be happy to put significant work into it.)
<rlb>any number of potential approaches...
<rlb>But for now srfi-207 is probably mostly "nice to have" for people messing with bytevectors.
<rlb>Another place it might be immediately useful is in our error handling for encoding/decoding.
<rlb>Right now we throw a bytevector for a broken path, say, and so you see iirc #vu8(n n n n n) when it might be a *lot* nicer in most cases (ascii supersets) to see #u8"somethin\x85;..."
<wingo>well, short review, lgtm. as regards printing, print-enable stuff is pretty terrible -- people don't use non-default modes
<wingo>what if we made a SU8 array element type? like VU8 and U8
<rlb>right -- and iirc I had some problem with read-enable (not sure it's related), where I *really* wanted it to be scoped per-module.
<wingo>it's a bytevector, but with a hint that it should print as a bytestring
<rlb>i.e. if I changed the reader in a module, I wanted it to go back to the original settings at the end of the module -- wasn't all that useful otherise.
<rlb>"otherwise".
<wingo>in the same way that VU8 vs U8 tells it to print as #u8() vs #vu8()
<wingo>prolly there is a better name than SU8
<wingo>C8 would be possible, A8... who knows
<rlb>No idea offhand -- maybe?
<rlb>But would we want that to render as #u8"..." given the standard (if we like the standard)?
<rlb>Hmm, and is that orthogonal to srfi-207?
<rlb>i.e. if you expect srfi-207, you'd expect all bytevectors to be bytestrings.
<rlb>when it's "active"
<rlb>i.e. #u8"..."
<rlb>As a semi-related aside, I had a conversation with a less (atm) scheme-involved friend about srfis where they asked "Is that their only name?", which made me vaguely wonder about aliasing them with their summary name too if we could do that cleanly somehow. e.g. (use-modules (srfi pipeline-operators)) too. He was a bit surprised you just had to learn the numbers right now.
<ieure>I have also found that irksome.
<rlb>(Since the (srfi ...) module names are guile specific anyway -- wouldn't be useful for portable code.)
<ieure>(I have extensive Lisp experience, but have only started using Scheme in the last ~2 years)
<dthompson>it would be nice to have aliases. naming is hard, though. there's multiple srfis for the same thing.
<ieure>dthompson, We can just append a number!
<ieure>(joke)
<rlb>I was imagining we might use the srfi subtitle if they all have one.
<rlb>(and if that's unique)
<rlb>i.e. so it's completely predictable
<ieure>So SRFI's aren't portable?
<rlb>they are, but our custom names wouldn't be
<rlb>unless that approach caught on, *and* say you had portable rnrs library refs.
<rlb>or whatever
<rlb>wingo: and wrt "useful for paths" (system data) -- I'm hoping that bytestrings might be part of a useful endpoint, perhaps along with the "noncharacter encoding" approach being proposed here: https://codeberg.org/scheme/r7rs/issues/51#issuecomment-1041568
<wingo>rlb: well. in guile bytevectors are bytevectors. you can write them as #vu8(...) and they will print as #vu8(...). or likewise with #u8
<ieure>SRFI-1 says 'In a Scheme system that has a module or package system, these procedures should be contained in a module named "list-lib".'
<wingo>#u8() i mean
<ieure>So they expect you to use (list-lib), but Guile picked (srfi srfi-1)?
<rlb>right, but if you "turn on" srfi-207, they change to be rendered as #u8"..."
<wingo>#u8"" would just be a different default printing for the same underlying bytevector
<rlb>maybe I misunderstand.
<dthompson>list-lib is a pretty bad name lol
<wingo>no, it would just be those bytevectors which were either created by bytestring procs, or created via #u8"" read syntax
<rlb>wingo: are you saying that if I "turn on" srfi-207, then I would only get #u8"" for a subset of bytevectors (the tagged ones) -- if so, then that sounds like it's not exactly what srfi-207 describes.
<wingo>i.e. add a SCM_ARRAY_ELEMENT_TYPE_C8
<wingo>no i don't see "turning on" as useful
<rlb>i.e. there #u8"..." is just another way to read/write a bytevector.
<wingo>if you write #vu8(...), you expect to see #vu8(...) printed, right?
<mwette>fwiw, I always appreciated the amount of detail in the Guile Manual. For example, it's not usual to see detailed explanation and API of the underlying interpreter(s).
<rlb>and you can read both #u8() and #u8"".
<wingo>mwette: yeah there are good parts. it just needs a refresh :)
<rlb>wingo: no I don't think so with srfi-207?
<wingo>rlb: i mean in guile!
<wingo>in guile as-is
<rlb>i.e. you can read either one, but you switch to just writing #u8"..."
<wingo>i.e. vs srfi-4
<wingo>already there is a difference: srfi-4 u8vectors print as #u8(...)
<rlb>hmm, I think maybe I did misunderstand.
<wingo>whereas those created by the bytevector procedures and read via #vu8(...) print as #vu8(...)
<wingo>they are the same underneath, but they have a different "default presentation" tag in the tag word
<rlb>So by default, I *think* I would have expected bytestrings to be same as bytevectors, so "unified" with #u8()?
<rlb>ACTION goes to double-check the write syntaxes...
<wingo>well. just start with #u8(1 2 3) and #vu8(1 2 3). how would you expect them to print
<wingo>the first is srfi-4 syntax, the second is r6rs/r7rs
<rlb>I keep confusing the two...
<wingo>i would expect them to be equivalent in the sense that any procedure that can take a #u8(...) can also take a #vu8(...) -- but they should print differently
<rlb>OK, so I was assuming that the srfi was only referring to #vu8(...), i.e. whatever the bytevector constructors give you -- that the srfi was just augmenting those.
<wingo>which is what guile does (because i made it do what i expect ;)
<rlb>And so only those should be affected by the bytestring rendering "when appropriate"?
<wingo>the bytestring itself carries a tag to indicate that it should print as a bytestring, not a vu8
<rlb>right -- I think that's what I'm uneasy about.
<wingo>well, if you figure out what makes you uneasy, lmk ;)
<rlb>I didn't think the srfi imagined/described bytestrings as having any observable difference from a bytevector.
<wingo>but it is already a thing for vu8 vs u8
<rlb>And so I'd be wary about that introducing portability issues, but haven't thought it through.
<wingo>i am not sure how one would detect such a portability issue
<wingo>anywhere a #vu8() is acceptable, a #u8"" is also acceptable afaiu
<rlb>well it's fundamentally, if I now understand you, a question of "what's it for"? i.e. if the user actually wants srfi-207 to change all guile's bytevectors to be rendered as bytestrings (as I think the srfi might have suggested, but not sure), then we should leave them as "indistinguishable", but if you want bytestrings to be their own subtype (which I actually thought the srfi would have leaned against), then what you're suggesting is
<rlb>more appropriate.
<rlb>I'm not really sure, ignoring whatever the srfi did or didn't intend for the moment, which I think is preferrable yet.
<rlb>I also wonder if the desirable rendering in some cases might be independent of the precise (sub)type. For example, in the for decoding errors, I suspect we might always want to render a bytevector as a bytestring, whether it's of the right flavor or not.
<rlb>s/in the for/for decoding errors/
<rlb>(On the system data front more broadly, that "noncharacter" proposal is the most promising thing I've seen so far...)
<rlb>wingo: I'll also plan to re-read the srfi with your idea in mind.
<rlb>wingo: not saying it has to dictate what we might actually decide to do, but I assume you saw "Most of the procedures of this SRFI begin with bytestring- in order to distinguish them from other bytevector procedures. This does not mean that they accept or return a separate bytestring type: bytestrings and bytevectors are exactly the same type."
<rlb>Though they also punt on the writer config question at the end of the "External Notation" section -- you may not default to this format, and "A future SRFI is expected to add a configurable version of the write procedure which may enable the use of this notation in this context."...
<rlb>Also "When the Scheme reader encounters a string-notated bytevector, it produces a datum as if that bytevector had been written out in full. That is, #u8"A" is exactly equivalent to #u8(65).".
<rlb>(All just to explain my default inclinations - we can of course pick whatever we think best and document any differences.)