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>note that this is not in guile <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 <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 <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. <lilyp>I think chickadee is actually guile-chickadee in Guix because of some reasons <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. <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) ? <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>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>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>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 <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>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? <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>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 <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? <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 <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>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. ;) <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! <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. <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" <mwette>(let loop () (cond (#t => (lambda (v) (loop))) (else #f))) is TCO wrt (loop), I believe. Is that right? <lilyp>but yeah, it should run infinitely without consuming stack