Slicing ideas

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

Re: Slicing ideas

Rob Kendrick-2
On Tue, Apr 03, 2012 at 12:54:34AM +0800, Alex Davies wrote:
> So..
>
> Just playing with this thought experiment, what does t[f()] do?
> Multiret into a __slice, falling back into an __index with the first
> return (or nil if none) if not found?
>
> Sounds messy on the vm. Or does it truncate to one argument and just
> call __index?

This is why I brought the discussion here; there are complexities.

> I'm not sold on the idea personally. I'd rather __index, __newindex
> were expanded to support multiple arguments if anything is to be
> done.
>
> Once you do that though, It's a bit how deep does the rabbit hole
> go? ie can you return multiple values from __slice? Can you assign
> multiple values to __newslice?
>
> ie would you want this to be able to be made to work:
>
> t[1,3] = 3,4,5

No.  There's only one item on the LHS, but many on the RHS.  Same rules
apply.

B.

Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Rob Kendrick-2
In reply to this post by Mike Pall-38
On Mon, Apr 02, 2012 at 06:57:43PM +0200, Mike Pall wrote:
> Alex Davies wrote:
> > I bet the very thought of that would make Mike break out in hives...
>
> I guess there's nothing new under the moon. 7.42 years ago I wrote:
>
>   http://lua-users.org/lists/lua-l/2004-11/msg00083.html
>
>   Subject: Things not to add to Lua (slices)

The name of the metamethod was throw-away.  The only thing that was
suggested was allowing multiple values inside [], and them be passed to
a metamethod orthagonally.  Different metamethod was only suggested to
maintain backwards compatibility.

B.

Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Thomas Jericke
In reply to this post by Rob Kendrick-2

On Mon, Apr 2, 2012 at 11:47 AM, Rob Kendrick <[hidden email]> wrote:

>
>
> foo = t[1, 2, 3] -> __slice(t, 1, 2, 3)
> t[1, 2, 3] = foo -> __newslice(t, foo, 1, 2, 3)
>
> Notes:
>      * Avoids reuse of __index and __newindex, due to stickyness
>        making it compatible with existing code.
>      * Syntax is backwards compatible with existing table
>        deferencing.
>      * __index and __newindex implementations can simply call the
>        slice equivalent if they want to share functionality.
>      * Slicing either in or out should raise a runtime error if there
>        isn't a suitable metamethod.
>      * From a different angle, a table deference is just a function
>        call waiting to be discovered.
>
Maybe my solution is to simple for your needs, but I think this is already possible using tables as indices.

I just hacked this little code as demonstation:
mt = {
__index = function(t,k)
  local r = {}
  for i=k[1],k[2] do
    r[i] = t[i]
  end
  return r
end,
__newindex = function(t,k,v)
  for i=k[1],k[2] do
    rawset(t, i, v)
  end
end

}
t = {"a", "b", "c", "d"}

setmetatable(t, mt)
t[{5,20}] = 1
print(table.concat(t[{1,10}],":"))

The output is: a:b:c:d:1:1:1:1:1:1


  Maybe I am too naive, but I think this is already possible using tables as indexes.
 I just hacked this little code as example:
 mt = {  
 __index = function(t,k)
 local r = {}
 for i=k[1],k[2] do
 r[i] = t[i]
 end
 return r
 end,
 __newindex = function(t,k,v)
 for i=k[1],k[2] do
 rawset(t, i, v)
 end
 end
 }
 t = {"a", "b", "c", "d"}
 setmetatable(t, mt)
 t[{5,20}] = 1
 print(table.concat(t[{1,10}],":"))
 The output is: a:b:c:d:1:1:1:1:1:1

 
Now of course the t[{_,_}] syntax is not as nice as t[_,_] but it does the trick. Unfortunately it is not possible to make a solution by syntactic sugar as the syntax t{_,_} already translates to t({_,_}).



 Now this has the overhead of creating a table each time you make an access this way, but it's as flexible as it can get.



 You could also simulate the right hand side by defining the __call metamethod for your table, than you could write foo = t(1, 2, 3) --> __call(t, 1, 2, 3), this doesn't work on the LHS though.


--
Thomas





Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Rob Kendrick-2
On Thu, Apr 05, 2012 at 03:53:26PM +0200, [hidden email] wrote:
> Now of course the t[{_,_}] syntax is not as nice as t[_,_] but it does the trick. Unfortunately it is not possible to make a solution by syntactic sugar as the syntax t{_,_} already translates to t({_,_}).

It also limits the use: what if you wanted to pass one or more tables to
the handler?

ie, t[{1, 2}, {3, 4}]

B.

Reply | Threaded
Open this post in threaded view
|

Re[2]: Slicing ideas

Thomas Jericke


On Thu, Apr 05, 2012 at 17:13+0100 [hidden email] wrote:
Unfortunately it is not possible to make a solution by syntactic sugar as the syntax t{_,_} already translates to t({_,_}).
>
> It also limits the use: what if you wanted to pass one or more tables to
> the handler?
>
> ie, t[{1, 2}, {3, 4}]
How about: t[{{1, 2}, {3, 4}}]

I actually can't think of a place where you can't store a list into the array part of a table with one exeption: A list with variable size that contains nils (as the array length of a table is defined by the first nil). Actually this problem can also be solved by storing the number of elements somewhere in the table e.g. t[0] = number of elements.

--
Thomas





Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Rob Kendrick-2
On Thu, Apr 05, 2012 at 06:59:41PM +0200, [hidden email] wrote:

>
>
> On Thu, Apr 05, 2012 at 17:13+0100 [hidden email] wrote:
> Unfortunately it is not possible to make a solution by syntactic sugar as the syntax t{_,_} already translates to t({_,_}).
> >
> > It also limits the use: what if you wanted to pass one or more tables to
> > the handler?
> >
> > ie, t[{1, 2}, {3, 4}]
> How about: t[{{1, 2}, {3, 4}}]

If you're content with this syntax, you'll be just as content, if not
more so, with t({1, 2}, {3, 4}).

B.

Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Krunal Rao

But with this you cannot set :p

KR

On Apr 5, 2012 11:45 PM, "Rob Kendrick" <[hidden email]> wrote:
On Thu, Apr 05, 2012 at 06:59:41PM +0200, [hidden email] wrote:
>
>
> On Thu, Apr 05, 2012 at 17:13+0100 [hidden email] wrote:
> Unfortunately it is not possible to make a solution by syntactic sugar as the syntax t{_,_} already translates to t({_,_}).
> >
> > It also limits the use: what if you wanted to pass one or more tables to
> > the handler?
> >
> > ie, t[{1, 2}, {3, 4}]
> How about: t[{{1, 2}, {3, 4}}]

If you're content with this syntax, you'll be just as content, if not
more so, with t({1, 2}, {3, 4}).

B.

Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Thomas Jericke
On 06-04-2012 01:51, [hidden email] wrote:
Subject: Re: Slicing ideas

But with this you cannot set :p

KR

One solution would be to have a __newcall metamethod that is called when you assign to a function call:

t(1,2,3) = foo -> __newcall(t,foo,1,2,3)

It looks a little funny though, but after all Ada lives well with having () for both indexing and function calls.


--

Thomas

Reply | Threaded
Open this post in threaded view
|

Re: Slicing ideas

Coda Highland
On Fri, Apr 6, 2012 at 4:28 AM,  <[hidden email]> wrote:

> On 06-04-2012 01:51, [hidden email] wrote:
>
> Subject: Re: Slicing ideas
>
> But with this you cannot set :p
>
> KR
>
> One solution would be to have a __newcall metamethod that is called when you
> assign to a function call:
>
> t(1,2,3) = foo -> __newcall(t,foo,1,2,3)
>
> It looks a little funny though, but after all Ada lives well with having ()
> for both indexing and function calls.

I can get behind the idea of having function invocations acting as an lvalue.

/s/ Adam

12