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 <mwette>apteryx: you mean like this: scm_from_int(5) <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 (_ _)> <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>I'll try the catch and fallback strategy instead <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? <rlb>Maybe -- just off the top of my head. <apteryx>it's funny the only references on the net are in the Guile Manual <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 <rlb>Yet another thing that by now I ought to know :) <rlb>(I mean really, how am I still not using the emacs info mode by default...) <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>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* <apteryx>alright, it finally builds, me thinks <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>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 <yarl>Hello guile. I am unable to use `geiser-xref-callers/callees`. Does it work for someone? <apteryx>sneek: later tell yarl nope; we should report a bug for it <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>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". <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 <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 :) <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 <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.) <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>...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. <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. <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. <lampilelo>e.g. (define (foo out-dir uri signing-key) (define (git-C . args) (apply invoke "git" "-C" out-dir args)) (git-C "commit" ...)) <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 <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...) <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>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 <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) <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>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