richardhundt / shine

A Shiny Lua Dialect
Other
231 stars 18 forks source link

Support for generic classes/modules #58

Closed romix closed 10 years ago

romix commented 10 years ago

Currently Shine does not support generic classes (i.e. parametrized by type) or modules explicitly. But many languages have this feature.

Of course, it is pretty easy to model it in Shine, e.g. like this:

function GenMap(keyPred, valuePred)
    class Map
        self()
        self.t = {}
        end
        get(k is keyPred)
        print("get", k)
        return self.t[k]
        end

        put(k is keyPred, v is valuePred)
        print("put", k, v)
        self.t[k] = v
        end

    end

    return Map
end

-- Create a class representing a Map<String, Number>
local StringNumberMap = GenMap(String, Number)
local siMap = StringNumberMap()

siMap.put('One', 1)
siMap.get('One')
siMap.get(1) -- BANG, wrong type of key
siMap.put(2, 'Two') -- BANG, wrong types of keys and values

-- Create a class representing a Map<String, String>
local StringStringMap = GenMap(String, String)
local ssMap = StringStringMap()

ssMap.put('One', 'Two')
ssMap.put('Three', 4) -- BANG, wrong type of value
ssMap.get('One')
ssMap.get(1) -- BANG, wrong type of key

There are probably also alternative implementations, where one does not generate a new class for every combination of generic parameters, but stores the generic parameters as a field of a class instance and then uses them at run-time to check the constraints on the types of parameters, etc.

My question is:

richardhundt commented 10 years ago

Hey, sorry for the late response. The thing is, I've deliberately kept the syntax for function calls and class constructors the same. They're both callable, so that lets you do exactly what you've shown above. Sure there are more efficient ways, but I'm hesitant to add new syntax. The main reason for this is ctypes are constructed as calls, and the cdata metatable is out of bounds (not only that, but their meta method hooks have different semantics from userdata and table types).

I've done this kind of thing in Lupa, and it gets fairly complex. I'd like to keep Shine as simple as possible, but perhaps port Lupa to TvmJIT and give it a decent runtime.

Alternatively I've started another version of Melody which starts with the Shine codebase but with curly brackets and other ideas from JavaScript Harmony. Since that's not targeted at the Lua crowd, we can go mad with features without worrying about maintaining familiarity with Lua.