IRC channel logs

2023-02-10.log

back to list of logs

<lechner>Hi, should i look at any external modules for a simple web app in addition to this? https://www.gnu.org/software/guile/manual/html_node/Web-Examples.html
<old>Say I want a module to be compatible with Guile 2.X because some distros are still on that version. How would you proceed?
<old>e.g., I use procedure P that is available since 3.0.9. I could fallback to something else if on 2.X
<old>Typically that would be done with the preprocessor in C, but what about Guile?
<gnucode>lechner: yes. You need a bit of guile code that needs to be committed to guile properly...
<gnucode> https://notabug.org/jbranso/guile-form/src/master/decode.scm
<gnucode>I think you might want that to get POST values...
<daviid>old: 7.5.2 SRFI-0 - cond-expand
<gnucode>lechner: I also have a guile web development playlist...
<gnucode> https://video.hardlimit.com/w/p/sYSiBeNcKNQjgSzpUNEg5Y
<old>daviid: awesome thank you
<daviid>old: welcome
<mwette>old: you use cond-expand
<mirai>What's missing here for (eof-object) support? <https://paste.centos.org/view/82b3d589>
<sneek>Welcome back dsmith-work!!
<dsmith-work>Happy Friday, Guilers!!
<dsmith-work>sneek: botsnack !!
<sneek>:)
<mwette>mirai: maybe this: https://paste.debian.net/1270269/
<apteryx>sxml-match seems not having the right indentation rule in emacs
<apteryx>it'd be nice to have json capability in
<mwette>do you have this: (put 'sxml-match 'scheme-indent-function 1)
<graywolf>I guess creating self-contained executable for guile program would not be that hard right? Can anyone recommend any reading on the topic (if there is any)?
<civodul>apteryx: hey! for JSON i recommend define-json-mapping; it lets you map JSON to records in both directions
<dthompson>graywolf: I don't know of anyone who has done that because guile can't produce standalone executables.
<dthompson>I have generated redistributable binary bundles for guile programs in the past by bundling up the guile executable, libguile, all the shared libs it uses, all the scheme modules, etc.
<graywolf>dthompson: Oh, I assumed since you can embed guile into C programs, it should be possible to just statically link it and bundle everything into one executable. Are there technical reasons I am missing?
<dthompson>you'd still have to bring along all the scheme modules.
<dthompson>I've never tried statically linking libguile into a program. the libraries it depends on would also need static versions to link in.
<dthompson>not sure if there are pitfalls there
<old>graywolf: It is easier said then done. I've had nighmware with trying to statically link Guile with some binary on a Ubuntu CI.
<old>Something something with libunistring
<dthompson>our best hope is having a native code compiler in the future that can produce a single executable.
<dthompson>maybe some day!
<graywolf>Right, so sounds like hard but in theory technically possible hard. Looks like fun research project, one day I might look into it. Thanks :)
<dthompson>bundling guile, libguile, etc. is the most practical approach we can take for now.
<dthompson>what I haven't tried yet is adding in something like flatpak that can produce a standalone executable with all stuff shoved into it.
<graywolf>I have... distaste for flatpak, so I hope that will not be the only way to achieve this...
<dthompson>I mean appimage
<dthompson>it's not great!
<dthompson>I agree!
<dthompson>appimage uses squashfs to do its magic
<graywolf>At that point why not just use a typical linux container? Seems like more mature way that many more developers actually understand (at least to some degree).
<apteryx>civodul: hi! that's in core Guile? thanks!
<dthompson>because you don't need a container runtime installed
<old>Guix-pack can do much of that
<old>Only for Linux though
<old>But what is the use case here for static binary?
<dthompson>it all depends on what you can assume about the target system
<old>true
<dthompson>old: giving someone a single file and saying "just run this"
<old>right then shipping a shell script with embedded .tar.gz of a guix pack should work
<old>in most cases
<dthompson>right now I've gotten guile game distribution to 2 steps: extract tarball, run executable launcher script.
<dthompson>old: there are some issues there.
<dthompson>1) a non-containerized guix package requires root privileges
<dthompson>2) a containerized version isn't guaranteed to not require root privileges
<dthompson>3) the resulting packs are huge
<old>yes I agree there's still some caveat. But it most cases where you want someone to try your stuff, it works
<old>at least I was able to run some students work on a HPC node by packing in some place else before.
<old>So it depend on the use case. For video game I agree it's not the best option
<dthompson>yeah, very use-case dependent.
<old>yes
<apteryx>dthompson: I don't understand where the root privileges requirement comes from?
<dthompson>apteryx: a non-containerized guix pack extracts to /gnu
<apteryx>ah, you mean non-relocatable, not containerized
<dthompson>relocatable guix packs aren't guaranteed to work, either
<singpolyma>Just put R more times
<old>Nothing wrong with assuming systems most support linux namespace
<singpolyma>Moar relocatable
<dthompson>the relocatable packs are good, though!
<dthompson>but shipping the entire dependency tree is not reasonable for all use-cases
<old>very true
<dthompson>the last game I made has a bundle that is 17MB. guix pack couldn't get close to that.
<old>But if we were to make a bundle Guil
<old>I think that having A) A static version of Guile available for download B) A way to patch that static version to include user modules + entry point
<dthompson>my bundles are targeted at non-guix FHS distros and assume its being run on a system with a graphical environment. reasonable assumptions for this type of thing. sometimes there are issues but most of the time it works.
<old>Or just statically link libguile with a bianry that bootstrap the program that way and include the modules in it
<old>In other words, just a matter of linkage here and bootstrapping.
<old>Easier said then done ofc, but doable
<dthompson>that could work. would be cool to see someone do it.
<old>I ain't afraid of low level so I could put a hand on that
<old>after my master thesis :-P
<dthompson>embed a squashfs like appimage
<old>Then there's the Windows problem
<old>Because who use ELF anyway
<dthompson>guile doesn't even work on windows really
<old>oh
<old>then it's a no brainer.
<apteryx>dthompson: fyi, it doesn't solve the fatness of guix packs, but the 'rpm' format (as in 'guix pack -f rpm' is coming soon (in review)
<old>The assumption is that the system is a sane one and use ELF as its binary file format
<dthompson>what I *almost* got to work was using guix to build relocatable libraries and executables for me.
<dthompson>it involved using a tweaked gcc that doesn't do runpath hardcoding (so no /gnu/store stuff) and making package variants for every library I needed that used the modified toolchain.
<old>Btw can static binary use dlopen?
<old>I can't remember
<dthompson>uhhhhh... I think so?
<old>I don't see why it could not
<dthompson>yeah me either but I don't want to be overconfident ;)
<old>but I have a vague souvenir of something
<old>well there's an easy way to find out. just some hello-world
<dthompson>one notable feature of chickadee's bundler that I think is neat is that it loads up the root scheme modules to be bundled and uses guile's module introspection to include only the set of modules needed.
<dthompson>that dramatically reduced the size of the final bundle
<old>test.c:(.text+0x13): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
<dthompson>a-ha!
<dthompson>so you need to pack those up, too
<old>it does work though
<old>but yes
<dthompson>in that case might as well just pack up all the shared libs
<old>yes
<dthompson>I use ffi stuff heavily so I would need to ship shared libs no matter what
<dthompson>until I conquer the world and replace the need for them with scheme code
<old>say you statically link all dependencies
<old>could we make the ffi to try to resolve library inside the binary itself before looking for external
<dthompson>not sure!
<old>how about something like this
<old> https://paste.sr.ht/~old/2a61fdf78a3afc5b64bcbdce9f0d6903098aec6d
<old>try to resolve "librt_shm_open" in the binary if it's available. Otherwise, lookup "shm_open" in "librt.so"
<dthompson>maybe!
<old>Only thing you need to do, generate some weak symbols in the final binary
<dthompson>my top priority for the ffi is to add something like CL's define-c-struct
<dthompson>really sucks not having it
<civodul>apteryx: define-json-mapping is in Guile-JSON
<old>dthompson: Can't find a reference to what. You have a link?
<old>i found this: http://www.lispworks.com/documentation/lw71/FLI/html/fli-55.htm
<dthompson>old: oops, got the name wrong. defcstruct
<dthompson>check this out: https://github.com/Shirakumo/cl-gamepad/blob/master/evdev-cffi.lisp
<dthompson>there's structs, bitfields, and enums here.
<dthompson>scheme-bytestructures exists but I dunno it feels too abstract. there should be something in core guile specifically for FFI purposes.
<old>hmm I see
<old>Can't be that hard to make
<dthompson>there's some struct padding rules that seem error prone
<dthompson>but nothing that some real-world usage couldn't expose :)
<dthompson>and guile has some very primitive struct handling code that does the padding right so we could use that as a starting point
<old>From what I can see, we want some syntax that could translate a more human readable form to a form acceptable for make-c-struct
<old>syntax/procedure
<dthompson>yeah it should look like a c struct definition
<dthompson>the CL syntax is very close to what it should be in Scheme imo
<old>here's something
<old> https://paste.sr.ht/~old/63a05994e24db892f8c3d27c287f95913f3bd85d
<old>Missing the getter/setter
<old>which require an understanding of the memory layout of members. Ofc that can be done
<old>we can even throw in a syntax to do something like (point (x 1) (y 2)) instead of (make-point #:x 1 #:y 2)
<dthompson>old: yeah that's the basic syntax. unfortunately, using make-c-struct and co. is inefficient.
<dthompson>but you've got the right idea
<dthompson>c struct objects should be backed by bytevectors so read/write in either c or scheme is efficient.
<dthompson>with a cached pointer object to avoid allocating a fresh pointer every time it's passed through the ffi
<old>well just need to pointer->bytevector
<old>then it's a matter of bytvector-TYPE-ref/set!
<old>with proper alignment and size
<old>I'll look into that this weekend if I have time. Should be relatively easy to do with syntax-case
<apteryx>the '...' in a match replacement doesn't behaves the same it would in a syntax definition, does it?
<old>getters/setters would be a syntax-transformer of the form: (define-syntax (getter obj) (bytevector-TYPE-ref (car obj) 0 (native-endianness) OFFSET)
<old>Not a fan of the (car obj) though. Would probably allocate an extra member at the end of the C struct to tag it. Then the object is simply a bytevector and its type is embedded in it
<old>apteryx: Both are zero or more?
<apteryx>more context: https://paste.debian.net/1270283/
<apteryx>I can work around it using map on revision and lang, but I thought there should be a way to make my original idea work
<dthompson>old: I'd recommend using a record type to hold all the data.
<old>apteryx: Hmm I'm no match guru unfortunatly :/
<old>dthompson: srfi-9 record are not bytevector?
<old>They are list I think
<old>how would you make that work?
<dthompson>old: the bytevector would be stored within the record
<old>ah
<old>but the field of the record
<dthompson>so that each distinct c struct type has its own type and they can't get mixed up
<dthompson>gotta go but nice chat!
<old> https://paste.sr.ht/~old/be66ad9dbe695af61a649432ae698488209c0552
<old>here's a refined version
<old>The type tag is whitin the bytevector. It's guaranteed to be its own type that way
<dthompson>but (bytevector? thing) would be #t
<old>yes
<dthompson>it should be false. it's *wrapping* a bytevector and is its own type
<dthompson>that's what I'd do, anyway!
<dthompson>okay g2g
<old>okay cya
<old>right. define-wrapped-pointer does that
<graywolf>Do I need to define functions in the order they are used? I assumed I can in general do (define (x) (y)) (define (y) #t) (x), and it should work. But it did blow up when I (define ...) function that used a record accessor before doing the (define-record-type). So, does order matter or I just did something bad?
<old>sneek: later tell dthompson here's with getters/setters inside srfi-9 record: https://paste.sr.ht/~old/e922eb82beae3abf0b50f7443e4112f5d6f8b513
<sneek>Okay.
<old>sneek: latter tell dthompson there's couple of things to get fix. First module resolving of type with (system foreign) means no composition of structure
<sneek>dthompson, old says: there's couple of things to get fix. First module resolving of type with (system foreign) means no composition of structure
<old>ooohhh bad sneek!
<old>sneek: later tell dthompson there's couple of things to get fix. First module resolving of type with (system foreign) means no composition of structure
<sneek>Got it.
<old>sneek: later tell dthompson then there's the referencing with bytevector with I don't like.
<sneek>Will do.
<old>sneek: botsnack
<sneek>:)
<mwette>old: If you want to create c-structs for FFI you want to think about referencing and dereferencing, I think. (The nyacc FFI Helper provides pointer-to and value-at.) Also, packed structs may be needed.
<old>mwette: Right. I'm on it
<mwette>Also, IIRC, wingo once mentioned wish to build ffi-gateway into the VM.