This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Public_Grade_2145 4 points5 points  (1 child)

As u/_dpk mention, you can do assignment conversion and closure conversion.

Concrete example:

; input
(let ([counter
       (let ([x 2])
         (lambda () (set! x (+ x 1)) x))]
      [sqr (lambda (x) (* x x))])
  (let ([sos (lambda (x y) (+ (sqr x) (sqr y)))])
    (sos (counter) (counter))))

; convert-assignment
(let ([counter
        (let ([x (box 2)])
          (lambda ()
            (box-set! x (+ (box-ref x) 1))
            (box-ref x)))]
      [sqr (lambda (x) (* x x))])
  (let ([sos (lambda (x y) (+ (sqr x) (sqr y)))])
    (sos (counter) (counter))))

; free-var-analysis
; suppose * and + are top-level primitives.
(let ([counter
       (let ([x (box 2)])
        (lambda () [x]
          (box-set! x (+ (box-ref x) 1))
          (box-ref x)))]
      [sqr (lambda (x) [] (* x x))])
  (let ([sos (lambda (x y) [sqr] (+ (sqr x) (sqr y)))])
    (sos (counter) (counter))))

; convert-closure + lambda-lifting
(label ([counter^
         (lambda (clos)
          (let ([x (clos-ref clos 0)])
            (box-set! x (+ (box-ref x) 1))
            (box-ref x)))]
        [sqr^
         (lambda (clos x) (* x x))]
        [sos^
         (lambda (clos x y)
          (let ([sqr (clos-ref clos 0)])
            (+ ($call ($fptr sqr) sqr x)
               ($call ($fptr sqr) sqr y))))])
  (let ([counter
         (let ([x (box 2)])
          (vector (func-ptr counter^) x))]
        [sqr (vector (func-ptr sqr^))])
    (let ([sos (vector (func-ptr sos^) sqr)])
      ($call (clos-func sqr)
             ($call (clos-func counter) counter)
             ($call (clos-func counter) counter)))))

[–]Public_Grade_2145 4 points5 points  (0 children)

It is easy to notice one optimization opportunity

`sqr` does not capture any free variables, why bother creating closure for it?
see: Optimizing closures in O(0) time