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>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 <lechner>ArneBab / i have to say sorry for being too pedantic. apparently sneek uses levenshtein distance of at least 1! <dsmith>Can I nerd snipe anyone into rewriting that with match? <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>where `int rl_tty_set_echoing (int);' <mwette>lecher: guile's `getpass' seems to support readline already <lechner>Hi, what happens to read-line when confronted with an impossibly large number of input characters, please? <dsmith>Heh along with two implementaions in Scheme (Gauche and PLT) <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 <lilyp>mwette: the code increases in complexity if you call edits "levenshtein" <mwette>guile-readline calls readline. the buffer overflow would happen in libreadline, I think. I wonder what it's behavior is. <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>(let (((values . x) ((lambda (x) x) (values 1 2)))) x) <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 <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? <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... <ttz>ahah not the answer I would have hoped for <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. <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) <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>) <mwette>I'll expose (make-cdata/* foo_t <pointer-val>) next round <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 <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>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? <lshoravi>daviid: have you experienced segfaults in g-golf binding widget instances at the top level? for example (define xyz (make <gtk-box>)) <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 <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>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 :)