IRC channel logs

2025-10-22.log

back to list of logs

<apteryx>has someone ever noticed this? https://gitlab.com/emacs-geiser/geiser/-/issues/77 e.g., entering a pseudo module in Geiser leaves you with an empty/broken environment.
<apteryx>where pseudo module is a module declared with define-module but whose name doesn't match the actual file layout
<apteryx>since my muscle memory to enter an REPL is C-c C-a, it's annoying. One has to C-c C-z to start a REPL without trying to enter the module, then hack the define-module form into a use-modules form... which is silly.
<apteryx>sneek: later tell mwette I'm using FFI, which appears simpler and maintainable to me: https://codeberg.org/guixotic/guix/commit/483e8fcb4839d89b7460cd83c2fd4b0254908ce7. It follows a similar (but not same) API as that in Artanis.
<sneek>Okay.
<apteryx>the most convenient way to use it in Guix will be call-with-mmap-bytevector, which unmaps after a user-provided proc has run.
<apteryx>ah, hm, that's an older version...
<apteryx>something happened in my tree ^^'
<apteryx>ACTION checks reflog
<apteryx>ACTION hates when work vanishes without understanding why ^^'
<apteryx>found it, buried behind a confusing rebase set of changes https://codeberg.org/guixotic/guix/commit/a4f1e5bdf5308371460924534a7f71571da0c435
<euouae>apteryx: Hey quick question, are there any restrictions on guile code ran under guix/ in Guix? Or is the full Guile system (plus modules) available?
<euouae>Because in (guix elf) I'm noticing some odd code, and I'm wondering if it's leftovers from 10 years ago or if it's purposefully written so to be within certain constraints of the compiler environment
<tomenzgg>I dunno if anyone here's done any work with G-Golf but I'm trying to create a class that inherits from GObject; I tried (define-class <example-record> (<gobject>) (title #:init-keyword #:title #:accessor title) (year #:init-keyword #:year #:accessor year))
<tomenzgg>but GTK keeps reporting "Type `ExampleRecord` does not have a property name `title`"; I would've thought that merely creating slots would become properties of the GObject but I may simply not understand GObjects well enough.
<rlb>tomenzgg: if you can hang around, I suspect daviid will have an answer later, alternately, try back later and sneek might have an answer for you.
<tomenzgg>Oh, nice. I /may/; but thanks for the heads up: I'll check back, if it turns out I can't.
<apteryx>euouae: The full Guile system is available yes
<apteryx>(guix elf) was apparently some wip code taken from Guile 2.1 or something.
<apteryx>and never released, IIUC
<apteryx>I've given a try at mmap via the Guile FFI, following the path laid down by Mu/Nala (Artanis), made a PR for it in Guix: https://codeberg.org/guix/guix/pulls/3737, in case someone would like to comment/review.
<euouae>okay thanks for confirming
<apteryx>I think one odd consideration is in (guix syscalls), for syscalls used during early boot, where a static Guile binary is used, but (guix elf) is not used there I think.
<meaty>hmm... why is and-map not part of r7rs
<meaty>i mean, i guess it is trivial </whining>
<tomenzgg>Is there a simple way to represent CDATA in sxml (using (sxml simple))? Trying to go from the opposite direction (xml->sxml) ends up with the CDATA opening and closing stripped from the resulting sxml structure (which causes sxml->xml to encode all of the angle brackets and not include "<![CDATA[…]]>" anywhere).
<euouae>tomenzgg: without knowing too much about this problem I'd say no based on CDATA being nowhere in the source file
<euouae>I do see it mentioned in (sxml upstream SSAX)
<tomenzgg>euouae: yeah; I expect that's what allows the module to read it correctly but it doesn't seem to get represented by anything in the resulting sxml (which just winds up stripping it out and not producing 1-for-1 XML, in the end). Unfortunate. Thanks for taking a look, though.
<euouae>apteryx: do you want to see what I have so far?
<euouae>e.g. what it looks like
<apteryx>sure :-)
<euouae>This is the modified elf.scm <https://codeberg.org/annoyingusername/guile-elf>
<euouae>This is e.g. how to read all the PT_DYNAMIC entries without reading excessive data: <https://termbin.com/gavs>
<euouae>My only issue is that since I added a large amount of new definitions, compilation has slowed down significantly. I'm considering removing the extra constants that are unused (e.g. things like (define EM_ARC 45); Argonaut RISC Core)
<euouae>I thought I'd add them to immitate <elf.h> but they seem to bog down compilation!!!
<apteryx>how large is the slow-down? It seems like constants should be cheap to compile, maybe.
<euouae>Apparently not. I'm not 100% sure. I need to test it.
<euouae>real 0m5.480s versus real 0m3.526s
<euouae>from a quick test
<euouae>I wonder if it's due to the dead code elimination, I haven't put all those symbols to export
<apteryx>I just noticed now that this file seems to be in Guile, as (system vm elf)
<apteryx>I thought it was never committed to Guile but it looks like I was wrong
<apteryx>After we're done testing and reviewing, probably it'd make sense to replace that copy in Guile
<apteryx>and Guix could use it directly then, importing it from (system vm elf), in an eventual Guile release.
<apteryx>ACTION returns to looking at the diff you prepared
<euouae>I basically added 3 procedures, read-elf, read-elf-program-entry and read-elf-segment
<euouae>the rest of the diff is cruft
<apteryx>OK!
<apteryx>I see in Guile, there's a elf.h file with all the contstants needed. I wonder if these are exposed to Scheme?
<apteryx>probably not
<euouae>It's not good to mix elf.scm with elf.h
<euouae>If you're going to use parts of elf.h, might as well use all of it (parse with elf.h C procs)
<euouae>if not, then you want a pure Scheme solution because you're trying to lift functionality into Scheme; then you shouldn't rely on C files
<euouae>Guile wants to have small C parts, I assumed that's why elf.scm was written like so instead of a C extensino
<apteryx>just looking at read-elf, it looks like you went to lengths to avoid any extraneous reads :-)
<apteryx>nice
<euouae>Thanks!
<euouae>This code deals with reading segment just fine, but I haven't yet added the part for reading sections
<apteryx>So, the way you see it currently, would your work would add new, more performant procedures to access things, while preserving the rest of the API?
<euouae>The performance gain is that you don't read more than you need
<euouae>so you wouldn't get memory errors on large files if the segments you need to read fit in memory
<euouae>e.g. in the example <https://termbin.com/gavs> only the PT_DYNAMIC segments are read
<euouae>I also did not modify any existing procedures
<apteryx>is seek something very cheap in terms of IO (I assume it must be?)
<euouae>It is for read operations
<euouae>the number of seeks performed is O(n) for n: = size of program header entries
<euouae>this is optimal; the constant is 2n, optimal is n.
<apteryx>great!
<euouae>so we're not super optimized, but it's good enough IMHO
<apteryx>much better than reading the whole file in memory.
<euouae>on the other hand, we are more memory performant, to get n seeks you need to read the entire program header table
<apteryx>It'll be interesting to compare getting the PT_DYNAMIC segment using the old API + mmap vs the new one you're making, in terms of syscalls used :-)
<euouae>hm... if you are going to use mmap perhaps I shouldn't bother though, I mean we're both solving the same problem
<apteryx>I think it's nice to have both; for example on Hurd there's probably no mmap
<apteryx>so it could make more sense to use something portable for something used in every package build
<euouae>The problem with mmap is that you'll still have to add code similar to mine
<euouae>if you look at elf-segments, that's how you obtain the segments in the old elf.scm
<euouae>what it does is it parses the ph-entry and then grabs the segment. That's what I'm doing.
<euouae>The difference is that it assumes the entire file is in memory and uses indexing, and I do it with read and seek offset
<euouae>mmap behaves like read/seek offset when you index mmaped memory
<apteryx>right! so you don't need mmap to avoid reading the whole thing in memory
<euouae>mmap can be more performant but I avoid it because it's a headache
<euouae>you can see that mwette had issues trying to get it to work in Guile
<euouae>whereas my procedures in elf.scm work fine
<euouae>anyway, I think what's missing is reading sections. I'll add that too, write some examples of use, and write a decent commit ChangeLog style and I'll alert you.
<apteryx>OK! Thanks for working on it. Do you agree it'd make sense to contribute this to Guile when done?
<euouae>Sure
<euouae>since it's part of Guile I don't need to release it as an independent library as I intended
<apteryx>or if you could adjust the define-module into some r7rs define-library, it could be a portable Scheme ELF parser as a separate library, perhaps
<euouae>I don't like writing portable Scheme
<euouae>I don't know enough of standard Scheme :P
<euouae>I also don't enjoy writing preprocessor eval-when for each particular implementation, it's too much work
<euouae>for us by us I say, stick with Guile
<apteryx>r7rs makes portable scheme almost trivial, that's progress :-)
<apteryx>I asked in #hurd; apparently the Hurd has mmap
<euouae>okay to be fair, you'll still have to write code like mine because you can't use all-segments without a predicate, it'll read the whole file in memory
<euouae>I mean elf-segments
<euouae>I'll look in r7rs define-library, maybe it can be done
<euouae>but in that case I'd rather start clean slate instead of adding to (system vm elf)
<euouae>Because I don't like their API. Also they don't consider certain ELF edge cases
<euouae>(program table size >= 0xffff, section table size >= 0xff00
<apteryx>euouae: sounds fair! I'll look into the elf-segments problem
<euouae>No worries, I'll take care of it
<euouae>You convinced me to write the r7rs library for ELF and I'll make it feature-complete for posterity
<apteryx>awesome! If you stay away from 'include' and a couple features which are still lagging behind in Guile, it should be doable.
<apteryx>(if you find something which you really needed and not in guile available, you may find something of used in this SRFI 209 series: https://lists.gnu.org/r/guile-devel/2023-12/msg00062.html)
<euouae>it's a pretty simple library it shouldn't run into trouble with Scheme peculiarities
<euouae>it's just file IO and records
<euouae>what do you think the name for the library be? (file-formats elf) is what I thought of
<apteryx>Are Scheme libraries organized like this usually? topically grouped in some category like file-formats? I've seen many small libraries shipping as a single named module, e.g. (git) for guile-git, (ssh) for guile-ssh, etc.
<apteryx>So assuming this is the prevalent style, it could be just (elf))
<apteryx>but worth looking around, not just in Guile-land
<apteryx>maybe #scheme can answer that question
<euouae>sounds good
<euouae>alright I have to bail now, I'll let you know when the elf lib is complete
<apteryx>o/
<apteryx>thanks for the update
<apteryx>I'm still interested in python-on-guile if someone knows how to fix it :-)
<Kyuvi>Hi
<Kyuvi>I just noticed that lists and alists constructed with quote are immutable in guile but there is nothing about it in the documentation
<Kyuvi>Is there anywhere I can get more info on this
<Kyuvi> https://pastebin.com/hYjdLpMY
<Kyuvi>This behavior seems a bit strange and inconsistent, at least to me
<sham1>The Scheme standard(s) do often make it so that changing to a literal value is an error
<Kyuvi>because set-cdr! works but assoc-set does not
<sham1>Okay, well that's odd
<dthompson>in the paste above neither set-cdr! or assoc-set! works on the immutable value
<dthompson>ah maybe I'm reading it wrong
<Kyuvi>line 1 al is defined as '((#:a . 2)), on line 15 al is now '((#:a . 4))
<Kyuvi>I call al explicitly
<Kyuvi>though when I use assoc-set! to insert a new value al does not change, sorry I just noticed that, but set-cdr! definitely mutates the value in al
<lloda>just (set-cdr! '(a . 2) 4) gives no error
<lloda>it's a bug in your program if you do that tho
<dthompson>yeah I noticed that, too. seems wrong.
<lloda>guile could be better at flagging those to be sure
<dthompson>what's worse, I just made guile segfault
<dthompson>`guile test.scm` where test.scm contains: (define al '(1 . 2)) (set-cdr! al 3) (pk al)
<identity>immutability of literals is not enforced, but the compiler relies on it
<identity>the segfault happens because the code tries to mutate something in read-only memory
<identity>less that the compiler relies on it and more that the code output by the compiler does
<Kyuvi>I am still reading up on the immutability of litrerals, but my issue at the moment was if "assoc-set!" is supposed to act like (set-cdr! (assoc x alist) y) in some cases should it not be consistent? If not, why not?
<identity>because this is a bug
<Kyuvi>Also there does not seem to be a way to check if something is immutable or mutable or am I missing something
<Kyuvi>identity ok should I try to report it?
<identity>Kyuvi: i guess so
<dthompson>Kyuvi: there's not intended to be a way to check if a pair is mutable or not
<lloda>i think there should be. Sometimes it's important to know - should i make a copy of this huge object? etc
<lloda>and the flags do exist internally
<dthompson>it's supposed to be an implementation detail
<dthompson>rather than something user visible
<dthompson>all this aside, I *highly* recommend not mutating pairs
<dthompson>mutable pairs were a mistake
<identity>if you intend to mutate a data structure internally, you should make a copy either way. if you intend to mutate a data structure externally, then the user should not pass something immutable in
<dthompson>mutating an alist doesn't make much sense when you can just use a hash table, etc.
<identity>or insert a new pair with the same key
<dthompson>yeah it's better to use it as a persistent data structure
<Kyuvi>Thanks, will repot this.
<Kyuvi>  Any documentation on immutability of literals would be appreciated, the R7RS references is not the clearest on this subject and guile documentation does not seem to mention it at all, in fact it states here  (https://www.gnu.org/software/guile/manual/html_node/rnrs-mutable_002dpairs.html) that "all pairs in guile are mutable"
<Kyuvi>I guess I should report that as well
<dthompson>yeah the docs should be more clear
<Kyuvi>identity dthompson but if I insert a new pair, then I will need to be sure to delete the old pair, won't I?
<lloda>functions don't know where their arguments come from. Copying them or not is a valid thing to want to optimize and them being mutable is user visible regardless
<identity>Kyuvi: assoc returns the first pair it sees, so it will return the one inserted most recently
<identity>(info "(guile) rnrs mutable-strings") also says that all strings in Guile are mutable, but (let ((string "wawa")) (string-set! string 2 #\b)) throws «string is read-only»
<identity>i guess the r6rs section of the manual needs a touch-up
<lloda>the word 'literal' doesn't even appear in the concept index
<dthompson>yeah those r6rs docs are out of date for sure
<dthompson>I think the manual should also steer users away from mutating pairs and strings
<Kyuvi>identity  but I am doing this periodically, so this would create a large alist eventualy.
<old>Kyuvi: use hash table
<old>dthompson: there are legitime case for mutating pairs. e.g., (ice-9 q)
<identity>Kyuvi: if you are updating entries frequently, alist is not what you want
<Kyuvi>on an embarrassingly related note ... '=( What is the idiomatic way to store (small) data in a file outside of guile in a way that I can read the data and edit it directly if need be
<identity>old: but what about immutable queues
<dthompson>old: tbh I think (ice-9 q) is quite bad
<dthompson>there are more efficient ways to implement a mutable queue
<dthompson>pairs are great for immutable queues, though
<old>identity: you always need a mutable state anyway for a queue. wether that state is a pair or something else is irrelevan and hidden to the user
<old>dthompson: I guess ring-buffer comes to mind but then you need to handle the case of higher producer vs consumer frequencies
<identity>Kyuvi: you can ‘write’ the data out into a file and then ‘read’ it back from the file
<dthompson>old: Okasaki's 1995 paper "Simple and efficient purely functional queues and deques" explains the immutable queue
<Kyuvi>identity old yes but what is the best format to use for that clojure has edn, is there an indiomatic system for guile? JSON? the thing with hashtables is there is no way for them to  persist across sessions. Writing and reading alists is quick and easy, and I guess potentially dangerous?
<dthompson>one of the simplest purely functional data structures besides the singly linked list
<dthompson>Kyuvi: the format you serialize is not necessarily the best format for runtime access
<dthompson>you could serialize to an alist and use a hash table at runtime, for example
<identity>Kyuvi: you can use the ‘read’ and ‘write’ procedures for most stuff
<identity>where the danger of reading alists would come from?
<ray1729>Is there a good way, using Guile's (web client), to make HTTP requests with a timeout? I imagine I could spawn a thread to do the request and call join-thread with a timeout, but is there a better way?
<Kyuvi>dthompson but it is only a length of max 10. I  don't think converting that to hashtables every time is worth it
<dthompson>Kyuvi: then don't :)
<identity>ray1729: there is no good and easy way to do timeouts without asynchronicity (be it threads or fibers) of some sort
<ray1729>identity: thanks, that confirms my suspicion.
<identity>then there is cancellation safety, though i am kind of unfamiliar with that in the context of a garbage collected language
<Kyuvi>identity there might not be a danger  for alists but reading from any file might be a bit dangerous though I don't think it is an issue in my case
<old>dthompson: it's worthless to consider a container implementaiton like so without also considering what would be its usage
<old>If I want't to avoid allocation in the insertion path and also I want to avoid any lock mechanism, pretty sure I can't do that with that 1995 paper
<dthompson>sure but I wasn't talking about that??
<dthompson>I was saying that the implementation of (ice-9 q), using two lists, is bad because for a *mutable queue* there's much better implementation strategies, but the two list approach is useful for an immutable queue.
<dthompson>each has its use cases
<old>but much better implementation in what context? the ccurrent implementation allocates a single cons-cell on push. I don't think it's possible to do better in term of memory usage
<dthompson>a vector based queue would usually allocate nothing except if the queue grows too large to fit in the current vector
<dthompson>it's much better to use a vector than mutable pairs here
<old>yeah. that's when you have new problems
<old>it depends. If you can want to be lock-less, than vector are not a good choice
<old>or you discard/overwrite things in the case of a ring-buffer
<dthompson>(ice-9 q) isn't usable in the lockless case, either
<old>no it's not
<old>but it could be with some tweaks
<dthompson>that's where a purely functional queue comes into play
<dthompson>this is what fibers does, for example. it uses immutable queues stored in an atomic box.
<old>yeah and the results is a lots of allocation in the scheduler
<dthompson>the point is that it's trivial to get safe, lock free behavior from functional data structures if those are the kinds of properties you need
<dthompson>I don't really understand what we're debating at this point
<old>well the original point is: mutating cells are dangerous
<old>I just argue that there are valid cases for it
<dthompson>but you just argued *against* it
<old>ice-9 q is one, even if it's not the best implementation for allllll cases, it does a fairly good job without doing much allocation and complex synchronization
<old>I don't think I have?
<dthompson>it's not a good implementation for any case, really, is my point. it's not useful for concurrent programs without additional protection/synchronization, and it's also not good in sequential programs because a vector-based queue would allocate a lot less.
<old>If you compact the vector sure that's a fair point
<old>btw this is a issue I had with fibers with the lock-less queue for tasks: https://codeberg.org/fibers/fibers/issues/138
<tomenzgg>'Mornin', #Guile.
<mwette>re: immutable literals the Guile manual says: "Note that an application must not attempt to modify literal lists or vectors obtained from a quote form, since they may be in read-only memory."
<sneek>Welcome back mwette, you have 1 message!
<sneek>mwette, apteryx says: I'm using FFI, which appears simpler and maintainable to me: https://codeberg.org/guixotic/guix/commit/483e8fcb4839d89b7460cd83c2fd4b0254908ce7. It follows a similar (but not same) API as that in Artanis.
<mwette>apteryx: Thanks. I assume user needs to manually unmap.
<Kyuvi>mwette Aha, thanks, that clarifies it somewhat
<mwette>section is "Reading and Evaluating Scheme Code"
<dthompson>hoot 0.7.0 has been released https://spritely.institute/news/hoot-0-7-0-released.html
<tomenzgg>🎉
<ArneBab>dthompson: here’s the promised PR for minmax: https://codeberg.org/spritely/hoot/pulls/785/files
<ArneBab>dthompson: and woohoo! (0.7.0)
<dthompson>thanks ArneBab!
<ekaitz>wingo: we need to talk about the lightening!
<sneek>Welcome back ekaitz, you have 1 message!
<sneek>ekaitz, sham1 says: While I can't be really sure, having one commit per package might be a vestige of the email-based patch workflow. It probably also makes bisecting easier
<ekaitz>sneek: botsnack
<sneek>:)
<ekaitz>this is cross-channel, right? that was an answer to something I wrote in guix
<sham1>Yes
<sham1>You'd think the bot would make sure it's in the right channel, but oh wells
<ekaitz>hehe
<ekaitz>wingo: i made the CI config for codeberg so we can move it to the guile org in codeberg
<ekaitz>wingo: all tests pass
<ArneBab>ekaitz: will you talk with wingo about the lightening patch by Lilypond to make Windows work?
<ekaitz>ArneBab: i wasn't thinking on that honestly
<ekaitz>i didn't even know about it
<ekaitz>i want wingo to put the lightening under the guile org in codeberg, because now it lives in his own repo in gitlab
<ArneBab>ekaitz: it’s transferred: https://codeberg.org/guile/lightening/
<ArneBab>ekaitz: it’s about this: https://codeberg.org/guile/guile/pulls/23
<ekaitz>yep! civodul is helping me with this
<ArneBab>ekaitz: and that’s important, because we’re frustrating Lilypond devs again who did the hard work to make Windows work and are now blocked by regulatory overhead.
<ekaitz>i didn't know about that but i guess the timing is perfect!
<ArneBab>ekaitz: can you get guile/pull/23 into lightening?
<ekaitz>i could
<ekaitz>let me prepare the CI first
<ArneBab>thank you.
<ArneBab>The reason why I’m asking here as I do is that the wording »I submitted this "upstream" 15 months ago« in the PR is a warning sign that frustration may be close to boiling over.
<ekaitz>ArneBab: it took me 2 years to merge my JIT work
<ArneBab>it’s an obviously correct 6 line patch that fixes JIT on Windows.
<ArneBab>(and yes, it should first get a CI run)
<ArneBab>What’s the process to get lightening improvements into Guile?
<Kyuvi>Is guile being developed on codeberg now? I thought it was on savannah
<rlb>Kyuvi: codeberg is now the main repo.
<Kyuvi>rlb Thanks. Nice.
<ekaitz>ArneBab: civodul told me it uses a branch for lightening
<ekaitz>that's the old way to do submodule-like features
<Kyuvi>Are there any contributing guidelines for guile on codeberg?
<Kyuvi>Should I post issues on codeberg? I already sent the one today to "bug-guile@gnu.org" should I put it on codeberg as well?
<rlb>Either is fine I think.
<rlb>Oh, wait, not sure about issues atm -- pr's are fine.
<rlb>and bug-guile is fine
<rlb>And some hacking/contribution information is I think in HACKING
<rlb>Though I'd be surprised if that doesn't need an update.
<rlb>You can also look at the git log history to get a sense of what commits should look like, e.g. still require changelog-style entries in the commit messages, need NEWS entries when appropriate, etc.
<ekaitz>ArneBab: I added the commit of #23 to lightening
<ekaitz>ArneBab: but you should undo the pr I believe
<ArneBab>ekaitz: thank you!
<Kyuvi>rlb Thanks, yes HACKING still seems to be based on the Savannah workflow, but it has some useful info. I will look into the commits
<ekaitz>ArneBab: you are welcome! in the end preparing this whole thing wasn't as difficult!
<ekaitz>many things are delayed for no reason
<rlb>(I'll often just poke at some of Ludovic and Andy's recentish commits when I can't recall some relevant requirements-related bit.)
<ArneBab>ekaitz: yes. I’m always trying to get improvements from Lilypond included where I have the needed skills - and prod others where I don’t - because I both like it a lot and consider it a strategically very important user of Guile. Anything that can make lily’s use of Guile more enjoyable to them is a step towards proving viability beyond innovators and early adopters (in marketing terms).
<ArneBab>ekaitz: can the PR cause conflicts? (I don’t know whether I can undo it -- beyond pushing and merging a revert commit that could cause conflicts the same way)
<ArneBab>I’d hope that merging should just work …
<ekaitz>ArneBab: I'd say a revert should work