IRC channel logs
2026-03-19.log
back to list of logs
<jab>I was considering closures...can one think of closures as object oriented programming ? Or is it more broad than that ? <jcowan>jab: Yes. "Closures are poor man's objects, but then again objects are poor man's closures." <jab>jcowan: I guess I was interested in learning about pure functional programming. <jab>it seems streams are an important concept in purely functional programming, at least according to SICP. I'm learning that now. <jcowan>Classic objects don't really fit with FP; the rough equivalent is sum types. <jab>yeah, SICP talks about making a bank account with closures. I'm still trying to figure out how to make a "bank account" program without using set! . <jab>I'll figure it out eventually. <jcowan>Basically thread the account object through your program, but you can't actually hide the fields in it. <jcowan>But doing set! on a local variable is not a Bad Thing <jcowan>local variables are truly hidden <jab>hmmm, I guess I have the notion of wouldn't it be cool to write programs without using any "!". <jcowan>If you make them parameters, you can tail recurse giving the new values, and using a shim procedure that supplies the original values. That is what (let loop ...) is rewritten to. <jab>ok, infinite streams are super cool! with a few lines of code you can define integers. <identity>jab: wait until you see (and understand) McIlroy's Power Serious <jab>you're right. I didn't understand it. :) <identity>jab: you would need to learn Haskell first, or at least an ML-like language <jab>is ML worth learning ? <identity>a programming language that does not change how you think about programming is not worth learning. ML is worth learning <apteryx>is the author of the current srfi-64 implementation in guile around? <identity>in fact, there is a book by the author of The Little Schemer called The Little MLer <jab>also I'm actually shocked. <jab>(stream-car (stream-drop 8 primes)) -> 23 <jab>then when you evaluate primes -> #stream(? ? ? ? ? ? ? 23 ...) <jab>the only value of primes that is known is currently the 8th value. I'm surprised that the earlier values have not been known yet... <identity>jab: it is not the most efficient way, but it should pretty fast unless you do, like, (stream-ref primes 1e9) <jab>that is probably the coolest way to define the prime numbers that I've ever seen. <jab>well actually I didn't know that it was possible to define an infinite series of numbers in code before. That is super cool! <identity>stream/lazy evaluation gives way for some concise definitions, like the Power Serious's definition of the sine and cosine series <jab>well, at the moment I'm still trying to understand how the sieve function filters out the composite numbers, but then I'm still trying to figure out how it's efficient too. <jab>SICP said that recursion is super cool, but the "naive" way to recursively define a function is normally not the most efficient. <jab>the second function defines factorial with 2 functions: factorial and fact-iter. <identity>jab: it is not efficient because it is not tail-recursive. in practice, any decent compiler is going to transform the first version into the second <jab>identity are you saying that the guile compiler is soo smart that the naive version of factorial and the more efficient version...run the same speed on guile ? <jab>that's kind of awesome. <apteryx>should GNU MP be added to the guile package in the guix.scm file at the root of the repo? configure fails without it, unless specified --enable-mini-gmp <identity>jab: assuming a compiler does not make such an optimization, the change in speed for the inefficient version because of the space requirement is likely negligible, but not non-existent <jab>well I guess my un-enlightened brain just sees the prime sieve function as looking like that naive factorial function. and thus slow. <jab>I'll probably end up blogging about this. maybe trying to teach it will make it make more sense for me. <identity>jab: this optimization is called ‹tail-recursion modulo cons›, because it is applicable to tail calls of the form (define (func …) … (cons … (func …)) …) <identity>but you can replace cons with almost any function <jab>yeah...maybe me writing a scheme compiler would help me understand this a bit too. <identity>jab: here is an interesting way to define factorial: (define (interval-list k l) (if (> k l) '() (cons k (interval-list (+ 1 k) l)))) (define (factorial n) (apply * (interval-list 1 n))) <jab>I'm going to have to take some time to digest that... <jab>actually I think guile has a interval-list function... <jab>something like return me a list of numbers 1 - n ... <identity>jab: (define (interval-list k l) (iota l k)) <identity>so that factorial definition is really just (define (factorial k) (iota k 1)) <jab>I actually found out about the iota function, because I started to write APL in guile. <jab>I haven't gotten very far. <jab>but I think there should be a SRFI for APL. <jab>maybe it would be hard to write that in portable scheme. <identity>jab: the interesting part about that factorial definition is that it runs in more-or-less the same time as (define (factorial k) (if (zero? k) k (* k (factorial (- k 1))))), despite the fact that it allocates memory for the whole list <jab>what are you using the test the speed comparison ? <jab>also, I probably need to go to sleep soon, but this guile chat has been super fun, btw. <jab>hmmm... ",pr (factorial 4)" --> no samples recorded. <jab>interesting. I'll have to play with that. <apteryx>hm, how is the srfi-64-test plugged into the test suite? it looks like it isn't <apteryx>I'd expect something like make check TESTS=tests/srfi-64-test.scm to work <rlb>apteryx: perhaps see the top of ./check-guile if you haven't wrt the last bit. <rlb>...and while I wasn't involved in creating the current srfi-64, I did wire it in to the parallel test harness in main. See c85825328826e2078fe0177e43185e4550d14282. <rlb>And the patches around df04f5357a0c7146d7ec1c4fcd8c11a42feb5e01 show how we switched to the parallel test harness a bit back. <apteryx>so all files ending by .scm .sr64 or .test are ran a Scheme tests (using the scheme test driver) ? <rlb>To run during make check, they also have to be listed in TESTS in the relevant Makefile.am. <rlb>see info autoconf for a lot more about that. <apteryx>should srfi-64-test.scm be added to SCM_TESTS ? <rlb>(the patches also show how some of that is done) <rlb>Sorry, guile-suite tests end in .test, not .scm. <apteryx>in Guix we have TESTS = $(SCM_TESTS) $(SH_TESTS) <rlb>While I don't know I assume that srfi-64-test.scm is "something else". <apteryx>that makes it possible to run a single scheme test via its file name like 'make check TESTS=tests/some-test.scm' <rlb>Oh, right, it's just included by srfi-64.test. <apteryx>I see; so it's already "registered" or at least part of the normal test suite <rlb>guile's test suite was originally completely custom (check-guile, test-suite/test-suite/, etc.), now that custom harness can also be driven by automake's parallel harness. <rlb>(and can handle srfi-64 too) <apteryx>good, I see that 'make check' alone picks tests/srfi-64.test. It's a bit odd that a failure (caused by a local change) is then reported as FAIL: tests/srfi-64-test.scm <rlb>(you can also run the tests from test-suite via "make tests/something.log" if the log doesn't exist) <apteryx>or can I select it via the TESTS environment variable? <apteryx>I can use 'make recheck' for now, but I'm still curious to know how to use TESTS with the Guile test suite. <rlb>The supported way is just ./check-guile ... <rlb>Read the top of ./check gule <apteryx>I see: Usage: check-guile [-i GUILE] [--] [TEST...] <rlb>Oh, sorry, I thought you were looking at main. <rlb>It's better documented now I think. <rlb>fsvo "better documented" <apteryx>I was reading ./check-guile --help from main yes <rlb>No, the comments at the top of the file. <apteryx>OK, so './check-guile srfi-64.test' should do it <rlb>(I don't recall offhand if there's an easy way to use TESTS to do the same thing with our arrangement.) <apteryx>thanks. Would be nice to have this plugged these tests in TESTS as standard in Automake as well (info "(automake) Overview of Custom Test Drivers Support") <apteryx>would be nice to have these tests registered in TESTS* <rlb>I suspect our recursive make arrangement might make it harder. <rlb>They are all in TESTS already. <rlb>See test-suite/Makefile.am, depending on what you mean. <apteryx>oh, right. So it should be possible to use TESTS; I think there must be a way to list tests as well but I don't know how. <rlb>Looks like this will do it <rlb>make -C test-suite check SUBDIRS= TESTS=tests/srfi-9.test <rlb>But ./check-guile srfi-9.test is a lot simpler, and likely to keep working as-is indefinitely. <rlb>i.e. it's the "supported way" atm <apteryx>Interesting; it's not too far from being usable, but I wonder why we havve to override SUBDIRS this way <apteryx>I'll use check-guile for now, thank you. <rlb>It'll run the standalone tests too. <rlb>Because we have more than one "test suite" <rlb>They're handled via the "SUBDIRS = standalone" in test-suite/Makefile.am, so you have to "turn that off", but that's also likely fragile. <apteryx>I see; it'd be nice that over time the test suites coalesce into a single one <rlb>The standalone tests also use TESTS, but in the subdir --- I don't know that the automake test harness has a way to use TESTS for selectivity across recursive make directories... <apteryx>I don't think so, but the relative file name can be used in these cases <apteryx>e.g. make check TESTS=tests/some-level-down/my-test.scm <apteryx>not very elegant but easy to reason with <rlb>Oh, the automake docs even talk about overriding SUBDIRS, so maybe that's "fine". <rlb>(or rather, expected) <apteryx>and in Guix we have a "fancy" test driver for Scheme that can select/deselect tests based on regexps, e.g.: make check TESTS=tests/packages.scm SCM_LOG_DRIVER_FLAGS='--select=^fold-packages' <apteryx>this selects tests whose names start with 'fold-packages' in a given SRFI 64 test file, in this case tests/packages.scm <rlb>I'm just glad we got the parallel harness working --- much faster testing (if you have multiple cores). <apteryx>yes, that's great improvement, thanks for working on it! <rlb>got tired of waiting :) <apteryx>In procedure simple-format: FORMAT: Unsupported format option ~x - use (ice-9 format) instead <apteryx>./check-guile srfi-207.test passes though, so that's odd <apteryx>I've tested it fixes the test-driver.scm in guix when using --select=something <identity>rogerfarrell: wdym? just do (match variable …) ? <rogerfarrell>Yes. I was going off the docs. I actually want to match anything but a variable. <old>rogerfarrell: I guess you are talking about syntax-case here and not match ? <old>not sure what you actually want here wrt to bound value <rogerfarrell>Supposing I have variable lst. How could I define a pattern that matches anything but the contents of another variable, say smbl = "word"? <identity>so you want the pattern to match if (not (equal? (car lst) smbl))? <old>I don't think you can with current match AFAIK <rogerfarrell>Good. That makes me feel slightly more literate. The manual section on pattern matching is a little dense for a beginner. <identity>(and (? symbol?) (? (lambda (x) (not (symbol=? x symbol))))) is definitely one way <identity>or i guess (not (? (lambda (x) (eq? x symbol)))) <rogerfarrell>Is that intuitive to you? I am still getting comfortable with the language, so I sometimes have trouble knowing what is ledgible syntax for more experienced eyes. (Think Haskell.) <identity>or, if it the first element of a list, (not `(,symbol . _)) should work <identity>rogerfarrell: sure, just knowing that you can use the usual logical operators in patterns and inject your own predicates takes you a long way, even if it is not the “best” way to construct the patterns <identity>or did you mean if the specification for the matcher in the manual is intuitive? <rogerfarrell>Your last suggestion is nice! I am mentally expanding it against the manual. <identity>it might take some time to get used to, but the DSL is pretty simple, all things considered <rogerfarrell>Thanks for the recommendations! I am playing with it now. <rlb>apteryx: wrt that change, and only from a cursory glance, I don't know enough about what srfi-64 requires to know if that'd be OK, i.e. whether it's OK depends on whether the skip count should only count intentionally skipped tests. The srfi-64.scm author might know (Tomas Volf). <rlb>apteryx: and right, the ./check-guile crash looks like a bug to me. <rlb>(I might poke at it later.) <rlb>apteryx: was just a missing use (ice-9 format). I'll fix it, and thanks for reporting it. <old>rlb: from my reading of the spec, SRFI-64 is not clear on wether skip should count or not. I think it should <rlb>I don't have an opinion either way atm --- haven't read srfi-64 closely enough on that front. <mwette>(define-syntax match-no-word (syntax-rules (word) ((_ any) any)))