Rethinking `<static>` in the Function Spec Dialect

In R3-Alpha, the FUNCTION construct was built on top of FUNC, and added features like statics as a refinement. It looked pretty awkward, because the static was added at the end of the expression:

 r3-alpha>> foo: function/with [x] [return staticvar: add staticvar x] [staticvar: 0]

 r3-alpha>> foo 10
 == 10

 r3-alpha>> foo 20
 == 30

Ren-C tried extending the function spec dialect to support this in a nicer way:

 foo: function [x <static> staticvar (0)] [return staticvar: add staticvar x]

The low-level FUNC implementation doesn't know what <static> is, so it's added by a higher layer, that makes things slower... and since the function spec dialect is kind of foundational it may be the wrong place to be putting this for the core.

@hiiamboris approaches this differently:

It's not the first time I've thought it would be a better direction to break it out. But putting it all as part of the function spec was supposed to have an advantage in that when the body was walked to create the copy, the binding to the static members would be done as well. This is no longer applicable, because the bodies of functions are largely left unbound...

We do lose a feature of noticing when you are naming the static the same thing as something in your function frame and you don't get an error in that case, but maybe you don't want an error (perhaps you inherited the frame through an adaptation or something like that, and you don't care about the frame variable).

Boris's dialect is a bit overloaded, and Ren-C has more parts to help with that...but it would help even more if there were FENCE!

foo: func [x] with [
    {staticvar: 0}
][
    return staticvar: add staticvar x
]

foo: func [x] with {staticvar: 0} [
    return staticvar: add staticvar x
]

So this wouldn't be confused with any other WITH things you were doing, like trying to use objects or words and add them to a block that already had a binding.

>> body: [keep staticvar: staticvar + x]

>> collect [
       wrapper: func [x] with ['keep {staticvar: 0}] body
       wrapper 1
       wrapper 10
       wrapper 100
   ]
== [1 11 111]

(Just trying to drum up a little excitement for FENCE! there, but I think it's the tip of the iceberg.)

Anyway, there've been educational lessons from showing that you can extend the FUNC spec dialect and build higher level features... but I think we should probably tear those out of the core and move to something like this.

1 Like