IRC channel logs
2023-01-26.log
back to list of logs
<mfiano>TLDR: there was a need for a variation of LGPL for a major Common Lisp vendor, due to fuzziness around what linking entails, so LLGPL was born. <janneke>civodul: it seems sometimes the only way to find such things, is to make a release %-| <civodul>it's not the first time that sort of thing happens to me <civodul>the good news is 'spawn' is still usable, you just have to make sure you don't give it non-file ports :-) <janneke>ACTION experienced something quite similar just yesterday... <janneke>you just found a test was missing... <civodul>the person who writes the bug usually forgets to write the corresponding test <civodul><insert praise of pair programming, peer review, TDD, and all that> <janneke>yeah, most of the time we must help them <janneke>otoh, some try things that "we" would never try, that's a feature too ;) <jpoiret>civodul: oopsie, that also went past me <oenone>I tend to use `cond` in places where I could've just used `if` (when there are only two branches) - should I try to use `if` more often or is this fine? <mfiano>It is more readable to use `if` in this case. <mfiano>It is fine if you are the only one ever reading your code. <oenone>i always think "what if it turns out there are more cases later?" <mfiano>Then you write code that conveys that. <mfiano>I think it's more important to favor the reader of code rather than the writer, especially with my memory as a future reader! That is my opinion though. If you are worried about refactoring time, it is just a tiny bit of elisp to convert an `if` form to a `cond` form. Infact, lispy.el has a binding for this if you don't want to write one yourself. <flatwhatson>cond bodies take multiple expressions, which can be neater than (if x (begin ... <old>mfiano: Are you using lispy with Scheme? <old>I though it was only for lisp <mfiano>I am not, but "Elisp, Clojure, Scheme and Common Lisp are supported." <old>mirai: seems to work yes <lloda>you could do ( ((or '+ '-) (? string? s) ...) ... ) <old>lloda: No need for `.'? <lloda>well . (x ...) is the same as x ... <mirai>I'm thinking on using car or performing map + fold? though maybe there's a more appropriate way? <mfiano>Probably overkill in this case, but you can prevent the intermediary sequence by using transducers (srfi-171 or the guile module which i haven't tried yet). <dadinn>I am looking into the with-exception-handler procedure, and the ways to handle exceptions in Guile. I would like to understand how to achieve a Java-style try-catch-finally structure? <dadinn>I don't see any ways to have a finally block which ensures that certain procedure is always ran, for example to close the open ports in case an exception is thrown during processing the thunk. <dadinn>I've experimented with using dynamic-wind, but that doesn't seem to be the correct way. I've looked at how call-with-port (ice-9 ports) is implemented, and I can see it uses call-with-values, but it feels a bit too low-level :/ <lilyp>dadinn: java's finally blocks are called at the end of the catch, so it's basically equivalent to (define (finally ...) ...) (catch whatever your-proc (lambda error (handle-error error)(finally ...))) <lilyp>call-with-port actually doesn't guarantee that the port is closed on exceptional exits <mfiano>What is the Scheme/Guile way to ensure sure fd leaks don't occur if say a bunch of threads start crashing? <lilyp>as I said, you can clean it up within catch/your fancy new exception handling stuff <lilyp>but it isn't done that way (yet) <mfiano>Interesting. I actually never worked with an exception system in about 20 years since I used Python. I've been spoiled by CL's condition system. <civodul>lilyp: i wondered if it was an omission (the fact that call-with-port doesn't close on non-local exits), but it turns out that R5RS explicitly makes it that way! <lilyp>I think the problem might be that with some non-local exits you can actually reenter (e.g. prompts) <lilyp>thus the "under"specification <mfiano>CL conditions have the option of unwinding the stack or not, and by how much, etc, at the time of error. It's just logical for an interactive language in my opinion, to a point where it's quite hard for me to think about programming robustly without it. It might take me some time :) <dadinn>lilyp: I don't understand your (catch whatever your-proc (lambda error (handle-error error) (finally))) exmaple. <dadinn>lilyp: it looks like the finally procedure will only get called when there was an error? <dadinn>in Java the finally clause will always get called. which is how it is ensured that the open ports/ioStreams always get closed. <mfiano>I think that is why he bound `finally`. It is implied you would call that again at the end of the computation for the success case, and wrapped in a macro or some HOF abstraction for convenience maybe? <dadinn>mfiano: not sure I understand. catch will only call the handler on case when an error happens. At least according to the docs <dadinn>at least this is definitely not doing that: (catch #t (lambda () (display "FOO!\n")) (lambda args (display "BAR\n"))) <old>here I call finally either after thunk or before handler <old>in every case, finally is called <old>you can also change the order of the syntax if you want a more traditionnal approach: try catch finally <old>little problem with this syntax is that if your `finally' throw an exception, it will get called a second time an rethrow the same exception but in the handler <old>which might be what you want idk