Re: Usecase: chaining operations after "optionals"
Arne Babenhauserheide 09 Jun 2020 22:08 UTC
Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> writes:
> 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.)
That was my mistake, sorry.
>> 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))
Let’s use the synatx again, but add one more point: receiving the 'foo
from somewhere (this is what I often see in Java streams). Please
correct me if I got SRFI 2 wrong.
SRFI 2:
(and-let* ((name (read-name))
(cons-cel (assoc name '((foo . bar))))
(value (cdr cons-cel)))
(symbol->string value))
Options:
(and=> (read-name) (assoc '((foo . bar))) (cdr) (symbol->string))
(and-chain (read-name) (assoc '((foo . bar))) (cdr) (symbol->string))
(and-chain (read-name) (assoc <> '((foo . bar))) (cdr <>) (symbol->string <>))
(and-bind (read-name) (cut assoc <> '((foo . bar))) (cut cdr <>) (cut symbol->string <>))
> Personally, I would choose `and-let*', which works in all cases
> (regardless of the position of the arguments).
and-let* looks unexpectedly nice, yes. It is much longer, but explicit.
For my most common case (need cdr after assoc), the difference is
significantly in favor of the new syntax, though.
It would make using assoc-style #f-or-cons-cel returns more usable.
For more complex chains, and-let* might actually win, though.
Best wishes,
Arne
--
Unpolitisch sein
heißt politisch sein
ohne es zu merken