Style question: alternatives to threading?

Sometimes I have an expression like (f (g (h x))), except that the f, g, and h represent operations that are a little too short to bother giving names to (or even introducing lambdas) but a little too long to mash together. In a procedural language, you'd maybe write a sequence of operations, something like ...

(let* ([x (F ... x ...)]
       [x (G ... x ...)]
       [x (H ... x ...)])
   x) 

(where F ... x ..., say, is supposed to mean "an expression involving x").

Is there some convention on this in Scheme? Would you write the above, or is that rather infra dig.? Would you write it but change subsequent bindings to y, z, ...? Would you just go ahead and define named functions on the grounds that that's cheap in Scheme? Or does everyone just use threading, and write a lambda where necessary?

1 Like

I'd write the above, but wrapped in a simple macro like this one.

2 Likes

That is very readable.

Are you finding that you need to frequently write lambdas when using the threading macro? I'm curious why that would be the case --- could you share an example?

Note that you can use _ to indicate placement of the argument within the expressions:

(~> "middle" (string-append "beginning-" _ "-end"))

Personally, I would favor the threading style here, and I would use Qi.

1 Like

And if you use Qi with SRFI-105 Curly Infix you can write more easy to understand flows in infix :

{("middle") ~> (string-append "beginning-" _ "-end")}

note that it seems that in @countvajhula example seems "middle" require to be between parenthesis ( ) because for me it does not works (even with #lang racket ) but i'm not absolutely sure of the syntax, see a full test below indeed (screenshot) :

1 Like