lua-users home
lua-l archive

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


Now we're waay of the reservation here, but I'm pretty far along in my
little side project: Monkey Type (or I'm thinking TPEG)
local tpeg = require 'tpeg'

local T, Ti, Tf = tpeg.t, tpeg.ti, tpeg.tf
type = tpeg.type

local new_interface = Ti(T("number") + (T"string" / tonumber) +
T"my_number_like_object")^-1 -- only one argument. If not specified,
it doesn't care how many, as long as you have this one.
local new_interface2 = Ti(Tt(Tf("my_field", new_interface))) --only
this field in the table

--named function type. if I put a function in the first argument, it
would wrap the function without naming the type.
local new_func_type = Tf("my_number_reader_func_type", new_interface +
new_interface2 / T"number")

local my_func = function(arg)
   ...
   return number_value
end


my_func = new_func_type(my_func)

print(type(my_func))

-->"function", "my_number_reader_func_type", "(number + (string /
number) + my_number_like_object)^-1 / number"

print(tpeg.gettype(my_func) == new_func_type)
--> true

----
With the `new_func_type(my_func)` command, `my_func` is wrapped in two
closures and has a reference stored in the library. The reference lets
me report the type value and works with "gettype," if I'm comparing it
or using it in another, nested type def. For the closures, first one
checks the incoming arguments and the second closure checks the return
values. If either aren't defined, then that closure isn't made, at
all.

When I'm wrapping a func table, I do the same thing, except I swap out
the __call function, instead. I haven't decided how to handle
coroutines, given that their interfaces are often different on their
first and last calls...

The cool thing is that, apart from any conversions built into the
interfaces (/ tonumber), the function call works identically to its
non-typed variant and I can "turn the library off" (not wrap functions
or mess with types) and things still work fine. Also, I don't make any
tables during any of the checking, so there isn't any extra garbage
collection. (This is why I've run into some of the nuances related to
nil and "really not there", as I've been using `select` an awful lot.)

The closures and type part are done. The LPEG like interface is what
I've been experimenting with for a while now. I don't pretend that
this will actually be awesome, but it is really fun seeing if I can
make a type system out of what amounts to an aping of the LPEG API.

-Andrew

On Sat, Jul 6, 2013 at 1:06 AM, Miles Bader <miles@gnu.org> wrote:
> Tim Hill <drtimhill@gmail.com> writes:
>> Cant say I disagree, but the same could be said of __tostring(), yet
>> we have that.
>
> That's the thing though:  I _don't_ think the same thing can be said
> of __tostring.  There's no real meaning expected of the resulting
> string (e.g. there's generally no particular expectation that the
> resulting string be parsable by Lua), so for the most part, so the
> "simple" interface is basically fine.
>
> -miles
>
> --
> Love is the difficult realization that something other than oneself is real.
> [Iris Murdoch]
>