IRC channel logs

2023-09-09.log

back to list of logs

<apteryx>how do I create some SCM number object in C?
<apteryx>I tried: scm_simple_format (fd, scm_from_latin1_string (";;; depth is ~S\n"), scm_from_int (12)) but I get: "simple-format" "FORMAT: Missing argument for ~~~A" (#\S) #f
<apteryx>ah, it want args, a list
<apteryx>yep, that was it
<mwette>apteryx: you mean like this: scm_from_int(5)
<mwette>yeah, list
<apteryx>yes (I'm using the GNU C code style that is used in the Guile code base)
<mwette>right; if you are working on the dependency stuff I have a small program that generates a dictionary of direct module dependencies for all gnu/packages
<apteryx>that's nice! for what I'm trying to debug (gnu packages cross-base), it seems the dependencies are indirect though
<apteryx>any idea what that migth mean? Wrong number of arguments to #<boot-closure 7f7990640260 (_ _)>
<apteryx>what is boot-closure?
<graywolf>Is there some pattern to do sequential operations on some object? I am curretly using let* and just re-assigning the same variable over and over, but I am curious if there is a better way. Technically I could just nest it, but that does not look that readable.
<mwette>graywolf: maybe (fold apply obj (list proc1 proc2 ...)), or the `compose' procedure, or transducers (srfi-171)
<graywolf>mwette: Will check that out, thanks for the tips :)
<mwette>apteryx: yup, you'd need an algorithm to iterate on that dict
<apteryx>interesting, arity = scm_procedure_minimum_arity (hook); doesn't work in load.c
<apteryx>it produces arity=(0 0 #t)
<apteryx>I'll try the catch and fallback strategy instead
<apteryx>how do I define a thunk in C?
<apteryx>I'm trynig to use scm_catch
<apteryx>or associated more general question: how do I define a Scheme procedure from C?
<rlb>scm_c_define_gsubr or similar?
<rlb>If you mean anonymous, then scm_c_make_gsubr?
<apteryx>thanks
<rlb>Maybe -- just off the top of my head.
<apteryx>it's funny the only references on the net are in the Guile Manual
<apteryx>^^'
<rlb>If you search the info pages (via repeated C-s in the console browser), you'll see all kinds of relevant bits.
<apteryx>yep, that's my tool of choice, but it's a reference, is often short of examples
<rlb>Wrt references, I think that may not be uncommon for guile atm.
<rlb>Also "git grep" on the guile source can help, once you get used to the code.
<apteryx>rlb: you can access functions by their index in the manual by pressing 'i', that's a nifty feature
<apteryx>(info manual)
<rlb>Yet another thing that by now I ought to know :)
<rlb>Thanks.
<apteryx>:-)
<rlb>(I mean really, how am I still not using the emacs info mode by default...)
<rlb>...habits?
<apteryx>'C-h i m Guile R RET'
<apteryx>(for your next habit ;-))
<rlb>mwette: ok, rebase worked fine. I'll push an update to the utf8 branch later tonight or tommorrow that should fix your current problem. (And I backed off the optimization -- wasn't as obviously an improvement as I'd thought (vs complexity, etc.).)
<apteryx>I'm getting a warning with the following C code: https://paste.debian.net/1291409/ any idea how how to fix it?
<apteryx>(this code is added to load.c)
<apteryx>maybe it doesn't like me sharing the same data structure object for the body and handler?
<RhodiumToad>the catch handler takes two SCM args after the void*
<RhodiumToad>i.e. SCM handler (void *data, SCM key, SCM args)
<apteryx>ah right, the key and args
<apteryx>thanks!
<mwette>rlb: got it
<RhodiumToad>daviid: no GVariant support yet?
<apteryx>alright, it finally builds, me thinks
<daviid>RhodiumToad: not yet -
<RhodiumToad>bleh. wanted to try out actions, but action values are all GVariant
<apteryx>RhodiumToad: what are you working on?
<daviid>RhodiumToad: as long as you can ignore, it will work, g-golf has a few example of GAction, in the adw1-demo ...
<daviid>RhodiumToad: see examples/adw-1/adw1-demo/window.scm install-actions ...
<daviid>be right back ... a few mins afk ...
<apteryx>I get a single test failure: FAIL: version.test: version reporting works
<apteryx>display the depth works... but it gets out of hand (rather, screen space) quickly: https://paste.debian.net/1291414/
<apteryx>perhaps I should just show the numerical depth value in the first colum
<apteryx>nice thing is that it can be refined without rebuilding via the %load-hook procedure
<apteryx>if you are curious / want to try it out -> https://notabug.org/apteryx/guile/src/load-verbosely-show-depth
<yarl>Hello guile. I am unable to use `geiser-xref-callers/callees`. Does it work for someone?
<apteryx>nope; we should report a bug for it
<apteryx>sneek: later tell yarl nope; we should report a bug for it
<sneek>Will do.
<dsmith>apteryx, Oh wow! That's crazy
<graywolf>Hello :) If I want to be lazy and DRY, I can create a helper macro: (define-macro (git-C . args) `(invoke "git" "-C" out-dir . ,args)). Seems to work. However documentation recommends not to use define-macro, and instead use syntax-rules and syntax-case. Those seems somewhat complex. Could anyone point me to an examples doing similar thing to mine git-C macro, but using those two constructs?
<graywolf>Would like to learn how to write it properly.
<mwette>graywolf: maybe for now (define-syntax-rule (git-C args ...) `(invoke "git" "-C" out-dir args ...))
<mwette>or (define-syntax git-C (syntax-rules () ((_ args ...) `(invoke "git" "-C" out-dir args ...))))
<graywolf>Mm, by understading was that the out-dir would be resolved when the rule was defined, not used.
<graywolf>With this new knowledge, I can switch to it. Will try it, thanks :)
<graywolf>mwette: One more question, the examples in the docs do not use the ` in the syntax-rules, what exactly does it do in this context?
<mwette>The above macro will return a list. Is that what you want? If you want to evaluate `invoke' then leave out the quasiquote.
<lampilelo>graywolf: https://dpaste.com/EEVZYZPZC.txt
<lampilelo>with your define-macro version you could let-bind invoke to e.g. (lambda (. args) (car args)) somewhere higher in the source tree and your git-C would act unexpectedly, but with a hygienic macro this can't happen
<graywolf>lampilelo: Ah, I see. This can get tricky. Thanks for the snippet, will use it (and understand it, need to read up on datum->syntax).
<rlb>graywolf: fwiw, clojure uses dynamic vars for *dir* params in some places, so they're also per-thread, etc. (similar to guile's parameters). But I'm not sure the implicit state in an api is worth it in a lot of cases, i.e. it seems more succinct initially but things rarely stay that simple, and now you have what are effectively hidden args scattered around.
<rlb>Of course, as usual, "it depends".
<mwette> https://www.scheme.com/tspl4/ Chapter 8
<graywolf>I agree. In this case it is a CLI script that mostly calls git bunch of times, so I want to make it more succinct, albeit at the cost of being a bit magical.
<graywolf>I did read about the guile's parameters, but have yet to find a nice usecase where I would prefer it over passing the arg explicitely
<graywolf>Any examples? :)
<rlb>One alternative can be to just capture the args locally, i.e. just bind (partial invoke "git" "-C" out-dir) and use it in the relevant scope.
<rlb>ACTION thinks guile likely has a "partial" or you could make one. Of course could just use lambda, but that's a bit more verbose unless you use unicode :)
<rlb>Could also trivially create partial: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/partial
<graywolf>ACTION has Hyper+l mapped to geiser-insert-lambda :)
<rlb>ACTION just recently learned about emacs' "TeX" encoding mode and can't believe he didn't already know about it...
<rlb>Where \lamdba automagically transforms :)
<graywolf>So much things to read today :) Glad it's a weekend
<rlb>Mostly what I meant by partial, is I suppose you could cast things more functionally -- away from macros, but not sure what'd be preferable in your situation...
<rlb>graywolf: and also fwiw, here's another take on the clj side for the kind of thing I think you're doing https://github.com/Raynes/conch Though I've generally ended up leaning against the extra dependency (and/or indirection)...
<rlb>It makes it easier to just bind system commands as functions, so similar code effect, but without (iirc) macros.
<graywolf>Will check it. Although would likely prefer to avoid the dependency on anything external for now
<rlb>I just tend to create something more explicit like (ex "git" "-C" ...), and build on that.
<rlb>i.e. build on that via locally bound variants, etc.
<graywolf>I repeat that pattern call like 20 times already, across functions and got tired of writing it out every time
<graywolf>So I wanted to try being lazy :D
<rlb>mwette: fwiw the bug was in fact in list->string (as I think you originally suggested), and the complication was that it was input size dependent, i.e. size had to be over (currently) 1024 chars.
<rlb>(That function is a bit more complex, taking a hybrid approach -- trying to work on the stack up to a point, then moving to the heap, because I think it could be more central for scm code in a utf-8 world, where you generally want to shun string-set!).
<rlb>i.e. it might be one of the more common bulk operators.
<lampilelo>rlb: for partial evaluation, guile has cut from srfi-26
<rlb>lampilelo: right - haven't really used that, and only just now saw that it has <...>, so yeah, thanks -- that'd work just fine.
<rlb>(and unsurprisingly more flexible -- though in clj, if you needed more than partial, you'd probably just use the reader anon-fn shorthand, i.e. #(apply foo %1 bar %&) -- not pretty, but compact...)
<rlb>wingo, civodul: I realized that we might be able to move some of the srfi-13 code to scheme without affecting performance enough to matter, if at all, and it'd be more compact, etc., but when I tried, it failed because (I think) we need those "early" and we never require the module, just rely on the C-only scm_init_srfi_13() in init.c. Does that sound plausible?
<lampilelo>there was a paper about implementing lambda that, when given not enough arguments, will return partially aplied lambda, like in haskell
<lampilelo>i wonder if there are any schemes that do that by default
<rlb>wingo, civodul: ...and if so, any idea offhand, how hard that might be to fix, if we decided we wanted to. i.e. wondered if it were likely a lot more than just figuring out where to put an appropriate "use" in boot-9.scm, or...
<rlb>(I *did* try to hack something in to boot-9 like what we do for ports (the module-use!) but that didn't work -- I forget why offhand.)
<mwette>rlb: following
<rlb>Oh, I think it was maybe exports...
<mwette>rlb: It seemed to me that when there were calls to reverse-list->string with large strings, the initial portion of the returned string was reversed. So, instead of (reverse-list->string '(#\a #\b #\c #\d)) -> "dcba", I'd get "cdba".
<rlb>Yep.
<rlb>...and I fixed it. Cleaning up now to push (along with a number of additional optimizations to other functions -- still working through "avoid repeated string-ref" changes.
<rlb>i.e. I eliminated most of the internal string-set! use, and now working through the less critical string-refs in strings.c srfi-13, etc.
<rlb>mwette: this is the bug, fwiw -- forgot a reverse https://paste.debian.net/hidden/69826389/ Right now that function also handles reversed-string->list, though I've contemplated just splitting then back into independent functions.
<rlb>(and we didn't have a test to cover the larger strings -- plan to fix that too)
<mwette>Also, I checked my nyacc package (maybe ~20 K lines of code): two string-set!'s: one in the pkg itself, and one in the example's. I'm going to to back to see if I can eliminate them.
<rlb>Sounds good -- of course only a problem if the strings are large and/or there are a lot of them...
<rlb>I've been assuming that we'll want to try to make all the relevant bulk converters as efficient as is reasonable, i.e. string-append, list->string, utf8->string, etc. Not sure I'm there yet, but that's the intent.
<rlb>And of course string-map/filter/delete, etc.
<rlb>I think/hope they're all at least plausible now (perf-wise).
<rlb>I've been hitting this (intermittent) error with some frequency now. Do others who run the tests (in parallel?) often?
<rlb>ERROR: asyncs.test: preemption via sigprof - arguments: ((wrong-type-arg #f "Wrong type (expecting ~A): ~S" ("resumable continuation" #<vm-continuation 7f96451ac1d0>) (#<vm-continuation 7f96451ac1d0>)))
<dsmith>graywolf, I have read all the backlog, but do you really need a macro?
<dsmith>A macro is really only needed when you need to extend syntax or not evaluate arguments.
<dsmith>Unless you just want to learn macros...
<graywolf>dsmith: "need" is probably bit strong, but I think it will save some typing and line-length while style being fairly easy to understand (complexity-wise) in this context (small, single-file script).
<graywolf>I want to use whatever the out-dir currently is when I call the function. I could pass it in (repetitive) or use parameters (meh, global variable). I could define a helper closure in each call place (repetitive).
<graywolf>Macro seem like a reasonable way to do it. And the syntax-case from lampilelo should work and allow me to learn more about this part of guile
<graywolf>I mean, this really should have been hacked-together shell script, but I wanted to take it as a learning opportunity, since I am very new to scheme (lisp in general)
<rlb>graywolf: could you not just define your own git-c as a function that refers to an out-dir global var or parameter? (define (git-c . args) (apply invoke ... out-dir args))?
<rlb>Though I imagine there's some reason that's not satisfying.
<dsmith>Yep, what rlb said
<rlb>ACTION added a random string > 4k to the test set, and immediately crashed a test -- fixing...
<graywolf>I am just not big on global variables, but I acknowledge that difference here is quite minor. It would probably be less magical? But more verbose in call places (with-params ... or how is the exact syntax). So macro seemed fine and I wanted to explore a bit :)
<rlb>out-dir is global either way?
<rlb>But either way, by all means -- as an excuse to learn macros better, sure :)
<graywolf>It is not, (define (foo out-dir uri signing-key) ... (git-C "commit" ...))
<graywolf>So they are always scoped to a procedures
<graywolf>That is why I wasn't sure how to write it without define-macro, since the resolution needs to happen in call place
<rlb>Yeah, ok, given what you want, for that I might lean toward the clj *dir* approach, i.e. make out-dir a parameter, and then have a macro helper like (with-out-dir ... . body), but not sure.
<rlb>i.e. https://clojure.github.io/clojure/clojure.java.shell-api.html#clojure.java.shell/with-sh-dir
<rlb>but dunno
<lampilelo>you don't really need macros if you're not creating new syntax, closures are enough for pretty much everything
<graywolf>So more idiomatic way here would be to either: 1. Have a a global parameter for out-dir, git-C as regular procedure that would use it. or 2. Create a closure in each call place (define (git-C . rest) (apply invoke "git" "-C" out-dir rest)) that would capture the current value of the out-dir.
<graywolf>?
<lampilelo>e.g. (define (foo out-dir uri signing-key) (define (git-C . args) (apply invoke "git" "-C" out-dir args)) (git-C "commit" ...))
<lampilelo>ah, you got it yourself
<graywolf>Yeah, that is how I ment the 2. Will likely do it like that, but I will still study on the macros (well, syntax-case), they look fun
<rlb>graywolf: this might be a rough translation of the clj approach in case the ideas are useful: https://paste.debian.net/hidden/35c15224/
<graywolf>Thank you onec more, people here are always nice :)
<rlb>Though I haven't used parameters much, so you'll definitely want to double-check things...
<rlb>I'll also need to make sure that actually has the right binding/scoping/etc. semantics. Was just offhand...
<rlb>(And also, yeah, generally preferable to avoid macros entirely if there's a comparable solution without them...)
<lampilelo>that looks pretty clean too
<dsmith>sneek, macros?
<sneek>macros is http://hipster.home.xs4all.nl/lib/scheme/gauche/define-syntax-primer.txt
<rlb>ACTION may want to consider that further for lokke...
<rlb>(Think that might simplify some things I did a harder way, but not sure...)
<rlb>Not today -- today, more quality time with utf-8 (bugs).
<rlb>...with utf-8, I suspect a "for each" helper that passes both the index and the char might be convenient, i.e. since the traditional string-for-each-index approach is expensive.
<rlb>(for cases where you'd wanted both the index and the char)
<graywolf>Does macro always need to start with the macro identifier? Can I have syntax in the form of (init --> exp ...)? Or can I express only (--> init exp ...)?
<graywolf>(Now I am in pure learning teritory, no longer directly connected to the git-C I was solving before)
<rlb>Macros are expanded top-down, and yeah, have to come first. But you could define -->
<rlb>(too, perhaps?)
<graywolf>Sure, I could, but to what?
<rlb>But you can also play tricks with the reader and/or identifier-syntaxes for some things...
<rlb>Oh, you meant that --> would be the macro, not init.
<rlb>Right, then -- yes, the macro always has to come first, but you can also use a top-level "context" macro to handle everything in the body, e.g. match.
<graywolf>Yeah, e.g. ((fib 10) --> (cut * 2 <>) (cut - 4 <>))
<rlb>(my-special-world ...)
<rlb>And but then that macro has to be able to understand everything in the whole body that you care about.
<graywolf>I see, that sound a bit too invasive, I will just move the --> to the front
<graywolf>:)
<rlb>(e.g. it could move all tthe --> to the front or rewrite them as process--> at the front, or...
<graywolf>I will make a note to look into this later, sounds like it could be of use, but a bit too advanced for me now
<rlb>Basically, once you're in a define-macro or a syntax-case, you can rewrite anything you like (which is incidentally how a good bit of lokke's "compilation" works...)
<mwette>I'm tending to use parameters or atomic-boxes for globals, depending on the context (i.e., per-dynamic-state or shared).
<dsmith>It is possible to make identifier macros (as least I think that's they are called).
<rlb>cf. indentifier-syntax
<dsmith>wingo make load a macro (to assist with source locations) and had to also make it an identifier so you could pass it as an argument (like to apply)
<dsmith>rlb, ya, thanks
<dsmith>Here perhaps? https://git.savannah.gnu.org/cgit/guile.git/tree/module/ice-9/boot-9.scm#n4426 I don't really understand all that. Pretty cool though.
<graywolf>Hm, after all I need some more help :/ Assuming I want to write macro auto-cut, that would be used as (auto-cut (* 2 <>)) , with result behind equivalent to (cut * 2 <>), how can I do so? ((auto-cut what) #'(cut what)) does not work (and I think I understand why), but I have no idea how to do it in a different way...
<rlb>Perhaps something more like (auto-cut (what ...)) => #'(cut what ...), given some assumptions about what you have.
<lampilelo>but mind that (what ...) will also match (), so if you want to force the user to pass at least one argument you'd do (what what* ...) and then #'(cut what what* ...)
<rlb>Oh right, or match () first and issue a (syntax-error ...) or...
<graywolf>behold my masterpiece: paste.debian.net/hidden/2df27a41 :D
<graywolf>I am sure there are bugs. But it is amazing how flexible this "scheme" thing is
<rlb>:)
<rlb>OK, that was a mini-adventure -- after testing some larger random strings, utf-8 port output was failing. Turns out it was because I was splitting across a multi-byte, which the buffering chunks don't care about, but one level up, the code to compute *character* positions (of course) doesn't like split chars at all.
<mwette>rlb: big project -- you're gonna hit those