lua-users home
lua-l archive

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


On Wed, Jul 24, 2013 at 1:45 AM, Philipp Janda <siffiejoe@gmx.net> wrote:
> Am 24.07.2013 06:41 schröbte Miles Bader:
>

<snip>
>
> How about a compromise:
>
> If called like this:
>
>     type( v )
>
> the `type` function returns one of the eight basic type names like it is
> now.
> If called with extra string arguments:
>
>     type( v, "integer" )
>
> it returns the first extra string argument that matches the type of the
> value, or nil if none matches.

I'm still not sure why `type.isfloat(x)` (etc) isn't getting any love,
but this works too and as you point out...
>
> This way we can use it as predicate for overlapping types:
>
>    if type( v, "float" ) then ... end
>
> and still dispatch on the type:
>
>    callbacks[ type( v ) ]( x, y, z )
>
> and even combine those two methods:
>
>    callbacks[ type( v, "callable", "indexable" ) or type( v ) ]( x, y, z )

... has the advantage of being able to check it against multiple type
properties.

>
> But I think the reason to introduce type predicates (virtual types such as
> "callable") is a reason to *not* use them for the integer/float distinction:
> there may be other objects that implement float-like or integer-like
> interfaces, and we would still have the same problem as with functions and
> is_callable ...
>
> IMHO, virtual types would be better handled with something like:
>
>    has"__index,__newindex,__len,__ipairs"( v )    --> array-like type or
> table
>    has"__call"( f )   --> callable type or function
>
> with some additional logic to handle the predefined capabilities of numbers,
> strings, tables, and functions.
>
>>
>> -miles
>>
>
> Philipp


This all points to a larger conversation about Lua's type system, as
opposed to what one can slightly change/add in order to find out if a
number is a float.

Does Lua need facilities beyond a string name associated with a
value's basic (sometimes vague) type?

I think I'm saying mostly the same thing, but how about "interfaces",
which I think gets at "has" and answers most of what subtypes is
after.

Example: A number supports the float and integer interface.

Example: My object, with all of the arithmetic metamethods defined,
includes this field in its metatable:

mt.__interface = "number"


Now libraries that respect interfaces know that my object can be
treated as a number.

For multiple interfaces:

mt.__interface = {"ordinal", "string"}

I'm not sure how it could look, but one could imagine functions having
an interface that included supported arguments and expected return
values. I would imagine that this would not be in the language. It
would only be facilitated by this sort of thing.


-Andrew


On Wed, Jul 24, 2013 at 1:45 AM, Philipp Janda <siffiejoe@gmx.net> wrote:
> Am 24.07.2013 06:41 schröbte Miles Bader:
>
>> Thijs Schreijer <thijs@thijsschreijer.nl> writes:
>>>
>>> Then I would rather have a single type() function and replace its
>>> number' return value with the new types. Big incompatibility but the
>>> new integer division operator already is. Incompatible but clean.
>>
>>
>> Predicates are actually _more_ clean, and yet aren't incompatible
>> ("isnumber" and "isinteger"/"isfloat" can exist simultaneously).
>>
>> If you are worried about function namespace pollution (I'm not,
>> particularly, but ...), it's also possible to use a predicate-style
>> solution with a separate type namespace, e.g. "istype(OBJ, TYPE)",
>> where TYPE is 'number', 'float', 'table', etc.
>
>
> How about a compromise:
>
> If called like this:
>
>     type( v )
>
> the `type` function returns one of the eight basic type names like it is
> now.
> If called with extra string arguments:
>
>     type( v, "integer" )
>
> it returns the first extra string argument that matches the type of the
> value, or nil if none matches.
>
> This way we can use it as predicate for overlapping types:
>
>    if type( v, "float" ) then ... end
>
> and still dispatch on the type:
>
>    callbacks[ type( v ) ]( x, y, z )
>
> and even combine those two methods:
>
>    callbacks[ type( v, "callable", "indexable" ) or type( v ) ]( x, y, z )
>
> But I think the reason to introduce type predicates (virtual types such as
> "callable") is a reason to *not* use them for the integer/float distinction:
> there may be other objects that implement float-like or integer-like
> interfaces, and we would still have the same problem as with functions and
> is_callable ...
>
> IMHO, virtual types would be better handled with something like:
>
>    has"__index,__newindex,__len,__ipairs"( v )    --> array-like type or
> table
>    has"__call"( f )   --> callable type or function
>
> with some additional logic to handle the predefined capabilities of numbers,
> strings, tables, and functions.
>
>>
>> -miles
>>
>
> Philipp
>
>
>
>