IRC channel logs

2024-02-21.log

back to list of logs

<mwette>rlb, old: making progress on binding .go's in an executable. Currently chasing linker error when I try accessing .go data size: "relocation R_X86_64_PC32 against absolute symbol `_binary_dummy1_go_size' in section `.text' is disallowed
<mwette>"dummy1.go" is the name of my example module
<mwette>^ from C
<old>did you compile it with fPIC?
<old>sounds like an error I would get with a DSO not compiled with PIC
<mwette>I did not. I can try.
<mwette>I did and now get another (odd) error: didn't find scm_c_take_typed_bytevector. That symbol lives in libguile.a but not libguile.go. I'm a bit stymied right now,
<old>sounds like you need to static-link against libguile.a then
<old>I'm suprised it is not in libguile.so ?
<mwette>me too; -static generates lto errors; it's gonna take some time
<mwette>anyway, if you run `objcopy -I binary -B i386 -O elf64-x86-64 foo.go foo.xo' that generates a .xo file that can be linked with other file: gcc -o myprog myprog.c foo.xo `pkg-config --cflags --libs guile-3.0`
<mwette>the linker generates symbols of the form _binary_foo_go_start ..._size that can lead to memory to feed to load-thunk-from-memory
<mwette>^actually objcopy generates the symbols
<zyd>anyone here use Hoot? I'm unable to build despite building Guile from main: https://0x0.st/H5XP.txt
<zyd>not a scheme hacker so this is pretty beyond me to debug at the moment
<daviid>zyd: you might want to ask for help in #spritely
<zyd>thanks, will do
<lechner>Hi, is there a module that parses email addresses according to RFC 5322? Does guile-email parse only entire messages?
<lechner>nvm, i found parse-email-address. for some reason, i did not see it in the docs
<ArneBab>old: since I sometimes find GC pressure to be the main overhead when I profile, I’d bre pretty interested in having a way to do the equivalent of borrow-checking in some performance critical parts of my code. Do you know whether there’s some existing Scheme DSL that would provide that (and that gives the performance I would hope to get from having no garbage)?
<old>ArneBab: Unfortunatelly no. A DSL would not be enough I think. You really need static analysis from the compiler.
<old>However, GC and borrow checking _can_ co-exist
<old>See: https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in-d/
<old>so if some compiler guru want, they could add borrow checking syntax and analysis passes to guile compiler. Maybe it is entirely possible to do so in the compiler tower
<old>otherwise in the mean time, the best we can do in performacne critical part is to lay off the work to C
<dthompson>there's a third way: optimize hot code paths to not allocate
<dthompson>you can go very far with this approach
<dthompson>I recommend optimizing your scheme as much as possible before resorting to c
<old>right. The difficulty reside in knowing what can do an allocation in scheme
<old>can probably also dissassembler functiion in the code path to determine if allocation happen and why
<old>for clarity, here's an example: https://paste.sr.ht/~old/941de2c3b80de9dde22e2e4fc377a6fc393e0a42
<old>add-1 does not allocate memory, but cons-1 does
<old>but it is kind of cumbersome having to manually disassemble function to see if there's allocation in it. It's not like explicit allocation in C that can be seen directly
<dthompson>add-1 might allocate, depending on the number passed in
<dthompson>but cons-1 explicitly allocates since 'cons' is a constructor
<dthompson>I have a WIP blog post about optimizing guile that I should try to finish up soon...
<old>I was kind of surprised that add-1 did not allocate. I thought that every object were heap allocated
<old>I guess the return value is allocate on the stack instead or something like that?
<dthompson>old: call-scm<-scm-uimm calls a primitive function. in this case, add/immediate. depending on the type of 'x', it might allocate.
<dthompson>the only numeric type that isn't heap allocated is the fixnum
<dthompson>on a 64-bit platform that means integers in the range [-2^63, 2^63)
<dthompson>if you pass in a float, (1+ x) will allocate a new float, for example
<dthompson>there are much faster paths for math, though. the compiler can do type inference and unboxed arithmetic with specialized ops for ints and floats. what you're seeing in that disassembly is a generic math primcall.
<old>right we talked about these
<old>wonder if it could be made easier to the programmer in some way
<old>for writting good performance code
<dthompson>I think more information in the manual would be good
<dthompson>the basic patterns are pretty simple
<old>yes
<old>in the end, any type of low level optimization required knowledge about the platform/runtime
<old>wether it is in C or scheme
<ArneBab>old: dthompsoncan I check for allocations from something like a macro that checks my code (basically static analysis of the part I pass into the macro?)
<ArneBab>dthompson: could you maybe add your blog post on optimization to the guile manual, too?
<dthompson>ArneBab: maybe something could be derived from it. writing a blog post is low friction so I want to just do that for now.
<ArneBab>dthompson: is the blog post licensed in a way that people could adopt sections of it into the manual?
<ArneBab>dthompson: and i’m looking forward to your blog post!
<dthompson>I do cc-by-sa but of course fdl is fine for inclusion in the guile manual should that be something that happens
<ArneBab>dthompson: maybo you could add a note about that? ☺
<ArneBab>s/maybo/maybe/
<dthompson>people know where to reach me ;)
<ArneBab>:-)
<reedm>Hi all. Does anyone know why this is invalid scheme: '(ecc (curve Ed25519) (q #ASDF#))?
<reedm>This is the error I'm getting:
<reedm>While reading expression:
<reedm>#<unknown port>:2:28: Unknown # object: "#A"
<reedm>It's been very difficult searching for documentation, since "#" has so many names and "quote" can refer to so many things
<civodul>reedm: hi! the (ecc …) form above is actually a “canonical sexp”
<civodul>it’s something that libgcrypt can consume, but it’s not a valid Scheme sexp
<civodul>what you can do is pass it as a string to Guile-Gcrypt’s ‘canonical-sexp->sexp’ procedure
<reedm>Thanks! Is there a good keyword I can use to search more about how "#" behaves in guile?
<civodul>and ‘string->canonical-sexp’ first
<civodul>ah!
<reedm>or is that "canonical sexp"?
<civodul>well, in this case it’s canonical sexp
<civodul>so not Guile
<civodul>Guile also uses “#”, but for different things
<civodul>for Guile’s syntax, i would recommend checking the syntax spec in R5RS (not exactly that of Guile, but close enough)
<civodul>Guile also supports “hash extensions”, where you can tell ‘read’ how to interpret certain sequences that start with “#”, like “#~”
<reedm>Thanks, I'll use this as a starting point
<old>dthompson: ArneBab: another thing that could be interesting is a @nogc. See https://wiki.dlang.org/Memory_Management (Writing GC free code)
<old>So something along like this: (define/no-gc (cons-1 x) (cons 1 x)) would fail at compile time because `cons' is not define with define/no-gc
<old>ofc, nothing prevent the gc from starting if another thread do allocations, so there is no guaranteed that the gc won't interupt the procedure
<ArneBab>old: having something like that would be great! I don’t mind the gc starting — my goal is not realtime operation — I would just love to have a way to say “this is a tight inner loop. I must not create garbage here”.
<old>Right. I mean I guess it is possible to do so
<ArneBab>old: could a define/no-gc actually examine the code (or even its disassembly?) inside it to ensure that there’s no gc allocation — ideally *after* optimization?
<old>tagged function with @nogoc can only call tagged function with @nogc
<ArneBab>that could likely be done with procedure-properties
<old>ArneBab: I guess that you could do this yes
<ArneBab>but that would miss that a function might be gc-less after optimization.
<ArneBab>(and I would fail to use information that’s already in the compiler)