lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, May 30, 2012 at 10:03 PM, Miles Bader <miles@gnu.org> wrote:
> Miles Bader <miles@gnu.org> writes:
>>> However, it seems to me that there is one hole in this clean model:
>>> the inability of a metatable to project a "type" into the Lua code
>>> space.
>> ...
>>> Thoughts anyone?
>>
>> I think the entire concept of a "type()" function is sort of fragile,
>> and really not what you want as a general interface.
>>
>> Something like type predicates would be much better.  So the trick is,
>> assuming a standard set of type predicates, how do you extend them to
>> work on user types?
>
> ... and of course they need not be real predicates, e.g. something like
> "istype(OBJ, TYPENAME)" can offer the same functionality, maybe.
>
> -miles
>
> --
> Conservative, n. A statesman enamored of existing evils, as opposed to a
> Liberal, who wants to replace them with new ones.
>

I give my objects _type fields, with names like "mylib.foo.bar",
identifying a type bar which is a more specific type of foo. Wrapping
type() to check for these fields is pretty simple.

Though, I've always felt like the other direction is the way to go:
make "isindexable" and "iscallable" functions (or if you prefer,
"istable" and "isfunction", though that can be confusing, since e.g.
istable("a") == true), so that you don't have to concern yourself with
types at all. If you expect an indexable type, go ahead and index it.
These helper functions then just provide convenience if you want to
handle indexable objects differently from callable ones or vice-versa,
or throw an error if given the wrong thing.

I was actually pondering earlier today the idea of making *all*
objects both indexable and callable. Calling a number, boolean or nil
value would just return their value (i.e. 4() == 4). Calling a string
would do the same as load()ing it. (Whether the resulting function
should be returned or executed on the spot is something I hadn't
decided.) Calling a table or userdata which doesn't have a __call
would throw an error, or maybe do nothing? Then, all of these
behaviours would be defined as functions in their respective
metatables, so that you could change them if you liked; e.g. if you
want calling nil to be an error: getmetatable(nil).__call = error.
Numbers, booleans and nil would share metatables like strings do.
As for indexing, perhaps any assignment to fields of such objects
automatically creates a table which emulates them, e.g.:
n = 4; n.i = 3 --identical to:
n = setmetatable({4, i=3}, {...various magic to make n work like a number...})

I was busy with work, so I didn't have time to fully think about the
fine details of this idea...

-- 
Sent from my Game Boy.