IRC channel logs
2025-04-22.log
back to list of logs
<trannus_aran>How do y'all handle polymorphism in your guile? Message passing á la (card 'print) with the constructor dispatching on a value? Or with callback messages like (print card)? I'm doing SICP Exercise 2.4 pg. 92 and I've been thinking about this sort of thing a while now... <daviid>trannus_aran: (most of) guile users who need polylorphism use goops, guile's clos/mop implementation <trannus_aran>Isn't there like a tradeoff in performance with goops tho? <trannus_aran>I guess the question is rather: is there something between a full blown CLOS system with inheritance and something folks do with, idk, record types and message passing? Like let's say we don't need inheritance but we *do* want good C interop (maybe that's a false dichotomy, pls lemme know!) <daviid>trannus_aran: goops is light, and quite efficent <ArneBab>daviid: wasn’t there an experimental result here that goops starts becoming a bit slow when there’s a lot of different types to dispatch on? ⇒ don’t build a big data classification system mostly on goop? <ArneBab>trannus_aran: it would be great if you could do a quick benchmark: create a generic function and check whether ,profile (for-each your-fun (iota 10000)) becomes slower when you add more specialized arguments to (your-fun something). <daviid>ArneBab: no miracle, it's a runtime type dispatch system, as a user, you should only specify the strict minimum arg's type to acheive proper dispatch, generally, like most of the situation, it's on the first arg only <ArneBab>daviid: that’s what I mean. If trannus_aran wants to build something with very many types, some benchmarking could be in order. Point in case: I have not yet hit any performance problems with GOOPS. <trannus_aran>nah, it's more the case that I'm trying to strike a balance between "not making a nightmare to refactor" and "not getting bogged down with abstraction layers" <trannus_aran>considering that record types were themselves a "why do people use that? *shrug*" kinda thing to me not that long ago, I wanted to make sure I wasn't leaving good design practice on the table <daviid>ArneBab: you can have many types, g-golf extensively uses it, it defines a couple of thousands of classes (as it imports the user required namespace classes), but rarely would a user pass more then a few args to its methods, and very rarely would he need to dispatch on more then the first arg - practically speaking, ime <daviid>trannus_aran: fwiw, imo, forget about writing your own oop system, just use goops, and ask for help if necessary <trannus_aran>sounds good, I think I'm more trying to figure out when the use case *calls* for something like goops, considering how much similarly "big" software gets made in guile without it? <trannus_aran>the sorta..."C-style" scheme of just having different functions for every type is more what I'm used to (and composition of those functions thereof), so I'm kinda eyeing goops from over the fence <daviid>ArneBab: g-golf is, by far, the 'most expensive' goops app 'out there', and I have zero performance problem - I need to improve the loading time, but it's not a goops the problem <daviid>trannus_aran: as soon as you need classes and inheritance, should it be for a few classes only, use goops <trannus_aran>ooo, I actually didn't know about g-golf at all! this is dope (I figured something along these lines existed in GNU land somewhere, but hadn't taken a look yet) <trannus_aran>yeah, I think that's the thing: I almost never need inheritance, but generic functions rear their heads in terms of usefulness more often than the other OO benefits <trannus_aran>(curious how clojure handles this...thinking of other big Lisp-1 impls 🤔) <daviid>clojure 'is java', exactly the opposite of what one should be doing, wrt oop I mean - but I don't have time t discuss this, get back to hack ... good luck with your project(s), ping if you need specific goops help (and read the above tutorial) <rlb>trannus_aran: clojure has two main tracks -- it pragmatically favors "protocols" which are effectively first-argument dispatch, because the jvm's designed to make that *fast*, including wrt jit optimization at runtime, but clojure also has "multimethods", which are more or less another flavor of generic functions. <rlb>And yes, I'd generally "just use goops" past a lowish threshold. <rlb>fwiw, that's what lokke currently uses (heavily) to implement its clojure dialect. <rlb>(lokke does not yet do multimethods, though -- in truth, I've personally, rarely needed them in clojure, but it's good that they're available) <rlb>What I've read about julia sounds generally interesting as compared to some of the other options in the domain... <rlb>Never tried it, though. <ieure>Julia is one I want to experiment with more. Heard some bad things about stability/bugginess, maybe that situation has improved. <rlb>I think it may have -- fwiw, there was another lwn article in the past month(s) iirc. <rlb>also think maybe I recalled reading they've been able to shrink the resulting binary sizes if/when you want one... <rlb>though still not "small" <lechner>Hi, what is this error message hinting at, please? In procedure frame-source: Wrong type argument in position 1 (expecting VM_FRAME_P): #<output: file /dev/tty9> <ieure>lechner, Something is calling (frame-source ...) and the first argument is a value of a type the procedure doesn't expect. <ArneBab>daviid: thank you for the info. IIRC the case where someone had performance problems was that they used types to categorize a huge onthology, so they may have had more than thousands of types — hopefully not the typical case. <old>ArneBab: you asked about way of improving fibers performance. I wonder, is conditino variables sometime a bottle neck? <old>In a wait/wake pattern <ArneBab>old: I don’t know, but if you find a way to speed them up more, it would help I think. <old>There is a pattern for wait/wake that is faster than condition variable and without mutex <old>but I'm not sure if this is really a problem for the operations that fibers does <ArneBab> heap grew too much: 11.27 MiB vs. 4.75 MiB <ArneBab>old: glad to … forward your work to the people who I hope can build on it (it’s not that I did a lot) <ArneBab>with luck I could contribute something by that ☺ <old>what's faster? (append lst '()) or (append '() lst) ? <ieure>Well, they should both be noops. <ieure>old, Try `profile' and see? I'd assume that, in general, (append short-list long-list) is going to be faster than (append long-list short-list). <old>would be nice to have support for ffi with variadic arguments <mwette>libffi does not really support variadic arguments. You can generate the ffi wrapper for each call. nyacc's ffi-helper does this (automatically) but user has to pass args with type). <old>libffi seems to support variadic arguments? <mwette>argument passing in C ABIs is typically complicated, especially for x86 <old>Just wished to use syscall(2) from Guile :( <Arsen>that sounds cursed.. why not just write a few lines of C at that point ;) <old>Because I want pure Guile for what I'm doing <Arsen>I fear calling syscall negates all portability being pure guile might yield you (also, syscall is usually a macro, not a variadic function) <old>syscall(2) is always a symbol on Linux ? <old>but I managed to do what I wanted without syscall so that's fine <old>any fibers friends here? <old>I have multiple fibers that wants to print something on the terminal. I want exclusive access while printing the text to avoid mangling <old>I was thinking of using a channel, but I don't know how to terminate the consummer when `run-fibers' terminates <old>hmm right and drain the queue <old>didn't see there was condition <old>only though there was channels okay <dthompson>and then the fiber that is in charge of printing can perform a choice operation: either read from the channel or wait on the condition <dthompson>or set a terminate message through the channel <old>I would just wait on a condition and loop over a queue <old>when run-fibers terminate, it also signal the same condition but say a flag to say to stop <ArneBab>old: (define out '()) (define lst (iota 100000000)) ,profile (set! out (append lst '())) ⇒ 1.83 seconds. <ArneBab>,profile (set! out (append '() lst)) => no samples recorded. <ArneBab>old: reason: (append lst '()) is a series of cons of elements from lst to '(). <old>ArneBab: right I saw that after testing <ArneBab>old: besides: I remembered that there was a difference, but only remembered that it’s a cons after seeing the result … <old>anyway good way to profile fibers? <old>meh I guess it support it natively well enough <mwette>Technically syscall should not be hard from guile. Just create a set of calls with 1,2,3,4,5 etc long (I think) args and base off that. <old>actually the syscall I was trying to use do have a glic wrapper <old>the man pages is just plain wrong <old>good lord I have 87% usage of set-procedure-property!. None of my path use that procedure <mwette>grep set-procedure-property goops.scm <old>I use goops extensively <old>but there are static definition, I don't understand what this has to do with what I'm doing <old>I am indeed calling abunch of goop methods <old>ah I assume it was becasue I was not loading a compiled version <ArneBab>old: I’d suggest running the skynet benchmark.