IRC channel logs


back to list of logs

***Server sets mode: +ntz
<fnstudio>RhodiumToad: this is a clumsy attempt i just made
<fnstudio>RhodiumToad: i thought of trying boxes, as it felt a bit clearer
<fnstudio>the code above doesn't work though
<fnstudio>i've the feeling i'm missing something important in the way the box is passed around
<RhodiumToad>what's the objective here?
<fnstudio>just a simplified version here, think of user-0 and user-1 exchanging messages over a pipe
<fnstudio>to start with, i'm trying to have user-0 to write onto the pipe
<RhodiumToad>so you want the pipe to be shared between all closures created by (user) ?
<fnstudio>i thought it was good to pass it as an argument instead of using it as a global
<fnstudio>(if passing it as global is even possible)
<RhodiumToad>what result did you expect and what did you get?
<fnstudio>right, good point, sorry :) i was expecting the pipe to start empty but the eventually to contain what written to it by user-0
<fnstudio>i get "Wrong type to apply: #<syntax-transformer set-box!"
<RhodiumToad>what guile version?
<fnstudio>guile (GNU Guile) 3.0.7
<RhodiumToad>that's not what I get
<fnstudio>oh... with the same code?
<fnstudio>oh, it works now
<fnstudio>you're right
<RhodiumToad>yeah, I c+p'd your paste into a file, ran it with (load), got the expected output of one blank line and then "alice"
<fnstudio>ooops sorry for wasting your time, i must have missed something earlier
<RhodiumToad>you don't actually need a box for this
<fnstudio>does it look like a relatively sensible way of doing this?
<fnstudio>ah right, i was going to ask
<RhodiumToad>you can share variables between closures by simply having local variables in an outer scope
<RhodiumToad>e.g. (define user (let ((pipe #f)) (lambda () (let ((name #f)) (lambda args ...)))))
<fnstudio>oh... right... like (let ((pipe ...
<fnstudio>you were faster of course
<RhodiumToad>done like that, "pipe" is shared between all instances of the closure returned by "user", but each one gets its own "user" var
<RhodiumToad>I think this ends up using a variable object under the hood, but I'm not sure of the compiler innards
<fnstudio>ok, something more for me to ponder... :)
<fnstudio>RhodiumToad: that was very useful, thanks! i'm going to experiment with this a bit more
<RhodiumToad>you can also use define-values to share locals between several top-level functions
<RhodiumToad>i.e. (define-values (foo bar) (let (...) (values (lambda () "body of foo" ...) (lambda () "body of bar" ...))))
<fnstudio>RhodiumToad: i suppose the best resources for these things are the docs + the source code + experience? or is there some other guile (or scheme) resource that i should get hold of?
<fnstudio>(source code = guile's interpreter itself, i meant)
<RhodiumToad>for what sort of things?
<fnstudio>some patterns like for my case above, where i could have used boxes, variables, outer-scope local vars, define-values, ...
<fnstudio>maybe it's just a matter of experience
<RhodiumToad>there are examples in the manual in the "About Closure" section
<RhodiumToad>(3.4 The Concept of Closure)
<RhodiumToad>the shared variable example uses separate (define) and (set!) operations to share a variable between two toplevel functions, but using define-values is maybe a bit cleaner
<fnstudio>hm right
***chris is now known as Guest1306
<utkarsh181>Hi! is there a Guile style guide?
<drakonis>regarding a style guide?
<drakonis>you mean for code in the repository?
<drakonis>because otherwise there's no style guide
<utkarsh181>No! I just thinking about how a Scheme programmer would like to indent their code, name global variables, etc.
<drakonis>refer to this then
<drakonis>its up to you though
<utkarsh181>Perfect! short simple and to the point. Thank you,
<daviid>sneek: later tell vijaymarupudi i just pushed a GObject (opque) boxed types auto free mechanism - so you may comment(delete) your *-free calls in these situation, such as you don't need to free gtk-tree-path anymore, it is now done by g-golf when the ffi pointer becomes unreachable ... please test, let me know (devel branch still ...)
<sneek>Will do.
<fnstudio>docs say one should use "set!" to redefine a variable, although i see that using "define" on the same var twice doesn't trigger an error
<fnstudio>so i suppose that's more of a best practice?
<fnstudio>"(define foo 0)(define foo (1+ foo))" also seems to work fine
<fnstudio>but i understand this is better? "(define foo 0)(set! foo (1+ foo))"
<ArneBab>sneek: later tell stis there is now a new section “more 10x advantages” — currently containing your note on named lets and yield it python-on-guile. Thank you!
<sneek>Got it.
<wingo>fnstudio: at the top level, (begin (define x 1) (define x 2) x) is the same as (begin (define x 1) (set! x 2) x)
<wingo>but in a lexical context, (let () (define x 1) (define x 2) x) is an error
<wingo>i.e. a syntax error
<wingo>so, as a general rule, if updating the value of an existing binding is what you want, use set!. if you are at the top level though and you don't know if the value is defined already you can use define, but often not knowing whether an identifier is bound or not indicates that the programmer is not thinking clearly :)
<fnstudio>wingo: i see, yeah, right, i wasn't thinking of lexical contexts
***karlosz_ is now known as karlosz
<ArneBab>wingo: thank you for the details! I tried to answer but didn’t find the distinction.
<fnstudio>i need a list-like data structure that i can pass to a function, the function will return a modified version of the data
<fnstudio>i know i can use "list-set!" to modify the list in place, but i was wondering if it might be cleaner to do it more functionally, just returning a new list instead
<fnstudio>however i was surprised not finding a "list-set", or similar, counterpart that returns a new list
<fnstudio>this not something missing in the language of course, it looks to me as an indication that i'm not fully grasping something
<fnstudio>i thought this could be specific to lists, because of how expensive this operation may be, but vectors seem to behave the same, i can see "vector-set!" but no "vector-set"
<fnstudio>so, in a nutshell, my question would be, why the machinery around these data types would seem to encourage a non-functional approach where things are modified in place
<fnstudio>of course, i suppose i can (deep-)copy the list or the vector and then use "list-set!" or "vector-set!" for a destructive change on the copy, and finally return the modified copy... if that's the recommended way
<lloda>vectors and lists just aren't good for that kind of functional update
<lloda>you cannot do better than copying the full vector for vector-set
<lloda>so it's better to use some other kind of data structure
<tohoyn>It would be quite easy to implement a functional version of list-set!
<lloda>you still have to copy the prefix up to the element you update
<lloda>there is
<lampilelo>for functional vectors
<fnstudio>lloda, tohoyn, lampilelo: very interesting, thank you v much!
<lampilelo>fnstudio: if you want to be functional, do it with a named let and recurse over the list, build a new one and reuse the tail of the old one following the changed value
<fnstudio>lampilelo: ok, thanks, that already sounds better than modifying a list-copy; would it be any faster/better to use a vector (constant time access) instead?
<fnstudio>ok, i think that's actually been answered already
<lampilelo>vectors have a constant time random access, so if you're modifying something in the middle of your data structure it would definitely be faster with vectors, with list you need to follow all of the pointers from the head of the list to the value you want to change
<fnstudio>i will refer to the links above
<fnstudio>lampilelo: ok, got it, thanks
<fnstudio>the most important point here for me was to make sure there was nothing major i was missing
<lampilelo>lol, sorry, you wrote "constant time access", i missed that
<fnstudio>lampilelo: no worries, thanks for helping with this! it's so helpful to have feedback here
<stis>Tja guilers!
<sneek>stis, you have 1 message!
<sneek>stis, ArneBab says: there is now a new section “more 10x advantages” — currently containing your note on named lets and yield it python-on-guile. Thank you!
***chris is now known as Guest1175
***Guest1175 is now known as chrislck
<fnstudio>hi, suppose i have a closure that i can instantiate with "(define user-0 (user))(user 'init "foobar")"
<fnstudio>i'd like to instantiate a small number of users, user-0 user-1 user-2 ...
<fnstudio>how would i approach this if i wanted to do it programmatically
<fnstudio>shall i create a "make-user" function that takes the user name and init value as input?
<RhodiumToad>it makes sense to have the function that returns the closure also do any required initialization, yes
<fnstudio>thanks RhodiumToad!!
<fnstudio>RhodiumToad: hm, nope, i must be missing something, i can create a "user-0" instance but what if i wanted to create "user-0" ... "user-99"?
<fnstudio>i've tried with a "wrapper", a make-user function that takes the name of the variable (e.g. user-0) and the name to initialise the instance with
<fnstudio>but it must be a very naive attempt lol
<RhodiumToad>you want to create them as distinct variables?
<fnstudio>yeah that was the idea
<RhodiumToad>rather than as, say, a vector of users
<fnstudio>that might make much more sense
<fnstudio>ok, let me try that
<fnstudio>(thanks for pointing me in the right direction!)
*RhodiumToad can understand wanting to generate some users with distinct names, but not generic user-NN ones