coalton-lang / coalton

Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.
https://coalton-lang.github.io/
MIT License
1.15k stars 70 forks source link

Bind *print-circle* t when dumping Lisp code #1214

Closed jbouwman closed 2 months ago

jbouwman commented 2 months ago

Variable names must be interned symbols when written as lisp code.

These cases came up during benchmarking and library conversion.

Note

Binding *print-circle* t produces working code, so this MR was changed to replace most cases of gentemp in codegen with gensym.

stylewarning commented 2 months ago

Should we gentemp from a package designed to hold gentemps?

jbouwman commented 2 months ago

Should we gentemp from a package designed to hold gentemps?

The symbols are interned into the package being compiled, so I think it's ok.

This came up on the initial PR, too, viz https://github.com/coalton-lang/coalton/pull/1091#discussion_r1645239679

stylewarning commented 2 months ago

Should we gentemp from a package designed to hold gentemps?

The symbols are interned into the package being compiled, so I think it's ok.

This came up on the initial PR, too, viz https://github.com/coalton-lang/coalton/pull/1091#discussion_r1645239679

Two Q's:

jbouwman commented 2 months ago

The gentemps are executed during compilation; at that time *package* is bound to the package containing coalton source. One line of trace:

Package = #<COMMON-LISP:PACKAGE "COALTON-LIBRARY/MATH/NUM"> Sym = T897 Sym Package = #<COMMON-LISP:PACKAGE "COALTON-LIBRARY/MATH/NUM">

I'll look at print circle again, I don't recall why it didn't work.

jbouwman commented 2 months ago

Setting print-circle t when dumping lisp forms does work, at a minor cost of legiblity, for example

print-circle = t

(common-lisp:defun fact #1=(n-55)
  (common-lisp:declare (common-lisp:ignorable . #1#)
                       (common-lisp:type common-lisp:integer n-55)
                       (common-lisp:values common-lisp:integer
                                           common-lisp:&optional))
  (common-lisp:let ((#2=#:match615 (common-lisp:the common-lisp:integer n-55)))
    (common-lisp:declare (common-lisp:ignorable #2#))
    (common-lisp:locally
     (common-lisp:declare (sb-ext:muffle-conditions sb-ext:code-deletion-note))
     (common-lisp:cond ((common-lisp:eql 0 #2#) 1)
                       (common-lisp:t
                        (coalton-library/math/num::|INSTANCE/NUM INTEGER-COALTON-LIBRARY/CLASSES:*|
                         n-55
                         (fact
                          (coalton-library/math/num::|INSTANCE/NUM INTEGER-COALTON-LIBRARY/CLASSES:-|
                           n-55 1))))))))

print-circle = nil

(common-lisp:defun fact (n-8158)
  (common-lisp:declare (common-lisp:ignorable n-8158)
                       (common-lisp:type common-lisp:integer n-8158)
                       (common-lisp:values common-lisp:integer
                                           common-lisp:&optional))
  (common-lisp:let ((match8160 (common-lisp:the common-lisp:integer n-8158)))
    (common-lisp:declare (common-lisp:ignorable match8160))
    (common-lisp:locally
     (common-lisp:declare (sb-ext:muffle-conditions sb-ext:code-deletion-note))
     (common-lisp:cond ((common-lisp:eql 0 match8160) 1)
                       (common-lisp:t
                        (coalton-library/math/num::|INSTANCE/NUM INTEGER-COALTON-LIBRARY/CLASSES:*|
                         n-8158
                         (fact
                          (coalton-library/math/num::|INSTANCE/NUM INTEGER-COALTON-LIBRARY/CLASSES:-|
                           n-8158 1))))))))
stylewarning commented 2 months ago

I think that legibility cost is well worth not leaking an unbounded number of gentemps into the runtime environment every time a compilation happens.

And besides, when we do something like COALTON-CODEGEN interactively, we can have print circle off.