JarrettBillingsley / Croc

Croc is an extensible extension language in the vein of Lua, which also wishes it were a standalone language. Also it's fun.
http://www.croc-lang.org
79 stars 12 forks source link

Something for "static" class variables #82

Closed JarrettBillingsley closed 10 years ago

JarrettBillingsley commented 11 years ago

One of the nice things that the old differential inheritance class model had was that you could simulate "static" class fields/methods by simply always accessing them through the class, rather than through an instance of the class.

The new class model means that ANY field that you declare in the class ends up in every instance of it. Methods can still be "static" (by using this: class in the parameter list), but fields cannot.

Static class methods have their uses, but most static class fields really just end up being global variables that you happen to access through a class. Furthermore, they tend to be private. Thus, you can really just simulate static class fields by using locals:

local staticVar = 0

class C
{
    function staticMethod(this: class)
    {
        staticVar++
        return staticVar
    }
}

But usually you also want the scope of the static variable to be restricted to the body of the class, in which case you also have to put braces around the whole thing.. and if you want to initialize the static variable to some value based on the class (such as a bound class method), you have to do it AFTER the class declaration, which is tedious.

{
    local staticVar

    class C
    {
        function foo() = staticVar
    }

    staticVar = object.bindClassMethod(C, "foo")
}

So instead, I propose that there be a little sugar for "static" variables, but so as not to introduce another keyword, we could just call them "class local"s. That's really all they are; they're locals which are only visible within the scope of the class.

So if you wrote:

class C
{
    function foo() = staticVar // okay to forward ref like any other member
    class local staticVar = object.bindClassMethod(C, "foo")
}

it would desugar to:

{
    local staticVar
    global C = object.newClass("C")
    object.addMethod(C, "foo", function foo() = staticVar)
    staticVar = object.bindClassMethod(C, "foo")
}

Of course if C was a local class, local C would be declared before the variable scope began.

Note on decorators: would class decorators run in the context of the static vars? That would make sense.

JarrettBillingsley commented 10 years ago

I mainly wanted this to make it easier to deal with iterator closures with the new privacy mechanism, but since that's being dumped I feel like this would be a solution looking for a problem.