IRC channel logs

2023-01-07.log

back to list of logs

<old>stis: What is the proposed interface for one-shot continuation?
<old>Something arounds abort-to-prompt?
<stis>its different, perhaps this is the best link, http://itampe.com/one-shot-continuations.html
<stis>note that this is not in guile
<stis>my mod of it ...
<stis>old ^^
<old>When capturing continuation with abort-to-prompt, a copy of the whole stack is made?
<old>My experience with delimited continuations is with userspace threads in guile-parallel btw
<old>I though that delimited continuation was just some magic around longjmp/setjmp
<mfiano>When I should use `inputs` or `propagated-inputs` when packaging pure guile-only code?
<mfiano>I'm not seeing any clear pattern when looking around at different guile libraries. From example, dthompson's Chickadee puts guile itself in propagated-inputs, but his Haunt puts guile in inputs.
<lilyp>mfiano: that depends on whether you fancy your code as an application or a library
<mfiano>Hmm, ok.
<lilyp>if it's a library, you need to propagate every guile-* (though ideally not guile itself)
<lilyp>if it's an application, you should instead simply wrap the binary
<lilyp>"binary"
<mfiano>Should I name my library guile-*? I don't see this done often, or at least in the peoples' repositories I've been looking at.
<lilyp>you should prefix it with guile- when packaging it for Guix if it doesn't have that prefix normally
<lilyp>as upstream, you're free to decide for yourself
<mfiano>Ok, becuase "chickadee" comes to mind off the top of my head, as a game engine intended to be used as a library for game applications, but exists in guix as "chickadee", unless I'm just mis-remembering.
<mfiano>ACTION goes to check
<lilyp>I think chickadee is actually guile-chickadee in Guix because of some reasons
<mfiano> https://git.dthompson.us/chickadee.git/tree/guix.scm#n124
<lilyp>It does hold for Tsukundere
<mfiano>Ok, well good information to know, regardless. Thank you.
<lilyp>Where my (developer's) intuition is that I fixed the load path through the command line utility and use a different escape hatch to modify it
<mfiano>Yeah that's similar to what I'm doing.
<lilyp>In that case mfianos-thing is as valid a name as guile-mfianos-thing imo.
<mfiano>It's mostly set up the way I want it. What I'm doing is also setting up different development entry points, for example, if guix suddenly stops working or requires me to run some maintenance I can't be bothered with at that specific time.
<lilyp>you got an example to share?
<mfiano>Not yet, but I'm essentially using direnv to run `guix shell` when I cd into a project, but I also have wrapper scripts for starting guile for a specific project by modifying the load path. Additionally, I also have simple independent shebang scripts.
<mfiano>Basically, for libraries my primary development entry point is cd-ing into the directory to set up the environment for guile, however it may be invoked, through vim or geiser/emacs or whatnot, and the fallback entry point is my wrapper script. And for applications, it's cd-ing with guix as per above with the same fallback method, or for simpler one-off things, just shebang scripts that don't depend
<mfiano>on anything and set up their own %load-path as needed.
<mfiano>I'm weird. I have wasted a lot of time over time years because something or another broke in the middle of a work day. I guess I care about this stuff being set up a lot before getting in the weeds of developing.
<mfiano>over the*
<lilyp>Call me old-fashioned, but I never had this class of problems through the act of not using direnv.
<mfiano>The first blog article I write, when I get the time, is going to be explaining what I did in every detail, because as someone mentioned the other day, there isn't much onboarding documentation available and I would like to help out in every way I can.
<lilyp>Usually, I either guix shell -Df guix.scm or guix shell -m manifest.scm and be done :)
<mfiano>lilyp: Oh, the direnv is just to do that exact thing automatically. I could very well do without direnv at the cost of running that myself. The rest of my setup is orthogonal to that though.
<mfiano>Does anyone know if guile/scheme has something like CL's destructuring-bind?
<mfiano>I know there is the match module, but just for working with arbitrary tree structures, I think such a thing is useful.
<lilyp>mfiano you probably want match, it has the $ and = bindings for records
<mfiano>in this case I just want to bind a couple of the (program-arguments)
<mfiano>I will have to learn match then.
<lilyp>oh, for program arguments there's getopt and some srfi (i think it was 37?)
<mfiano>Do you mean (ice-9 getopt-long) ?
<lilyp>yup
<mfiano>Ok reading, thanks.
<lilyp>the other is args-fold
<mfiano>Yes, found it, thanks again.
<mfiano>Ok, I see. getopt is more declarative and srfi-37 is more functional, and also more flexible lifting some restrictions of the getopt parser. In this case, getopt is more than enough. Nice to know there is something else available though.
<lilyp>srfi 37 gives you some of those python tricks but yeah, most often getopt's the one you want
<ArneBab>mfiano: chickadee is both a runtime to run games written in chickadee and a library to use in games, so it needs guile propagated.
<mfiano>Aha
<mfiano>Ok, getopt-long cannot be used for what I want.
<mfiano>"getopt-long splits a given command line into several pieces. All elements of the argument list are classified to be either options or normal arguments."
<mfiano>An option is anything that begins with "-" or "--".
<mfiano>I simply want to parser arguments, not options.
<mfiano>parse*
<mfiano>I guess I can change my interface to use required options with values.
<mfiano>Is there a place in the documentation that talks about how to handle bad exit codes in the middle of a procedure that makes system or system* calls?
<mfiano>Or any good resources otherwise for writing "shell" scripts in guile to handle these things idiomatically instead of the ugly bash way
<lilyp>you could use guix' invoke, but the exit code is returned by system, so you can make decisions based on that
<mfiano>Hmm
<mfiano>How do I redirect any stderr output from a `system*` call to nowhere?
<lilyp>that one's a bit tricky, you have to do the same thing as in C
<mfiano>Oh I don't know C
<lilyp>hmm, you might try open-pipe[*] from ice-9 popen, IIUC it assigns /dev/null to the file descriptors, which is what you want to do
<mfiano>Checking, thanks.
<mfiano>lilyp: I didn't have any luck. It was still binding the current-error-port because it is inherited. But this worked for me:
<mfiano>(with-error-to-port (%make-void-port OPEN_WRITE) (lambda () (zero? (system* "cmd" "that" "could" "fail"))))
<mfiano>Transducers just made it near the top of my favorite Guile features list, particularly the guile-specific transducers. Finally, a Common Lisp SERIES implementation that is actually intuitive to use and composes well with the rest of the language.
<ArneBab>mfiano: I am too lazy … I often just use member …
<ArneBab>(define (main args) (when (member "--foo" args) …))
<mwette>epony: my fav' Scheme features are named-let and define-syntax (i.e., macros); I use named-let w/ cond a lot
<stis>++ yes named let is one of the most ignores functional super powers in lagugaes claiming to support functional programming
<old>How does one use the foreign interface with C type time_t ?
<old>Do you assume time_t to be uint64_t on a x86-64 system? How would you make this portable for 32 bits systems?
<mwette>old: time_t seems to be non-portable. It may be signed, also. I found this: https://stackoverflow.com/questions/471248/what-is-time-t-ultimately-a-typedef-to
<old>Unix and POSIX-compliant systems implement the time_t type as a signed integer is good enough
<old>don't care about system that don't respect POSIX
<old>I guess I could do something like this: (define time_t (case ((@ (system base target) target-word-size)) ((8) (@ (system foreign) int64)) ((4) (@ (system foreign) int32))))
<old>But since it's from the kernel header file, I guess this is don't even portable
<old>s/don't/not
<old>I guess that using int64 is safe for most systems
<mwette>if you are just passing around a pointer then 8 bytes can't break, I would think
<mwette>(pointer to the time_t value)
<old>right but the deference could
<old>if it's not the right size
<old>but I think that the glibc wrapper make its that time_t is always 64 bits even with a 32 bits kernel. I could be wrong
<old>anyway, I will try with int64 :)
<mwette>right, if you are putting in a struct
<a12l>I'm trying to implement binary search in Guile as an exercise. The function / returns a rational number when running (/ 3 2), but I need an integer to be used as an index for picking the middle element in the (sub)array.
<a12l>Is there an integer division function implemented as part of the std, or should I round the rational number that I get myself?
<Aurora_v_kosmose>euclidean/ ?
<Aurora_v_kosmose>It's documented in (info "(guile) Arithmetic")
<Aurora_v_kosmose>a12l: ^
<daviid>old: sizeof should correctly answer, no?
<daviid>old: ah, not defined in guile, i see the config.h[.in] in guile does the check, fwiw
<mwette>maybe you're looking for quotient and remainder
<a12l>Aurora_v_kosmose: Thanks! I'm reading the documentation for them
<a12l>mwette: The `euclidean-quotient` procedure seems to be what I'm looking for
<old>a12l: You can use bitwise shift also
<a12l>old: Feels that would reduce readability? Depends very much on who's reading the code and what they're used to, but I at least would be very confused if you did a bitwise operation in an otherwise "high-level function"
<a12l>(I associate bitwise operations with low-level code there you need to write specific bits to registers etc.)
<a12l>Is a named let expression a good solution when implementing binary search? Trying to think of a nice way to get the recursive call at the end of the procedure, when what you're going to do have more than two "branches".
<a12l>I.e. (1) the value at index n is the value you're looking for; (2) the value at index n is bigger than the value you're looking for; or (3) the value at index n is smaller than the value you're looking for.
<a12l>Because from what I've understood, if I've a recursive call in two conditions in a (cond ...) expression, Guile can't do TCO?
<old>a12l: In C it's very common to do such optimization, except when usin literal where the compiler should be able to optimize itself
<daviid>old: is this desktop 'tower' using gdm?
<old>Look at srfi-43, there's a vectore binary search I think
<old>daviid: Oops wrong channel :p
<old>but yes it uses gdm
<a12l>old: Guess that I haven't done enough programming in C then :)
<old>looking a vector-binary-search in srfi-43
<old>I see that it uses (quotient (+ lo hi) 2)
<a12l>Looking at it also
<a12l>Hmm, it looks like it have two different calls to loop in it.
<a12l>It Guile still able to do TCO?
<mwette>If you have multiple tail calls within a cond in a named-let those are TCO if I understand what you're asking. Read section called "Proper Tail Recursion" in the R5RS .
<a12l>And that's the convention with variables that begins with %?
<a12l>mwette: Thanks! I found the line "cond — last expression in each clause, and the call to a => procedure is a tail call" in § 3.3.2 Tail calls in the ref. manual
<a12l>Didn't know that cond was a special case, thought that the rules for let applied in this case.
<a12l>But I'll read the SRFI also :)
<antipode>a12l: Tail calling is a requirement of the Scheme language; it is independent of naming.
<antipode>Renaming variables doesn't impact TCO, AFAIK.
<a12l>antipode: The ref. manual specify that only the last expression in a procedure or a `let`-expression can be TCO'ed, so I thought that only the last expression in the last cond- condition could be TCO'ed.
<a12l>But when I revisited the section in the ref. manual I discovered that if you use cond, the last expression in each condition can be TCO'ed; even if the cond-expression is in a procedure or in a let-expression :)
<a12l>Or maybe we talk besides each other?
<antipode>a12l: I forgot what the manual says, but all last expressions in a 'cond' clause are TCO. It doesn't matter if its the first clause or the last.
<antipode>I don't see what this has to do with "And that's the convention with variables that begins with %?" though.
<antipode>-- Guile's compiler, expander and optimiser, and the Scheme standards, don't care about naming conventions.
<a12l>Nothing, just that when I read Gule's implementation of vector-binary-search (from SRFI-43) it's using a variable named %vector-binary-search, and I've seen other variable identifiers prefixed with %, so I wondered what it meant/how it's usually used. ;)
<a12l>:)*
<mwette>guile uses %var for globals; sometimes *var* is used
<antipode>stis: Do you have a link to the implementation of 'one-shot continuations'? In the blog post, I see an example of how to use them, but no link to your modifications to Guile.
<mfiano>%name is used to name some procedures too
<a12l>mwette: Thanks for the explanation!
<mfiano>Some even public
<antipode>a12l: it varies, sometimes I use '%procedure' for ‘raw’ procedures wrapped by something else, for example to implement 'smart constructors' as they are named in Haskell.
<mfiano>I just used %make-void-port from (ice-9 popen) today.
<a12l>Thanks
<stis>mwette: I have a branch to guile git repo. Shall I try to publish that? what's the best way?
<mwette>stis: you git format-patch and submit to bug-guile@gnu.org and/or attach to email to guile-devel@gnu.org
<stis>hmm which is main? master?
<stis>hmm it's main ... how do I format patch between branches? diff works?
<stis>mwette: I sent a patch file to guile-devel
<mwette>If you modify, better to generate a branch and work on that. I'm not expert in git. You'll have to read manual pages.
<stis>I work on a branch called stis
<mwette>between branches I figure out what the commit # is on the other branch. There may be a better way but I don't know it.
<lilyp>a12l: % means "implementation detail, touch with care"
<Aurora_v_kosmose>ah
<mwette>(let loop () (cond (#t => (lambda (v) (loop))) (else #f))) is TCO wrt (loop), I believe. Is that right?
<lilyp>looks cursed
<lilyp>but yeah, it should run infinitely without consuming stack