nex3/arc — comment on commit 8495169202afdcd02217b244a21a2381ff91ea7a
File:  line 0
By rocketnia:

My trick for allocating something boring used to be `[]`, but Rainbow lambda-lifts that into a constant rather than allocating a new closure each time, and I can't blame it. ^_^

I hope you didn't mind me refactoring your macro. I was extracting the logic into a function to make the hygiene easier (for me) to reason about, and then I realized that your code was a variant of `when` that had a side effect and bound a variable, so I turned the function into an `if` variant with its own macro. I tried to avoid at least a little bit of YAGNI by having `ifread` only take one else clause, but I dunno, I think there's a lot of YAGNI about this whole thing. :-p

Amusingly, we're allocating a cons cell for each read, just as we would if `read` returned a singleton list upon success and `nil` upon failure. If `read` did work that way, `(reading x port ...)` would just be `(whenlet (x) (read port) ...)`.

We might be able to avoid that allocation altogether if we implement `ifread` in terms of Racket `eof-object?` rather than relying on `read`. But then we might allocate a bunch of closures on each read either way, and I don't care enough to profile it, lol.