Re: Usecase: chaining operations after "optionals" Marc Nieper-Wißkirchen 09 Jun 2020 19:11 UTC

Am Di., 9. Juni 2020 um 19:55 Uhr schrieb Adam Nelson <xxxxxx@nels.onl>:

> (cond ((assoc 'foo '((foo . bar))) => (lambda (x) (symbol->string (cdr
> x)))) (else #f))
>
> (Not that your examples are all missing a `cdr', I think.)
>
> As we can see, R7RS-small already provides all we need. :) And it's
> even quite idiomatic.
>
> It's also 1.5x as long as the other examples and contains extra structure (`lambda`, `else`) that makes it harder to tell what it's doing at a glance, reinforcing the point that the purpose of threading macros is brevity. Or, in this case, preventing you from needing to write a utility function if you do this several times in a program.

Without the `cdr', you can drop the lambda and several characters ;)

Sure, with more procedures it becomes a bit longer.

> Using the `chain` syntax, and separating more parts of this expression out into the pipeline, it can be made much clearer:
>
> (and-chain '((foo . bar)) (assoc 'foo) (cdr) (symbol->string))

Actually, I don't think that `cond' is less clear because everyone
knows `cond', while I would have to look up what `and-chain' does. And
`and-chain', at least in this form, will need helper procedures as
well or the cut syntax as soon as the arguments do not come in the
right order.

That said, I wouldn't choose cond in this example (mainly because of
the meaningless `else #f', which you have already rightfully
complained about). :) I just wanted to make the point, that in the
example Arne has given, we are only talking about minor improvements.

Personally, I would choose `and-let*', which works in all cases
(regardless of the position of the arguments).