IRC channel logs

2025-01-16.log

back to list of logs

<lechner>actually, i'm asking that question. all my parameters are bare pointers (or unboxed integers)
<lechner>oh i see. sorry
<lechner>i get no such errors. in fact, nyacc v2 gave new energy to my project. the ffi code works flawlessly and the cdata interface is super intuitive
<mwette>If an arg for a ffi-compiled function is a (cdata) typedef that resolves to a number, then passing a number should work.
<mwette>Thanks. I was hoping for a good result from the rework.
<mwette>rlb: true story: When I was in grad school I was approached by someone who introduced himself as Brian Fox. He said he was working for RMS to create a new Bourne-based shell and was wondering if he could get time on our Sun1. I agreed (until I was ordered to stop) and ended up being of the first alpha-testers for bash.
<lechner>mwette / I have a couple of remarks about cdata if you'd like to hear them
<mwette>Yes. Could you post to https://savannah.nongnu.org/bugs/?group=nyacc&func=additem
<lechner>sure
<ArneBab>lechner: apteryx … sorry.
<lechner>ArneBab / i have to say sorry for being too pedantic. apparently sneek uses levenshtein distance of at least 1!
<ArneBab>:-)
<ArneBab>sneek is pretty neat
<dsmith>lechner, It's something else: "metaphone" https://en.wikipedia.org/wiki/Metaphone
<dsmith>lechner, (no, I did *not* write this!) https://gitlab.com/dalepsmith/sneek/-/blob/master/scripts/bot/metaphone.scm
<dsmith>Can I nerd snipe anyone into rewriting that with match?
<lechner>sneek / seen deesmith
<lechner>sneek / seen lexner
<lechner>Hi, does anyone have a read-line that does not echo the characters being typed?
<UncleRRR>So you want the bahaviour being like that of getpasswd where you can't see what is typed in?
<mwette>maybe gen ffi for rl_tty_set_echoing, to allow https://paste.debian.net/1345423/
<mwette>where `int rl_tty_set_echoing (int);'
<lechner>UncleRRR / yes
<mwette>lecher: guile's `getpass' seems to support readline already
<lechner>mwette / thanks! that's beautiful!
<lechner>Hi, what happens to read-line when confronted with an impossibly large number of input characters, please?
<mwette>don't know. here is the manual: https://tiswww.cwru.edu/php/chet/readline/readline.html
<mwette>dsmith: here is a cute algorithm that may inspire: https://norvig.com/spell-correct.html
<mwette>^ in python
<dsmith>Heh along with two implementaions in Scheme (Gauche and PLT)
<mwette>interesting problem
<shawnw>ACTION just whipped up a version in modern Racket. Looks very different from that old PLT one.
<lechner>mwette / Hi, I just meant Guile's read-line procedure and not the Readline library
<rlb>mwette: hah, nice.
<rlb>...deesmith?
<lilyp>mwette: the code increases in complexity if you call edits "levenshtein"
<sneek>tohoyn: Greetings
<tohoyn>sneek: botsnack
<sneek>:)
<mwette>guile-readline calls readline. the buffer overflow would happen in libreadline, I think. I wonder what it's behavior is.
<mwette>lilyp: I bet it does
<lechner>mwette / i was merely talking about the procedure exported by (ice-9 rdelim) https://bpa.st/744A
<lechner>mwette / in a more urgent matter (cdata c-struct) allocates rather than aliases, right?
<lshoravi>Hi all. Not to hijack, I need help with a segfault using g-golf. Trying to `(define xyz (make <any-widget>))` segfaults the program. I don't know where to begin.
<lshoravi>also, if someone feels this has been asked earlier today had some struggles with setting up my IRC client. Seems to work now.
<mwette>lechner: Do you mean `(make-cdata my-type)' ? I do have (not yet exported) procedure to `alias' as you say: `(make-cdata/* my-type <pointer-val>)' Otherwise you can go through a pointer `(cdata* (make-cdata my-type* <pointter-val>))'
<lechner>mwette / well, when interfacing with C, I most often alias pointers and then access their contents via cdata. That is a pretty basic use case, i guess. When data is created, I have a choice of using malloc(3)---for example when the recipient expects to use free(3)---or to pass in a compatible Scheme object and rely on Guile's gc. Does (make-cdata my-struct) create such a compatible Scheme object for the latter case?
<lilyp>lshoravi: try running your program in gdb. Typically, that's `gdb --args guile your-program.scm arguments to your program`
<lshoravi>lilyp: thanks, that gets me to the breakpoint. The frames are all ?? inside libgtk4. It appears the symbol tables are missing.
<ttz>Why does ((lambda (x) x) (values 1 2)) returns 1 while ((lambda (x y) x) (values 1 2)) returns an error?
<ttz>Why do we need call-with-values to pass multiple values around?
<ttz>Finally, can I rely on the fact that ((lambda (x) x) (values 1 2)) returns 1 or is there some context in which this will cause an error?
<ieure>ttz, ((lambda (x y) x) (values 1 2)) returns an error because it takes two arguments, and you gave it one.
<ieure>call-with-values is needed to handle (values ), because this is a feature that was added to Lisps after the initial language was designed, so it doesn't integrate super well.
<ieure>"can I rely on the fact that ((lambda (x) x) (values 1 2)) returns 1" - no, because it doesn't return 1, it returns multiple values, the first of which is 1.
<lilyp>ieure: uhm:
<lilyp>(let (((values . x) ((lambda (x) x) (values 1 2)))) x)
<lilyp>$1 = (1)
<ieure>lilyp, I get "let: bad let in form" when evaluating that.
<lilyp>(use-modules (srfi srfi-71)) 🙂
<ieure>lilyp, Nice, I had no idea. Haven't needed to deal with multiple values in Scheme yet, but nice that there's a more convenient facility for it.
<ttz>ieure: I know how to use call-with-values
<ttz>My issue here is rather to understand the asymmetry of these examples
<ttz>And ((lambda (x) x) (values 1 2)) does return 1
<lilyp>(values 1 2) is a single argument
<lilyp>any value but the first is discarded if not in a multi-value context
<ttz>okay, so 2 is never passed to my lambda
<lilyp>hence why you need things like call-with-values, receive, or srfi 71 let to deal with them
<lilyp>yes
<ttz>but then why isn't ((lambda (x y) x) ...) a multi-value context?
<ieure>ttz, Multiple values are like lists with some magic. Stuff that knows about multiple values can use any/all of them, things that don't only see the first value. Which allows you to have optional behavior without breaking existing stuff.
<ArneBab>note that multiple values sent to a standard function cause some schemes to break.
<lshoravi>Running guix, how do I get debug info for gtk? guix install gtk:debug says that there is no debug output for gtk :(
<lilyp>lshoravi: you can always use --with-debug-info=<package>
<ttz>Okay, so a context taking multiple values e.g. ((lambda (x y) ...) ...) is not a multi-value context?
<ttz>And the only way to create such a context is using call-with-values?
<ieure>ttz, You're confusing multiple values with arguments. That function takes two arguments. The arguments may or may not themselves be multi-valued.
<ttz>Well I was talking about the continuation
<ttz>Doesn't it take two arguments in my example?
<ieure>Yes, it takes two arguments. This is orthogonal to multi-values.
<dsmith>Aren't continuations defined to be single values in the specs?
<ieure>That I do not know.
<dsmith>ISTR someone in #scheme mentioning it
<ttz>Is there a good reason why multiple values cannot simply be passed to continuation taking multiple arguments?
<lilyp>continuations *can* be multi-valued, but that's opening another can of worms
<ttz>In a language without currying, can we do without multi-valued continuations?
<lilyp>the reason is, informally, that (x (y) (z)) will always call x with two arguments, regardless of your implementations of y and z
<lilyp>this is the correct thing to do assuming that x only takes two arguments
<ttz>I think I struggle understanding how are multiple values implemented...
<lilyp>deep C magic
<ttz>ahah not the answer I would have hoped for
<lilyp>if you care about the high level stuff, read https://srfi.schemers.org/srfi-210/srfi-210.html – in particular, the rationale and its links
<ttz>Is Guile following https://legacy.cs.indiana.edu/~dyb/pubs/mrvs.pdf ?
<lilyp>long story short, "Scheme's application syntax does not deal directly with operands returning multiple values"
<ieure>Right... (values ) returns a special structure that contains multiple values.
<ieure>Things that are multi-value aware can use all the values; things that aren't only see the first value.
<dthompson>this is a nit but it doesn't return a structure
<ieure>Sure, it's, I don't know what the internal stuff looks like. Stack-allocated, probably.
<ieure>The point is that thinking of them as a list of values is closer to the reality of things than thinking them of multiple arguments to a function.
<dthompson>yeah
<ttz>Then why doesn't this work:
<lilyp>a *hidden* list of values, that is
<ttz>((lambda (x) (call-with-values (lambda _ x) (lambda (x y) y))) (values 1 2))
<dthompson>(lambda (x y) y) takes 2 args and you only send one
<ttz>well it was supposed to be the multiple values
<ttz>so it cannot be passed around like lists
<dthompson>the producer procedure only produces 1 value: (lambda _ x)
<dthompson>they are indeed not lists
<rlb>I was under the impression that values could even be placed in registers if the implementation wants to for given call sites.
<ttz>gosh... it seems to me it would be clearer to always fail upon receiving unexpected multiple values.
<dthompson>it's a choice that could be made. both approaches have trade offs.
<ieure>ttz, A major reason why multi-values work how they do is so that functions *don't* break when given multiple values.
<ieure>This is an explicit goal of the design of the feature, letting code that cares about multi-values do so, and code that doesn't ignore them.
<ieure>vs. if you return a list of N values, *any* caller has to car to get the first value out.
<ttz>okay, thanks I gathered some interesting thoughts, thanks for the pointer lilyp
<ttz>ieure: from Dybvig's paper
<ttz>"Another approach is to ignore extra values but signal an error when no values
<ttz>are received. We feel that either approach tends to mask pro- gramming errors
<ttz>without adding significantly to the flexi- bility of the language. Thus, we have
<ttz>chosen to signal an error both when no values are received and when more than
<ttz>one value is received by a continuation expecting a single value."
<ttz>I found no mention of " A major reason why multi-values work how they do is so that functions *don't* break when given multiple value"
<dthompson>that paper describes chez scheme's choices, not guile's
<ttz>Sure, I get that. But I cannot find any explicit implementation choice in the Guile Reference Manual, so I don't know what ieure was referring to.
<dsmith>I remember wingo writing somehing. Can't find it in the wingolog. Might have been on the mailing list. It's was about stack frames and how values are handled
<mwette>lechner: if you get a pointer you should use make-cdata with the pointer type : (make-cdata foo_t* <pointer-val>)
<dsmith>Maybe it was this I was remembering (which doesn't mention values at all): https://wingolog.org/archives/2010/02/26/guile-and-delimited-continuations
<mwette>I'll expose (make-cdata/* foo_t <pointer-val>) next round
<dsmith>Ah, I think this was it: https://wingolog.org/archives/2013/11/26/a-register-vm-for-guile
<dsmith>"The calling function knows how many values are returned by looking at the SP. There are convenience instructions for returning and receiving a single value. Multiple values can be returned on the stack easily and efficiently."
<mwette>It has always seemed odd to me that call-with-values and values are procedures and not syntax.
<dsmith>Yeah, the whole business seems very un-schemey
<mwette>Well I was wondering how a compiler knows that these are procedures to be treated differently than others.
<ttz>Actually the continuation ((lambda (x y) x) ...) takes only one argument and will just raise an error upon being called. So I understand better the asymmetric behaviors of ((lambda (x) x) (values 1 2)) and ((lambda (x y) x) (values 1 2)).
<ttz>(values obj ...) is actually simply defined as "deliverers all its arguments to its continuation" in the R7RS.
<ttz>So the only way to create multi-argument continuations is to use call-with-values.
<ttz>Now I am wondering why the number of arguments a continuation take cannot be evaluated w.r.t to its call-site, which would avoid the need for call-with-values.
<lechner>mwette / i don't need make-cdata/* because FFI generated pointer types
<lechner>Hi, is there an easier way to malloc copy a string? https://bpa.st/L5AA
<mwette>you could use strdup()
<daviid>ttz: (ice-9 receive), a syntax that expand to a call-with-values expression, and there is let-values (srfi-11)
<ttz>thanks daviid but this doesn't really answers the question of why can't a continuation take the same number of arguments as required by its call-site
<mwette>ttz: ((lambda args (if (positive? (length args)) (car args))) (values 1 2))
<mwette>thought, I'm not sure what you are trying to accomplish
<mwette>s/thought/though/
<mwette>The `fold-values' procedure in sxml/fold.scm is an example of procedure using unknown number of values passed to it's continuation.
<ttz>I am just trying to understand
<ttz>Your snippet of code is really interesting
<ttz>so when using an unspecified number of arguments in a procedure, the continuation resulting in its application takes more than one parameter?
<ttz>ah no my bad
<lshoravi>daviid: have you experienced segfaults in g-golf binding widget instances at the top level? for example (define xyz (make <gtk-box>))
<lshoravi>having a hard time debugging it
<lechner>mwette / (cdata& ...) is amazing! especially when used twice like this (cdata& (cdata& ...)). Not even C can do that
<daviid>lshoravi: please paste a smal test snipset i can look at, thans
<daviid>lshoravi: it's liely because you do not initialize gtk - make sure to (gi-import-by-name "Gtk" "init") and call (gtk-init) before you make any instance
<lshoravi>You are correct, this fixed it
<lshoravi>daviid: however, would you expect this to crash?: https://gist.github.com/lshoravi/778aeabfe68f77d320486b9d0d8a525c
<daviid>lshoravi: yes, because you can't instanciate anything prior to call gtk-init
<lshoravi>I thought creating a gtk-application does gtk-init
<daviid>no
<lshoravi>OK - thanks
<daviid>it's a bit confusing actually, but gtk_init() is called in the default handler for the GApplication::startup signal - also, in your exanple, there is no main procedure, so guile rasies an exception, it doesn't segfault
<daviid>actually, let me clarify, it doesn't segfault if you comment the last line - this is because gtk will let you make a <gtk-application>, and call gtk-init if you run the app ... but this example of yours makes the app, doesn call run anc tries to instancitate a gtk-pane .. bang
<daviid>lshoravi: by all mean, you should adopt (mimic) what the hello-world example does (and all examples, including adwaita), that is you should 'fill the app' as part of the activate signal callback code
<daviid>lshoravi: and i am not sure what app you are building, but i highly recommend you look at and use libadwaita, only use gtk(widgets) when there is no libadwaita one ...
<daviid>lshoravi: run and look at all the g-golf adwaita-demo pages, to get an idea, then lok at the code ... i'll help you if needed, let me know
<lshoravi>daviid: Thank you, I will reach out if I get stuck and can't solve it myself
<daviid>lshoravi: welcome - using libadwaita is 'the way to go', don't miss that train :)