IRC channel logs

2025-10-15.log

back to list of logs

<daviid>mwette: i need to pass a pointer to a location for a double, then gets its value after the call - i am confused if i should call (cpointer (cbase 'double)) or make-cdata?
<mwette>(let ((data (make-cdata (cbase 'double)))) (foo (cdata& data)) (cdata-ref data))
<mwette>make-cdata creates space for the double; cdata& passes the pointer to that space
<daviid>ok, i was calling cpointer, and got an error ... let me fix and try
<daviid>excellent, thanks
<mwette>yw
<euouae>Hello
<mwette>o/
<euouae>It's quite annoying how boot-9 interferes with programming
<euouae>e.g. I defined a GOOPS method named peek and I'm getting errors; boot-9.scm has a silly 'peek' procedure
<euouae>I can use #:replace (peek) in the module definition, but that forces me to export peek
<euouae>Perhaps I can #:hide from boot-9?
<euouae>I don't know if #:hide is a real keyword
<rlb>euouae: agreed that were we starting from scratch I'd advocate for a smaller default environment, but yes, hide/replace/etc. are worth a look.
<rlb>e.g. "#:use-module ((guile) #:hide (apply))"
<rlb>or whatever
<euouae>There's no #:hide as far as I can tell but I can use #:renamer
<rlb>That line above is from lokke - it uses #:hide in any number of modules.
<rlb>iirc it may not be *documented* well, but it does exists/work
<euouae>oh, thank perhaps the docs are incomplete or I misread them, I'll take a look
<rlb>right
<euouae>thank you
<rlb>s/exists/exist/
<rlb>certainly
<euouae>#:use-module ((guile) #:hide (peek)) doesn't work, is boot-9.scm something else?
<rlb>It depends on where peek is coming from in part.
<euouae>or is there some issue that define-generic fails after a define has been used?
<euouae>I do (define-method (peek ...)) immediatelly without define-generic. `peek' comes from ice-9/boot-9.scm... oh maybe (ice-9 boot-9)
<rlb>oh, wait -- multimethods are more complicated.
<euouae>re-loading ice-9/boot-9.scm not allowed
<rlb>What is it you're trying to do (and I might or might not have to wait to help in more detail until tomorrow)?
<euouae>I'm defining this method (define-method (peek (scanner <scanner>)) ...) in my module for private use inside the module, but I get #<procedure peek stuff> is not a valid generic function referring to boot-9.scm's peek
<euouae>It works if I do #:replace (peek)
<dsmith>I vaguely remember something about goops and something with primitives...
<euouae>the problem is that now peek is exported and it's supposed to be private
<rlb>OK, right -- I'll have to help more tomorrow, and also need to refresh my self wrt the details.
<euouae>This isn't very important for me but it seems that it does uncover some interesting details (like #:hide perhaps not documented well)
<rlb>I do remember that :)
<dsmith>enable-primitive-generic!
<dsmith>Hmm. Just for C procedures..
<dsmith>ItExtending Primitives
<dsmith>in the manual
<dsmith>(info "(guile) Extending Primitives")
<euouae>jesus
<euouae>Hm. I think Guile should probably give a more descriptive error in the case a "C primitive" is attempted to be used in generic context
<euouae>The error should probably suggest enable-primitive-generic!
<euouae>Does this include only Guile's primitives or all primitives including user-defined C functions loaded as extensions?
<euouae>I'm also confused -- peek is not a C procedure, it's defined in ice-9/boot-9.scm
<dsmith>Yeah, my primitive comments are probably not applicable.
<dsmith>Sorry for the noise
<euouae>no worries, thanks
<euouae>I solved it by adding (define-generic peek)
<euouae>I didn't have to do anything else
<euouae>"The default duplicate binding resolution policy is given by the ‘default-duplicate-binding-handler’ procedure, and is (replace warn-override-core warn last)"
<euouae>By the above I think core "peek" should always be replaced, but define-method without define-generic elides this somehow
<euouae>sneek: tell rbl I resolved it by adding define-generic
<sneek>rbl, euouae says: I resolved it by adding define-generic
<sneek>dsmith: Greetings!
<dsmith>sneek, botsnack
<sneek>:)
<euouae>Hello
<ekaitz>euouae: o/
<dsmith>euouae, There is a letv in the string-ref primcall-converter with lots of unused variables. I doubt if removing the extras would help with your string-ref issue, but might be worth a try.
<dsmith>euouae, As in https://bpa.st/T67CW
<euouae>dsmith: I was /really/ confused about those extra variables
<euouae>I have not figured out cps enough to understand what's going on, but I thought they were part of the string representation
<dsmith>Yep apparently leftovers from when that code was way more complicated
<euouae>oh okay, so they're not needed
<euouae>One thing I've figured out is that the bug is related to the shared property of strings (%string-dump)
<euouae>I tried to look at the C sources for special handling of IS_SHARED() but I haven't pinpointed anything
<dsmith>Right. I don't think they are hurting anything.
<euouae>Another thing that really bothers me is that this appears to be an interaction between compiled/non-compiled code. I can't trigger the bug strictly from compiled code nor the REPL
<euouae>It was a suggestion that it's due to incongruent data representations between the two states (compiled/noncompiled). IDK. It's beyond me right now :)
<euouae>Do you have experience with the VM bytecode?
<dsmith>I was wondering about string encoding.
<dsmith>No experience at all. I worked through a JIT coding probem on arm some years ago, but that's it.
<euouae>I tried grasping parts of it but unfortunately the documentation is lacking in some important details
<euouae>and it's not like x86 or JVM where there's tons of details online on it
<dsmith>Yeah it's all in wingo's head mostly.
<ekaitz>bus factor is huge in guile
<euouae>ACTION learned about bus factor
<euouae>I'll send him an e-mail and see if he responds
<dsmith>I have a suspicion it might involve string representation. Like 8bit vs 32bot chars. Does Guile do 32bit char strings?
<euouae>it upgrades 1 byte to 4 byte strings, there's latin-1 and UCS-4
<euouae>I tried putting some unicode characters in there but the behavior didn't change
<ekaitz>dsmith: i think someone was trying to move to 1byte strings using utf-8
<euouae> <https://codeberg.org/rlb/guile/src/branch/utf8>
<euouae>That's the work for utf8
<dsmith>ekaitz, rlb the da man!
<dsmith>So if the string is 4byte, but the generated code thinks it 1byte, would that explain the wrong char that is returned?
<euouae>I don't know, you can inspect several bytes and most are \0
<dsmith>smells like 4byte there...
<euouae>if that were true then we'd get 25% nonzero
<euouae>let me check
<euouae>I see a lot of 0s and some concentrations of nonzeros
<euouae>What I think instead is that it's doing some wrong index calculation and I'm reading from a random part of memory
<euouae>looks like this: <https://termbin.com/e0az>
<dsmith>What text should the string be?
<dsmith>I don't see anything that looks like ascii in that
<euouae>the string is "aaaaaaaaaa...."
<dsmith>dsmith@avid:~/src/guile$ echo aaaaa | hd
<dsmith>00000000 61 61 61 61 61 0a |aaaaa.|
<euouae>You can play around with the source code here <https://codeberg.org/annoyingusername/guile-string-shared-bug/src/branch/memory>
<dsmith>I don't see a single 0x61 in that
<euouae>Run `make` and then `./run test.scm`
<euouae>yeah I attempted to search some of these hex strings inside the bug.go compiled elf but they didn't match
<dsmith>I'll try to poke at it a bit. No guarantees.
<euouae>but they're 8-byte aligned so it's some part of memory that's being printed, i.e. these are SCM objects
<euouae>dsmith: It's OK. I don't think I can fix this bug with my current knowledge
<dsmith>Have you tried on a different arch? 32bit instead of 64. Arm instead of x86. Or...
<euouae>The only thing I've tried was make sure this bug replicates on 3.0.8, 3.0.10 and HEAD
<dsmith>ok
<daviid>euouae: wrt generic, guile core procs and duplicate handler, you should call ensure-generic and use #:replace (peek) in your module def, because otherwise it will replace but you'll get a warning... and ensure-generic will tske care of the guile core proc as a default method ...
<daviid>euouae: you may as well do this yourself 'manually', see https://cgit.git.savannah.gnu.org/cgit/g-golf.git/tree/g-golf/hl-api/gobject.scm?h=devel - the connect definition related code and export ...
<euouae>#:replace exports peek which I don't want to do because it's a private method
<euouae>I don't understand the difference between ensure-generic and define-generic
<euouae>Oh, it seems that ensure-generic is an optimization over define-generic. However it's less future-proof (in case peek gets removed from boot-9.scm then it'll fail)
<daviid>look at the source code - but if private, you should call it something else and not bother with all this, imo
<euouae>No, I am following strict names because I'm trying to convert some Java source code into Guile
<euouae>It's pedagogical
<euouae>but perhaps... I should. I don't know
<euouae>(pedagogical, i.e. this is a tutorial/book thing)
<daviid>euouae: you should understand what it takes to promote a guile core proc as a method, then decide ... my 2c
<daviid>if it private, there is no need to name as the java upstream code either, imo ... but ok do as you wish ofc
<euouae>yeah thanks for ensure-generic, I'll look into it
<daviid>euouae: also, define-method will call define-generic if there is none, so you don't need to - and shouldn't because this is the most severe design bug ingoops, compared to clos,in that define-generic won'r raise an error if there is a g eneric, it will silenghtly create a new one and 'hide' the existing one ...
<euouae>daviid: but the behavior is not the same
<euouae>(define-generic peek) (define-method (peek ...)) works and merely (define-method (peek ...)) does not
<daviid>but that id because peek exists ... you must call ensure-generic - try (define-method (foo ...) ...)
<euouae>I agree with that
<daviid>euouae: if you use goops in several modules and some importmethod(s) that are also defined in diff modules, you should 'redefine' the duplicates in those modules, and add merge-generics, see the above link, lines 55 and below ...
<euouae>hmmm
<daviid>last but not least, you should be very carefull not to export (generic function) names that are imported, because in guile, the export clause is processed before the merge-generic and it will silenghtly create a new module variable which will 'hide' the imported one ... in order to avoid this problem, I wrote and use g-export, as in line 76 in the above link - the g-export code is here -
<daviid> https://cgit.git.savannah.gnu.org/cgit/g-golf.git/tree/g-golf/support/g-export.scm?h=devel - lines 54 - 63 are the important ones
<euouae>oh it's actually quite nutty to deal with
<daviid>this allw you to always (g-export foo bar ...) without having to know (to check) wether the name was imported ... extremelly important whenyou work in large code base and import others libs ... for a few modules 'on your own' it is possibleto manage, otherwise you will face 'heisen bugs'
<euouae>by the way I saw g-golf because it provided doubly-linked lists in my search
<euouae>I thought that's cool; I like GTK glib it has a lot of goodies. It's a bit annoying that baisc data structures are missing from Guile
<euouae>like queues
<euouae>yeah, it appears that scheme's semantics get in the way of OO
<daviid>euouae: yes, but that is because of a guile design, not clos/mopproblem
<euouae>too bad
<euouae>when you're trying to avoid nuttiness in all the languages out there and you once again strike nuttiness, it's a bit annoying
<euouae>the nuttiness in this case is "we have a nice OO feature, but you need to be expert-level to not shoot yourself in the foot"
<daviid>euouae: but with the advices I just gave, you're good, and is easy enough to follow
<euouae>Yeah... I'll try.
<euouae>thank you!
<daviid>euouae: looking the gobject module code I pasted above, I don1t think (and by far not) that there ids any 'nutines' - the code is cristal clear, the module definotion as well: (1) you export class names and (public) procedure names, you _always_ call g-export to export method names; (b) you never ever call define-generic - then you'll never ever have a 'guile module' based bug
<daviid>wrt define-generic, you could also adopt to define a generic module and in there calldefine-generic, then all import it ... but this will work if you do not import other libs, written by other devs, that also use goops and may define method bearing the same name(s) ...
<daviid>voilà, ping me if you need help ...
<euouae>if g-import is so good it should probably be part of goops
<euouae>i mean g-export
<daviid>g-export - this will never happen,just copy and use this code
<euouae>why not?
<daviid>because it's a patch upon a design choice - and as explained, it is one of the steps you need to take to be 'on the safe side', you also need to properly use merg-generic, properly export class names, properly replace guilecore procs promoted as methods ...
<euouae>I guess it's not a complete solution
<euouae>I mean... you make me think I should just not use goops at all heh
<euouae>It's annoying because then how will I get virtual methods etc.. :( Sigh sigh... I just need to learn all of the baove
<euouae>above*
<daviid>euouae: i don't see why following the advices, as simple as a tenn learning programming could follow and simply apply would be a motive to not using goops
<euouae>every time something must be learned it's a matter of cost/benefit
<daviid>euouae: true, you don't become a goops wizard in a few minutes, but it's worth learning and using it where appropirate, imo, it will turn you a much better programmer then just 'scheme'
<euouae>it's just a means to an end
<daviid>euouae: just wanted to help/warn/save you precious time, do as you wish
<euouae>yeah I appreciate it
<dsmith>Personally, I've never done "OO" style stuff. I suspect its main usefulness is for GUI type apps (which bullet I've mostly dodged)
<daviid>tha't's a misconception, just as an example, former guile maintainer uses goops as a high level api to mqqt, I am also using it, right now, as a high levelapi to the fluidsynth library
<daviid>but anyway, back to hack, these conversations usually go nowhere
<dsmith>Like I said. My personal experince. Which is mostly embedded and drivers and networking. Low level stuff
<dsmith>I really like the way CLOS/GOOPS does generic functions.
<dsmith>Can dispatch on any/all arguments.
<daviid>euouae: fwiw, i actually did write those advices down in 2017, rsponding a user, here is a copy of the email - https://0x0.st/KSyY.txt [the guile-user ml archive at savannah is temporarily inaccessible]
<euouae>daviid: dont' you think it's worthwhile adding a subsection in the manual on GOOPS with that advice?
<euouae>I'm not saying you should do it, I might do it, I'm just wondering, is it worthwhile? Why did you not bother?
<euouae>(I saved that email)
<daviid>euouae: as i told you, it won't be accepted, as those advices 'patch' a design choice
<euouae>oh right
<rlb>I vaguely recall having some (maybe similar) trouble with a primitive in lokke.
<rlb>daviid: oh, right, I don't recall whether I though this was "right", but might be related: https://codeberg.org/lokke/lokke/commit/dacb2df2d6b1106832181ccec085417094d9e174
<rlb>(I should probably review.)
<daviid>i wouldn't do it this way indeed
<daviid>rlb: you define a close generic but no method in that module, are other modules extending the generic-function with specialized method(s)?
<daviid>i would either call ensure-generic or manually grab and define the 'default' method, as done in guile-gnome and g-golf (and guile-cv)
<daviid>rlb: see https://cgit.git.savannah.gnu.org/cgit/g-golf.git/tree/g-golf/hl-api/gobject.scm?h=devel lines 91-96
<daviid>then you don't need to hide and keep the #:replace statment
<rlb>I'm not sure anything else *currently* defines close, but in the clojure "with-open" context, it should be a generic method, i.e. it's expected other code can and will eventually define methods.
<daviid>ensure-generic does this 'for you', but I somewhat prefers to do it 'manually'
<rlb>Ahh, right -- yeah I suspect I just hadn't remembered/noticed ensure-generic, but I think I see what you mean with respect to handling it manually too.
<rlb>(and yes, it also think it was probably confusing until I figured out what was going on :) )
<rlb>dsmith: yeah, I tend to feel like generics are great when I want/need them, and a lot of times I don't. Somewhat think of them like macros -- the bar has "some height" :)
<rlb>I also tend to favor placing them on top of a lower level api, e.g. even if you have a generic foo, tend to favor also having vector-foo and list-foo, etc. so you can be more specific when you like.
<rlb>(at least I tended toward that in lokke somewhat wrt the typical clojure polymorphic apis)