jackfirth / resyntax

A Racket refactoring engine
Apache License 2.0
51 stars 10 forks source link

when in for loop #213

Open sorawee opened 12 months ago

sorawee commented 12 months ago

Rewrites

(for (....)
  (when ... .....))

to

(for (....
      #:when ...)
  ....)
Metaxal commented 12 months ago

Personally, I don't like this transformation. Syntactically, the test gets substantial rightward drift even though the body is less indented. The intent is also less clear because the #:when clause behaves in a rather subtle way.

(I got caught by a logical mistake with a #:when clause last, but I can't recall what it was.)

Metaxal commented 12 months ago

This is probably more helpful:

(for (clause1 ...)
  (when test
    (for (clause2 ...)
      body ...)))
;; ->
(for (clause1 ...
      #:when test
      clause2 ...)
  body ...)

But I think @jackfirth wants to see an example in the wild before adding a rule.

A very beneficial use case would be for code that tries to do for/list with #:when but using nested for/list and append instead, or using an external accumulator. The #:when version is a big save there.

jackfirth commented 12 months ago

I like this rule, since it unlocks further for loop simplifications. For example, that for loop flattening that @Metaxal suggested is already implemented. The (for ... (when ... (for ...))) example would be simplified in two passes if we had this rule.

I'm sympathetic to the idea that #:when is a bit less intuitive than (when ...). Perhaps if we limited this to cases where the condition expression is short? Limiting it only to cases that unlock further simplifications is also doable, but it's more work.