callback implementation details..

classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

callback implementation details..

Ando Sonenblick
Gang,

I have a feeling my question here is rather, well, stupid, but lua has proven so amazingly flexible that I just may be surprised that what I'm asking isn't just stupid, but actually possible.... yet I doubt it...

Anyway, I am about to implement callbacks... so that a script can call a C function to do some background process and when done, have the C code execute a lua call back. Here would be a standard way:

local x, y, p1, p2;
DoSomething(x, y, {function  callback(a, b) print(a+ b) end, p1, p2});

Where DoSomething is the call to C to initiate the bg process, x and y are parameters for that process, and the table is the description of the callback:

it has the function to execute and the (variable number) of parameters to pass to it.

In this case, say p1 and p2 are 10 and 20 respectively, my C code creates a ref to the table, does the work, then using the ref calls the function callback, passing p1 and p2, which prints out 30. I see no problems with implementing this.

What I'd love (for simplification sake) would be to somehow already pass the parameters to the function so that I don't have to have a table, or do extra parsing/passing in my C code, etc.

So, in this case, things would look like (hypothetically speaking):

local x, y, p1, p2;
DoSomething(x, y, function callback(a = p1, b = p2) print(a+ b) end); -- a is preassigned to p1 and b is preassigned to p2

so in this case (assuming 10 and 20 again for p1 and p2), my C code could simply just call callback and the parameter a is already 10 and p already 20, yielding the same print out of 30.

Is anything like this possible?

thx,
ando

-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com


Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Bilyk, Alex
local x, y
local p1, p2 = 10, 20
DoSomething(x, y, function  callback() print(p1+ p2) end);

The callback will print your 30.
AB


-----Original Message-----
From: Ando Sonenblick [[hidden email]]
Sent: Friday, October 17, 2003 12:47 PM
To: Lua list
Subject: callback implementation details..

Gang,

I have a feeling my question here is rather, well, stupid, but lua has
proven so amazingly flexible that I just may be surprised that what I'm
asking isn't just stupid, but actually possible....  yet I doubt it...

Anyway, I am about to implement callbacks...   so that a script can
call a C function to do some background process and when done, have the
C code execute a lua call back.  Here would be a standard way:

local x, y, p1, p2;
DoSomething(x, y, {function  callback(a, b) print(a+ b) end, p1, p2});

Where DoSomething is the call to C to initiate the bg process, x and y
are parameters for that process, and the table is the description of
the callback:

it has the function to execute and the (variable number) of parameters
to pass to it.

In this case, say p1 and p2 are 10 and 20 respectively, my C code
creates a ref to the table, does the work, then using the ref calls the
function callback, passing p1 and p2, which prints out 30.  I see no
problems with implementing this.

What I'd love (for simplification sake) would be to somehow already
pass the parameters to the function so that I don't have to have a
table, or do extra parsing/passing in my C code, etc.

So, in this case, things would look like (hypothetically speaking):

local x, y, p1, p2;
DoSomething(x, y, function callback(a = p1, b = p2) print(a+ b) end);  
    -- a is preassigned to p1 and b is preassigned to p2

so in this case (assuming 10 and 20 again for p1 and p2), my C code
could simply just call callback and the parameter a is already 10 and p
already 20, yielding the same print out of 30.

Is anything like this possible?

thx,
ando

-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com


Reply | Threaded
Open this post in threaded view
|

Re: callback implementation details..

Ando Sonenblick
AB,

thanks for the feedback.

now what if we have this:

local x, y;
local p1, p2 = 10, 20

callback = function(a, b) print(a + b) end

DoSomething(x, y, f(p1, p2))

-- is that possible? (I'd try it but haven't yet gotten my code in place to do so...)

also, in your implementation, if p1 and p2 were globals and the values changed after the call to DoSomething and the callback, that might not be what the caller of DoSomething desired...

ando


On Friday, October 17, 2003, at 02:02 PM, Bilyk, Alex wrote:

local x, y
local p1, p2 = 10, 20
DoSomething(x, y, function  callback() print(p1+ p2) end);

The callback will print your 30.
AB


-----Original Message-----
From: Ando Sonenblick [[hidden email]]
Sent: Friday, October 17, 2003 12:47 PM
To: Lua list
Subject: callback implementation details..

Gang,

I have a feeling my question here is rather, well, stupid, but lua has
proven so amazingly flexible that I just may be surprised that what I'm
asking isn't just stupid, but actually possible....  yet I doubt it...

Anyway, I am about to implement callbacks...   so that a script can
call a C function to do some background process and when done, have the
C code execute a lua call back.  Here would be a standard way:

local x, y, p1, p2;
DoSomething(x, y, {function  callback(a, b) print(a+ b) end, p1, p2});

Where DoSomething is the call to C to initiate the bg process, x and y
are parameters for that process, and the table is the description of
the callback:

it has the function to execute and the (variable number) of parameters
to pass to it.

In this case, say p1 and p2 are 10 and 20 respectively, my C code
creates a ref to the table, does the work, then using the ref calls the
function callback, passing p1 and p2, which prints out 30.  I see no
problems with implementing this.

What I'd love (for simplification sake) would be to somehow already
pass the parameters to the function so that I don't have to have a
table, or do extra parsing/passing in my C code, etc.

So, in this case, things would look like (hypothetically speaking):

local x, y, p1, p2;
DoSomething(x, y, function callback(a = p1, b = p2) print(a+ b) end);
    -- a is preassigned to p1 and b is preassigned to p2

so in this case (assuming 10 and 20 again for p1 and p2), my C code
could simply just call callback and the parameter a is already 10 and p
already 20, yielding the same print out of 30.

Is anything like this possible?

thx,
ando

-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com


-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com


Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Virgil Smith
If my reading is correct it would not matter if "globals" p1 and p2 changed
because a closure was formed at the time of the DoSomething call.
In fact I would think that the closure mechanism could be used to achieve
what you wish, but I'm far from an expert so check what I am suggesting (and
yes, just suggesting, not telling).

BTW: You're last example should not function correctly (of this much I'm
sure :)

---------------
local x, y;
local p1, p2 = 10, 20

callback = function(a, b) print(a + b) end

DoSomething(x, y, f(p1, p2))
--------------

Should result in f(p1, p2) being called and its return value (nil) passed to
DoSomething as a parameter.

However, you should be able to specify to your users that the Callback
receives no parameters and they can "overcome" this restriction by creating
a closure (this is the part where I'm not 100% sure of myself)

Example of user circumventing that "annoying" library provider who didn't
let him pass any arguments to his callback...
---------------
local x, y;
local p1, p2 = 10, 20

callback = function(a, b) print(a + b) end

DoSomething(x, y, function return callback(p1, p2) end)
--------------


If this looks like too much for your users to comprehend then you could
offer the following rather bizarre helper function...

function BindParameters(f, ...)
	return function return f(unpack(arg)) end end
end

which could be used to make the DoSomething call from above look like....

DoSomething(x, y, BindParameters(callback, p1, p2))


-----Original Message-----
From: [hidden email]
[[hidden email] Behalf Of Ando Sonenblick
Sent: Friday, October 17, 2003 4:37 PM
To: Lua list
Subject: Re: callback implementation details..


AB,

thanks for the feedback.

now what if we have this:

local x, y;
local p1, p2 = 10, 20

callback = function(a, b) print(a + b) end

DoSomething(x, y, f(p1, p2))

-- is that possible?  (I'd try it but haven't yet gotten my code in
place to do so...)

also, in your implementation, if p1 and p2 were globals and the values
changed after the call to DoSomething and the callback, that might not
be what the caller of DoSomething desired...

ando


On Friday, October 17, 2003, at 02:02 PM, Bilyk, Alex wrote:

> local x, y
> local p1, p2 = 10, 20
> DoSomething(x, y, function  callback() print(p1+ p2) end);
>
> The callback will print your 30.
> AB
>
>
> -----Original Message-----
> From: Ando Sonenblick [[hidden email]]
> Sent: Friday, October 17, 2003 12:47 PM
> To: Lua list
> Subject: callback implementation details..
>
> Gang,
>
> I have a feeling my question here is rather, well, stupid, but lua has
> proven so amazingly flexible that I just may be surprised that what I'm
> asking isn't just stupid, but actually possible....  yet I doubt it...
>
> Anyway, I am about to implement callbacks...   so that a script can
> call a C function to do some background process and when done, have the
> C code execute a lua call back.  Here would be a standard way:
>
> local x, y, p1, p2;
> DoSomething(x, y, {function  callback(a, b) print(a+ b) end, p1, p2});
>
> Where DoSomething is the call to C to initiate the bg process, x and y
> are parameters for that process, and the table is the description of
> the callback:
>
> it has the function to execute and the (variable number) of parameters
> to pass to it.
>
> In this case, say p1 and p2 are 10 and 20 respectively, my C code
> creates a ref to the table, does the work, then using the ref calls the
> function callback, passing p1 and p2, which prints out 30.  I see no
> problems with implementing this.
>
> What I'd love (for simplification sake) would be to somehow already
> pass the parameters to the function so that I don't have to have a
> table, or do extra parsing/passing in my C code, etc.
>
> So, in this case, things would look like (hypothetically speaking):
>
> local x, y, p1, p2;
> DoSomething(x, y, function callback(a = p1, b = p2) print(a+ b) end);
>     -- a is preassigned to p1 and b is preassigned to p2
>
> so in this case (assuming 10 and 20 again for p1 and p2), my C code
> could simply just call callback and the parameter a is already 10 and p
> already 20, yielding the same print out of 30.
>
> Is anything like this possible?
>
> thx,
> ando
>
> -----------------------
> Ando Sonenblick
> SpriTec Software
> www.spritec.com
>
>
-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com


Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Bilyk, Alex
In reply to this post by Ando Sonenblick
How about this?

---CUT here----------------------------------------

function CallBackFactory(callback_func, callback_param_table)
   return 
      function ()
         return callback_func(unpack(callback_param_table))
      end
end

-----------------------------------------------------
function DoSomething(x,y, callback)
   print (x, y)
   local done = true

   if(done) then
      callback()
   end
end

function Callback(a, b)
   print("callback : ", a+b)
end

DoSomething(0, 1, CallBackFactory(Callback, {10, 20}))
DoSomething(0, 1, CallBackFactory(Callback, {40, -40}))
---CUT here----------------------------------------


-----Original Message-----
From: Ando Sonenblick [[hidden email]]
Sent: Friday, October 17, 2003 2:37 PM
To: Lua list
Subject: Re: callback implementation details..

AB,

thanks for the feedback.

now what if we have this:

local x, y;
local p1, p2 = 10, 20

callback = function(a, b) print(a + b) end

DoSomething(x, y, f(p1, p2))

-- is that possible?  (I'd try it but haven't yet gotten my code in
place to do so...)

also, in your implementation, if p1 and p2 were globals and the values
changed after the call to DoSomething and the callback, that might not
be what the caller of DoSomething desired...

ando


On Friday, October 17, 2003, at 02:02 PM, Bilyk, Alex wrote:

> local x, y
> local p1, p2 = 10, 20
> DoSomething(x, y, function  callback() print(p1+ p2) end);
>
> The callback will print your 30.
> AB
>
>
> -----Original Message-----
> From: Ando Sonenblick [[hidden email]]
> Sent: Friday, October 17, 2003 12:47 PM
> To: Lua list
> Subject: callback implementation details..
>
> Gang,
>
> I have a feeling my question here is rather, well, stupid, but lua has
> proven so amazingly flexible that I just may be surprised that what I'm
> asking isn't just stupid, but actually possible....  yet I doubt it...
>
> Anyway, I am about to implement callbacks...   so that a script can
> call a C function to do some background process and when done, have the
> C code execute a lua call back.  Here would be a standard way:
>
> local x, y, p1, p2;
> DoSomething(x, y, {function  callback(a, b) print(a+ b) end, p1, p2});
>
> Where DoSomething is the call to C to initiate the bg process, x and y
> are parameters for that process, and the table is the description of
> the callback:
>
> it has the function to execute and the (variable number) of parameters
> to pass to it.
>
> In this case, say p1 and p2 are 10 and 20 respectively, my C code
> creates a ref to the table, does the work, then using the ref calls the
> function callback, passing p1 and p2, which prints out 30.  I see no
> problems with implementing this.
>
> What I'd love (for simplification sake) would be to somehow already
> pass the parameters to the function so that I don't have to have a
> table, or do extra parsing/passing in my C code, etc.
>
> So, in this case, things would look like (hypothetically speaking):
>
> local x, y, p1, p2;
> DoSomething(x, y, function callback(a = p1, b = p2) print(a+ b) end);
>     -- a is preassigned to p1 and b is preassigned to p2
>
> so in this case (assuming 10 and 20 again for p1 and p2), my C code
> could simply just call callback and the parameter a is already 10 and p
> already 20, yielding the same print out of 30.
>
> Is anything like this possible?
>
> thx,
> ando
>
> -----------------------
> Ando Sonenblick
> SpriTec Software
> www.spritec.com
>
>
-----------------------
Ando Sonenblick
SpriTec Software
www.spritec.com


Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

RLak-2
In reply to this post by Ando Sonenblick
Hi, Virgil.

Did you try this code? I think it is what you might be looking for, 
actually. Although you can do it with unpack() etc.
Or did I blow it somewhere?


static int l_docurry(lua_State *L) {
  int n = lua_pushupvalues(L);
      // lua_rotate would be useful here. Oh, well.
  for (; n > 0; --n) lua_insert(L, 1);
  lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
  return lua_gettop(L);
}

// Register this one as curry

static int luaB_curry(lua_State *L) {
  lua_pushcclosure(L, l_docurry, lua_gettop(L));
  return 1;
}

Then you can just write:
  curry(method, self)
or:
  curry(method, self, 7)



Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Reuben Thomas-5
> Did you try this code? I think it is what you might be looking for,
> actually. Although you can do it with unpack() etc.

Yes, curry is simply:

-- curry: Partially apply a function
--   f: function to apply partially
--   a1 ... an: arguments to fix
-- returns
--   g: function with ai fixed
function curry (f, ...)
  local fix = arg
  return function (...)
           return f (unpack (fix), unpack (arg))
         end
end

which is a lot simpler than messing around with C.

-- 
http://www.mupsych.org/~rrt/ | Caution Children At Play Drive Slowly (Anon)

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Eric Tetz-2
--- Reuben Thomas wrote:
> Yes, curry is simply:
> 
> function curry (f, ...)
>   local fix = arg
>   return function (...)
>            return f (unpack (fix), unpack (arg))
>          end
> end

You don't need the 'fix', because a unique table is passed in every
time the function is called:

function curry (f, ...)
  return function (...)
    return f (unpack(arg))
  end
end



__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Reuben Thomas-5
> --- Reuben Thomas wrote:
> > Yes, curry is simply:
> >
> > function curry (f, ...)
> >   local fix = arg
> >   return function (...)
> >            return f (unpack (fix), unpack (arg))
> >          end
> > end
>
> You don't need the 'fix', because a unique table is passed in every
> time the function is called:

I don't think you're right: in the code below:

> function curry (f, ...)
>   return function (...)
>     return f (unpack(arg))
>   end
> end

you don't keep the fixed arguments. All you do is call f on whatever the
function gets, i.e. your curry (f) is the same as f.

-- 
http://www.mupsych.org/~rrt/ | Analogy midwives, identity murders

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Eric Tetz-2
--- Reuben Thomas <[hidden email]> wrote:
> I don't think you're right: in the code below:
> 
> > function curry (f, ...)
> >   return function (...)
> >     return f (unpack(arg))
> >   end
> > end
> 
> you don't keep the fixed arguments. All you do is call f on
whatever the
> function gets, i.e. your curry (f) is the same as f.

Well, I stated the wrong reason (which I realized the second I
clicked "submit"). You don't need 'fix' because you already have a
local to bind the closure to: 'arg'.

This function:

> function curry (f, ...)
>   local fix = arg
>   return function (...)
>            return f (unpack (fix), unpack (arg))
>          end
> end

Creates a second local referring to the same table, then passes
passes the same argument list to 'f' twice.


__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Reuben Thomas-5
On Fri, 17 Oct 2003, Eric Tetz wrote:

> Well, I stated the wrong reason (which I realized the second I
> clicked "submit"). You don't need 'fix' because you already have a
> local to bind the closure to: 'arg'.

No, fix and arg refer to different tables.

> This function:
>
> > function curry (f, ...)
> >   local fix = arg
> >   return function (...)
> >            return f (unpack (fix), unpack (arg))
> >          end
> > end
>
> Creates a second local referring to the same table, then passes
> passes the same argument list to 'f' twice.

No, one is for the args you want to fix (curry's arg) and one is the
arguments passed to the curried function (the anonymous function's arg).

-- 
http://www.mupsych.org/~rrt/ | impossible, a.  worth doing

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Eric Tetz-2
--- Reuben Thomas <[hidden email]> wrote:
> No, fix and arg refer to different tables.

Ahhhh... I see what you're doing now. Good idea. It allows the
closure to receive additional arguments when it's called.

However, it won't work as written because in the expression:

f(unpack(fix), unpack(arg))

f will only receive the first value returned by 'unpack(fix)' and
all the values returned by 'unpack(arg)' For instance, this code:

cb = curry( function(a,b,c) print(a,b,c) end, "a", "b", "d")
cb()
cb(1,2,3)

Will output:

a       nil     nil
a       1       2

Personally I've always found that behavior to be one of Lua's
warts.


__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

Reply | Threaded
Open this post in threaded view
|

Re: callback implementation details..

Philipp Janda
In reply to this post by Reuben Thomas-5
Am 18.10.03 01:01 schröbte Reuben Thomas:
Did you try this code? I think it is what you might be looking for,
actually. Although you can do it with unpack() etc.


Yes, curry is simply:

-- curry: Partially apply a function
--   f: function to apply partially
--   a1 ... an: arguments to fix
-- returns
--   g: function with ai fixed
function curry (f, ...)
  local fix = arg
  return function (...)
           return f (unpack (fix), unpack (arg))
         end
end

Your version does not work correctly.
If I say

local f = curry( print, 1, 2 )
f( 3, 4 )

I get:
1   3   4
but I should get
1   2   3   4

This is because only the first return value of unpack(fix) is used.
I got that problem with the following helper function:

local function dump( ... )
  io.stdout:write( unpack( arg ), "\n" )
  io.stdout:flush()
end

which only printed the first argument.

For the curry function to work you will need some table merging:

function curry2( f, ... )
  local fix = arg
  return function( ... )
           local params = {}
           for _,a in ipairs( fix ) do
             table.insert( params, a )
           end
           for _,a in ipairs( arg ) do
             table.insert( params, a )
           end
           return f( unpack( params ) )
         end
end


which is a lot simpler than messing around with C.


Philipp



Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Reuben Thomas-5
In reply to this post by Eric Tetz-2
> Ahhhh... I see what you're doing now. Good idea. It allows the
> closure to receive additional arguments when it's called.

That's what currying is.

> However, it won't work as written because in the expression:
>
> f(unpack(fix), unpack(arg))
>
> f will only receive the first value returned by 'unpack(fix)' and
> all the values returned by 'unpack(arg)' For instance, this code:

Thanks for pointing this out (and to Philipp). My mistake owing to a
mis-translation from Lua 4. Since I've not tried to curry on more than one
argument since then, I'd not noticed the problem.

For anyone who's interested, a working version that is a bit more
decomposed than Philipp's (and exposes two other useful functions in the
process) is:

-- @func table.clone: Make a shallow copy of a table, including any
-- metatable
--   @param t: table
-- returns
--   @param u: copy of table
function table.clone (t)
  local u = setmetatable ({}, getmetatable (t))
  for i, v in pairs (t) do
    u[i] = v
  end
  return u
end

-- @func table.merge: Merge two tables
-- If there are duplicate fields, u's will be used. The metatable of
-- the returned table is that of t
--   @param t, u: tables
-- returns
--   @param r: the merged table
function table.merge (t, u)
  local r = table.clone (t)
  for i, v in pairs (u) do
    r[i] = v
  end
  return r
end

-- curry: Partially apply a function
--   f: function to apply partially
--   a1 ... an: arguments to fix
-- returns
--   g: function with ai fixed
function curry (f, ...)
  local fix = arg
  return function (...)
           return f (table.merge (unpack (fix), unpack (arg)))
         end
end

Another useful functional is

-- compose: Compose some functions
--   f1 ... fn: functions to compose
-- returns
--   g: composition of f1 ... fn
--     args: arguments
--   returns
--     f1 (...fn (args)...)
function compose (...)
  local fns, n = arg, table.getn (arg)
    return function (...)
             for i = n, 1, -1 do
               arg = pack (fns[i](unpack (arg)))
             end
             return unpack (arg)
           end
  end
end

which is like currying, but one level up: it wraps up function
application rather than argument application. In lazy languages you don't
need compose.

ADVERT: All the code above is from my stdlib project, in CVS on
lua-users.org. I'm currently making over the code for Lua 5 (it's all
working in Lua 5, and I'm now "restyling" it a bit, mostly renaming the
functions into tables, but also more subtle Lua 5-ification). Unlike the
Wiki, CVS is still working fine for reading *and* writing. See
http://cvs.sourceforge.net/viewcvs.py/lua-users/stdlib/modules/

-- 
http://www.mupsych.org/~rrt/ | taciturn, n.  a silent pot

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

marcus.cf
In reply to this post by RLak-2
> -- curry: Partially apply a function
> --   f: function to apply partially
> --   a1 ... an: arguments to fix
> -- returns
> --   g: function with ai fixed
> function curry (f, ...)
>   local fix = arg
>   return function (...)
>            return f(
>              table.merge(unpack (fix), unpack (arg)))
>          end
> end

Shouldn't be
return f(unpack(table.merge(fix, arg))?

> Another useful functional is
> 
> -- compose: Compose some functions
> --   f1 ... fn: functions to compose
> -- returns
> --   g: composition of f1 ... fn
> --     args: arguments
> --   returns
> --     f1 (...fn (args)...)
> function compose (...)
>   local fns, n = arg, table.getn (arg)
>     return function (...)
>              for i = n, 1, -1 do
>                arg = pack (fns[i](unpack (arg)))
>              end
>              return unpack (arg)
>            end
>   end
> end
> 
> which is like currying, but one level up: it wraps up f
unction
> application rather than argument application. In lazy l
anguages you don't
> need compose.
> 
> ADVERT: All the code above is from my stdlib project, i
n CVS on
> lua-
users.org. I'm currently making over the code for Lua 5 (
it's all
> working in Lua 5, and I'm now "restyling" it a bit, mos
tly renaming the
> functions into tables, but also more subtle Lua 5-
ification). Unlike the
> Wiki, CVS is still working fine for reading *and* writi
ng. See
> http://cvs.sourceforge.net/viewcvs.py/lua-
users/stdlib/modules/
> 
> -- 
> http://www.mupsych.org/~rrt/ | taciturn, n.  a silent p
ot
> 



 
__________________________________________________________________________
Acabe com aquelas janelinhas que pulam na sua tela.
AntiPop-up UOL - É grátis!
http://antipopup.uol.com.br/



Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Reuben Thomas-5
> Shouldn't be
> return f(unpack(table.merge(fix, arg))?

Thanks.

-- 
http://www.mupsych.org/~rrt/ | Slow Pedestrian Crossing (Anon)

Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Marius Gheorghe
In reply to this post by Reuben Thomas-5
-- @func table.merge: Merge two tables
-- If there are duplicate fields, u's will be used. The metatable of
-- the returned table is that of t
--   @param t, u: tables
-- returns
--   @param r: the merged table
function table.merge (t, u)
  local r = table.clone (t)
  for i, v in pairs (u) do
    r[i] = v
  end
  return r
end

For the purpose of merging argument lists it appears that this table.merge
doesn't work quite as intended.
The tables (in essence both are arg) being merged for the purpose of
currying only use numerical indices (with exception of ['n'], of course). A
version of merge that uses ipairs (instead of pairs) and that appends at the
end of the table (instead of overwriting preexistent indices - which appears
to happen always in this case) should probably work better.
Marius Gheorghe


Reply | Threaded
Open this post in threaded view
|

RE: callback implementation details..

Reuben Thomas-5
> -- @func table.merge: Merge two tables
> -- If there are duplicate fields, u's will be used. The metatable of
> -- the returned table is that of t
> --   @param t, u: tables
> -- returns
> --   @param r: the merged table
> function table.merge (t, u)
>   local r = table.clone (t)
>   for i, v in pairs (u) do
>     r[i] = v
>   end
>   return r
> end
>
> For the purpose of merging argument lists it appears that this table.merge
> doesn't work quite as intended.

Oops. This is what I get for happily writing code without testing it.
Where I called "table.merge" I should have called "list.concat":

-- @func list.concat: Concatenate two lists
--   @param l: list
--   @param m: list
-- returns
--   @param n: result {l[1] ... l[table.getn (l)], m[1] ...
--     m[table.getn (m)]}
function list.concat (l, m)
  local n = {}
  for _, v in ipairs (l) do
    table.insert (n, v)
  end
  for _, v in ipairs (m) do
    table.insert (n, v)
  end
  return n
end

-- 
http://www.mupsych.org/~rrt/
penitent, a.  undergoing or awaiting punishment (Bierce)

Reply | Threaded
Open this post in threaded view
|

loadstring (...)

Reyn Vlietstra
In reply to this post by Reuben Thomas-5
Hi.

loadstring (string [, chunkname]) creates a function,
I'd like to be able to call that function with arguments,
meaning it should be a defined as a (...) function. It
doesnt seem to be.

I'm using this to implement serializable callbacks.
eg.

dialog = something
dialog.OnClick = Event:new()

dialog.OnClick:Add([[
print(unpack(arg))
]])

which I then load with loadstring, and execute when
the event is fired, a JIT callback.

Can any of you think/know about a better way to implement
serializable callbacks ? Does it make sense to have loadstring 
create a (...) function ?

Thanks
--
Reyn Vlietstra




Reply | Threaded
Open this post in threaded view
|

Re: loadstring (...)

Luiz Henrique de Figueiredo
>Can any of you think/know about a better way to implement
>serializable callbacks ?

Try using the bytecode instead of the source. See string.dump.

>Does it make sense to have loadstring create a (...) function ?

Yes. It's in our plans for 5.1: chunks will be vararg functions.
--lhf

12