carp-lang / Carp

A statically typed lisp, without a GC, for real-time applications.
Apache License 2.0
5.51k stars 174 forks source link

expandAll misses some fixpoints #1334

Open hellerve opened 2 years ago

hellerve commented 2 years ago

expandAll relies on the fact that at some point, an expansion will hit a fixpoint, because there is nothing left to expand. Some forms seem not to hit those fixpoints, leading to the occasional hang. Let’s consider this example:

> (defdynamic x Int.+)
> (x 1 2)
<hangs>

This seems to be related with dynamic symbols or forms evaluating to static objects.

The expansion is quite interesting:

(x 1 2)
; expands to
((defdynamic x (external Int.+ (λ [Int Int] Int))) 1 2)
; expands to
((defdynamic (defdynamic x (external Int.+ (λ [Int Int] Int))) (external Int.+ (λ [Int Int] Int))) 1 2)
; expands to another nesting, and another, and so on

I haven’t quite gotten to the point where this happens, but this is where I’m at at the moment.

Cheers

eriksvedang commented 2 years ago

That expansion is wild!

Looks like it's expanding x into the whole defdynamic form, right? 🤔

hellerve commented 2 years ago

It does, which is what the binder evaluates to. defdynamic forms are always bound as-is, so this kind of makes sense. I don’t really like that we do this, but it’s how we make sure we know it’s a dynamic value I guess?