Multiple indexing (was: 'in' keyword today)

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

Multiple indexing (was: 'in' keyword today)

Dirk Laurie-2
2014-04-10 8:16 GMT+02:00 Dirk Laurie <[hidden email]>:

> 2014-04-10 6:50 GMT+02:00 Coroutines <[hidden email]>:
>
>> After thinking about this for a while I think it would be okay if
>> object literals were also allowed instead of only valid identfiers:
>>
>> 1, 2, 3 in { 'a', 'b', 'c' } --> return 'a', b', 'c'
>
> I'm happier with the notion that `x,y,z in tbl` is just a synonym for
> `tbl.x, tbl.y, tbl.z`. The above would be better described by
> { 'a', 'b', 'c' }[1,2,3] — but let's not hijack this thread.

Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
as a syntactic sugar, but as genuine multiple indexing overridable
by metamethods.

__index(tbl,key1,key2,...).
__newindex(tbl,key1,val1,key2,val2,...).

Invoked when tbl is not a table, when key1 is absent, and when more
than one key is supplied.

People who want tbl[i,j] to mean matrix-like indexing can do that
by metamethods.

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

steve donovan
On Thu, Apr 10, 2014 at 8:41 AM, Dirk Laurie <[hidden email]> wrote:
> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
> as a syntactic sugar, but as genuine multiple indexing overridable
> by metamethods.

It's a cool idea - I should say, it's still a cool idea since there
has been at least one thread about it before:

http://lua-users.org/lists/lua-l/2010-10/msg00761.html

People were rather concerned about efficiency at the time - you do not
want to slow the language down for an occaisional convenience

Also, it makes particular sense when overridden by extended
metamethods, but what precisely does it mean in their absence?  That
tbl[i,j] is tbl[i][j]?  That's what I would expect from my old Fortran
days....

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Coroutines
I do like this but I feel like it can only work for the
__index/__newindex metamethods where I'd be crazy enough to want it
for most of them.

__mod = function (...) ....

print('%s %s', 'string', 'interpolation')

At least with [] you know very easily where the arglist starts and
stops, it's not ambiguous.  Would be nice :-)

On Wed, Apr 9, 2014 at 11:49 PM, steve donovan
<[hidden email]> wrote:

> On Thu, Apr 10, 2014 at 8:41 AM, Dirk Laurie <[hidden email]> wrote:
>> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
>> as a syntactic sugar, but as genuine multiple indexing overridable
>> by metamethods.
>
> It's a cool idea - I should say, it's still a cool idea since there
> has been at least one thread about it before:
>
> http://lua-users.org/lists/lua-l/2010-10/msg00761.html
>
> People were rather concerned about efficiency at the time - you do not
> want to slow the language down for an occaisional convenience
>
> Also, it makes particular sense when overridden by extended
> metamethods, but what precisely does it mean in their absence?  That
> tbl[i,j] is tbl[i][j]?  That's what I would expect from my old Fortran
> days....
>

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Dirk Laurie-2
In reply to this post by steve donovan
2014-04-10 8:49 GMT+02:00 steve donovan <[hidden email]>:

> On Thu, Apr 10, 2014 at 8:41 AM, Dirk Laurie <[hidden email]> wrote:
>> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
>> as a syntactic sugar, but as genuine multiple indexing overridable
>> by metamethods.
>
> It's a cool idea - I should say, it's still a cool idea since there
> has been at least one thread about it before:
>
> http://lua-users.org/lists/lua-l/2010-10/msg00761.html
>
> People were rather concerned about efficiency at the time - you do not
> want to slow the language down for an occaisional convenience

Implementation would have very little more overhead than at present:
a simple check on lua_top for the number of arguments.

> Also, it makes particular sense when overridden by extended
> metamethods, but what precisely does it mean in their absence?  That
> tbl[i,j] is tbl[i][j]?  That's what I would expect from my old Fortran
> days....

No, it means just what I said at the beginning. Term-by-term indexing.
Vararg maps to variable return list. In effect a fallback metamethod
if you have failed to provide one yourself.

For tbl[i,j] to mean matrix indexing requires extra information, and therefore
a metamethod — but at present such metamethod can't use that syntax.

Let's not get onto the topic of Fortran. I'm even more of a Fortran apostate
than a Python apostate.

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Javier Guerra Giraldez
In reply to this post by Dirk Laurie-2
On Thu, Apr 10, 2014 at 1:41 AM, Dirk Laurie <[hidden email]> wrote:
> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
> as a syntactic sugar, but as genuine multiple indexing overridable
> by metamethods.


this is one of the very few changes I'd like to see.


--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

steve donovan
In reply to this post by Dirk Laurie-2
On Thu, Apr 10, 2014 at 9:27 AM, Dirk Laurie <[hidden email]> wrote:
> No, it means just what I said at the beginning. Term-by-term indexing.
> Vararg maps to variable return list. In effect a fallback metamethod
> if you have failed to provide one yourself.

Ah, I should read more carefully, and sorry to use the F-word so late
in the programming century. But the numerical guys will tend to read
it as multiple-indexing.

It's a little awkward with string keys : t["one","two"], but not awful.

Given f() that returns multiple values, is t[f()] intended to access
all those values? Because then we have the classic
propagation-of-multiple-values problem that gave you such grief with
string.gsub.

I think I'd need to see more elaborate code snippets to decide if this
is useful, or just cute...

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Javier Guerra Giraldez
On Thu, Apr 10, 2014 at 2:38 AM, steve donovan
<[hidden email]> wrote:
> Given f() that returns multiple values, is t[f()] intended to access
> all those values? Because then we have the classic
> propagation-of-multiple-values problem that gave you such grief with
> string.gsub.


I'd say yes, just like g(f()), where g() gets all return values from
f().  if you want just the first, you have to do g((f())).
specifically, if f() returns 1,2,3:

t[f()] => t[1,2,3]      -- like g(f())
t[(f())] = t[1]         -- like g((f()))
t[f(),4] => t[1,4]        -- like g(f(),4)
t[5,f()] => f[5,1,2,3]         -- like g(4,f())
t[f(),f()] => t[1,1,2,3]         -- like g(f(),f())


--
Javier

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

steve donovan
In reply to this post by Dirk Laurie-2
On Thu, Apr 10, 2014 at 8:41 AM, Dirk Laurie <[hidden email]> wrote:
> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
> as a syntactic sugar, but as genuine multiple indexing overridable
> by metamethods.

What about defining 'unpackt' so that 'unpackt(tbl,i,j,k)' achieves
the same result?

Granted, it could never be as fast as a hard-baked language feature,
but is fairly explicit and can of course be made to respect suitable
'synthetic' metamethods of tbl.

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Dirk Laurie-2
2014-04-10 9:45 GMT+02:00 steve donovan <[hidden email]>:
> On Thu, Apr 10, 2014 at 8:41 AM, Dirk Laurie <[hidden email]> wrote:
>> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
>> as a syntactic sugar, but as genuine multiple indexing overridable
>> by metamethods.
>
> What about defining 'unpackt' so that 'unpackt(tbl,i,j,k)' achieves
> the same result?

I actually have a whole library of `tuple` methods, which I find
I almost never use, but the name `unpackt` never occurred to me.

> Granted, it could never be as fast as a hard-baked language feature,
> but is fairly explicit and can of course be made to respect suitable
> 'synthetic' metamethods of tbl.

I'll retreat into Lua-the-whole Lua-and-nothing-but-Lua mode again, once
5.3 gets out of work, alpha and beta. For the moment, we're all mixing
dough for the fancy biscuits.

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

steve donovan
On Thu, Apr 10, 2014 at 10:04 AM, Dirk Laurie <[hidden email]> wrote:
> I actually have a whole library of `tuple` methods, which I find
> I almost never use, but the name `unpackt` never occurred to me.

As soon as I typed it, I realized it was ugly. How about vindex?

Performance should not be too shabby if done in C, like Renato's
varargs library:

http://www.tecgraf.puc-rio.br/~maia/lua/vararg/vararg.c

(this is one kind of manipulation which will always be much faster in C)

> 5.3 gets out of work, alpha and beta. For the moment, we're all mixing
> dough for the fancy biscuits.

Absolutely.  Intellectual entertainment and problem-space exploration.

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Eduardo Ochs
In reply to this post by Dirk Laurie-2
On Thu, Apr 10, 2014 at 3:41 AM, Dirk Laurie <[hidden email]> wrote:

> 2014-04-10 8:16 GMT+02:00 Dirk Laurie <[hidden email]>:
>> 2014-04-10 6:50 GMT+02:00 Coroutines <[hidden email]>:
>>
>>> After thinking about this for a while I think it would be okay if
>>> object literals were also allowed instead of only valid identfiers:
>>>
>>> 1, 2, 3 in { 'a', 'b', 'c' } --> return 'a', b', 'c'
>>
>> I'm happier with the notion that `x,y,z in tbl` is just a synonym for
>> `tbl.x, tbl.y, tbl.z`. The above would be better described by
>> { 'a', 'b', 'c' }[1,2,3] -- but let's not hijack this thread.
>
> Suppose that the notation tbl[i,j,k] meant tbl[i],tbl[j],tbl[k], not
> as a syntactic sugar, but as genuine multiple indexing overridable
> by metamethods.
>
> __index(tbl,key1,key2,...).
> __newindex(tbl,key1,val1,key2,val2,...).
>
> Invoked when tbl is not a table, when key1 is absent, and when more
> than one key is supplied.
>
> People who want tbl[i,j] to mean matrix-like indexing can do that
> by metamethods.
>

What about using __multiindex and __newmultiindex for the metamethods
for the new cases tbl[i,j] and tbl[i,j]=foo (or tbl[i,j]=foo,bar), and
keep using __index and __newindex for one-argument indices? Then there
will be no performance overhead, and no confusion...

Btw, I believe that the default behavior for both tbl[i,j] and
tbl[i,j]=foo should be just to raise an error - "multi-indexing
behavior not defined".

  Cheers,
    Eduardo Ochs
    [hidden email]
    http://angg.twu.net/
    http://angg.twu.net/ferramentas-para-ativistas.html

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Thomas Jericke
In reply to this post by steve donovan
On 04/10/2014 09:38 AM, steve donovan wrote:
> It's a little awkward with string keys : t["one","two"], but not awful.

Let's assume you could use the proposed "in" syntax for string keys:

Currently we have

t["one"]
and
t.one -> t["one"]

Additionally there would be:
t["one", "two"]
and
one, two in t -> t["one", "two"]



Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Thomas Jericke
In reply to this post by Dirk Laurie-2
On 04/10/2014 09:27 AM, Dirk Laurie wrote:

> 2014-04-10 8:49 GMT+02:00 steve donovan <[hidden email]>:
>
>> Also, it makes particular sense when overridden by extended
>> metamethods, but what precisely does it mean in their absence?  That
>> tbl[i,j] is tbl[i][j]?  That's what I would expect from my old Fortran
>> days....
> No, it means just what I said at the beginning. Term-by-term indexing.
> Vararg maps to variable return list. In effect a fallback metamethod
> if you have failed to provide one yourself.
>
> For tbl[i,j] to mean matrix indexing requires extra information, and therefore
> a metamethod — but at present such metamethod can't use that syntax.
>
I have a problem with that fallback. It doesn't give back the same
number of results as the usual metamethod.
You would have the same problems as if you were allowed to return
multiple results from the normal __index metamethod.

If I get your example right then:
matrix[x, y] whould return one result while table[x, y] would return two.

--
Thomas


Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Sean Conner
In reply to this post by Thomas Jericke
It was thus said that the Great Thomas Jericke once stated:

> On 04/10/2014 09:38 AM, steve donovan wrote:
> >It's a little awkward with string keys : t["one","two"], but not awful.
>
> Let's assume you could use the proposed "in" syntax for string keys:
>
> Currently we have
>
> t["one"]
> and
> t.one -> t["one"]
>
> Additionally there would be:
> t["one", "two"]
> and
> one, two in t -> t["one", "two"]

  Question:  What does the following mean?

        foo = { a = 1, b = 2, c = 3 }
        bar = { x = 'one' , y = 'two' , z = 'three' }

        a,b,c in foo = x,y,z in bar

  How about:

        foo = { a = 1 , b = 2 , c = 3 }
        bar = { x = 'one' , y = 'two' , z = 'three' }
        baz = { one = 'alpha' , two = 'beta' , three = 'gamma' }

        a,b,c in foo = x,y,z in bar in baz

  -spc (I can neither confirm nor deny my approval for this)


Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Sven Olsen
In reply to this post by steve donovan
Given f() that returns multiple values, is t[f()] intended to access
all those values? Because then we have the classic
propagation-of-multiple-values problem that gave you such grief with
string.gsub.

I think I'd need to see more elaborate code snippets to decide if this
is useful, or just cute...

Seconded.  We could certainly do some cute things with this semantic, but, I suspect the real bulk of the use cases would be people using it as syntax sugar on top of an existing multi-index table implementation.  And I'm not convinced that's a use case that justifies the costs of implementation.  Supporting the feature would require new VM opcodes, I think... 
Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Thomas Jericke
In reply to this post by Sean Conner


-----Original Message-----

> From: "Sean Conner" <[hidden email]>
> To: "Lua mailing list" <[hidden email]>
> Date: 10-04-2014 19:29
> Subject: Re: Multiple indexing (was: 'in' keyword today)
>
> It was thus said that the Great Thomas Jericke once stated:
> > On 04/10/2014 09:38 AM, steve donovan wrote:
> > >It's a little awkward with string keys : t["one","two"], but not awful.
> >
> > Let's assume you could use the proposed "in" syntax for string keys:
> >
> > Currently we have
> >
> > t["one"]
> > and
> > t.one -> t["one"]
> >
> > Additionally there would be:
> > t["one", "two"]
> > and
> > one, two in t -> t["one", "two"]
>
>   Question:  What does the following mean?
>
>      foo = { a = 1, b = 2, c = 3 }
>      bar = { x = 'one' , y = 'two' , z = 'three' }
>
>      a,b,c in foo = x,y,z in bar
I am not really sure if I should answer any questions including the words "foo" and "bar" but I try.

It probably should expand to:
foo["a", "b", "x"] = bar["x", "y", "z"]

Now the question is what should:
foo["a", "b", "x"] = 1, 2, 3 mean?
>
>   How about:
>
>      foo = { a = 1 , b = 2 , c = 3 }
>      bar = { x = 'one' , y = 'two' , z = 'three' }
>      baz = { one = 'alpha' , two = 'beta' , three = 'gamma' }
>
>      a,b,c in foo = x,y,z in bar in baz

Depends on the order of the in operarator, IMO it should be right to left:

foo["a", "b", "x"] = baz["bar"]["x", "y", "z"]

As  baz["bar"] is nil, you will get:

attempt to index field bar (a nil value)I think what you wanted to write is:

a,b,c in foo =  baz[x,y,z in bar]

--
Thomas





Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Sean Conner
It was thus said that the Great Thomas Jericke once stated:

>
>
> -----Original Message-----
> > From: "Sean Conner" <[hidden email]>
> >   How about:
> >
> >      foo = { a = 1 , b = 2 , c = 3 }
> >      bar = { x = 'one' , y = 'two' , z = 'three' }
> >      baz = { one = 'alpha' , two = 'beta' , three = 'gamma' }
> >
> >      a,b,c in foo = x,y,z in bar in baz
>
> Depends on the order of the in operarator, IMO it should be right to left:
>
> foo["a", "b", "x"] = baz["bar"]["x", "y", "z"]
>
> As  baz["bar"] is nil, you will get:
>
> attempt to index field bar (a nil value)I think what you wanted to write is:
>
> a,b,c in foo =  baz[x,y,z in bar]

  Interesting.  Because in my mind, I was parsing it as

        a,b,c in foo = (x,y,z in bar) in baz

  (left to right) That is:

        foo.a = baz[bar.x]
        foo.b = baz[bar.y]
        foo.c = baz[bar.z]

  I'm not saying I'm right or you are wrong, just how I would interpet it.

  -spc (Anybody?  Anybody?  Bueller?  Bueller?)


Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Petite Abeille

On Apr 10, 2014, at 10:04 PM, Sean Conner <[hidden email]> wrote:

>  -spc (Anybody?  Anybody?  Bueller?  Bueller?)

 Anyone know what this is? Anyone? Anyone? Anyone seen this before?  Something-d-o-o design. "Voodoo” design.

http://www.youtube.com/watch?v=uhiCFdWeQfA


Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Tom N Harris
In reply to this post by Thomas Jericke
On Thursday, April 10, 2014 01:56:36 PM Thomas Jericke wrote:
> I have a problem with that fallback. It doesn't give back the same
> number of results as the usual metamethod.
> You would have the same problems as if you were allowed to return
> multiple results from the normal __index metamethod.

So if multiple indexing were combined with multiple get/set on a table index
then we could end up with:

    sometable[somekey(...)] = anothertable[anotherkey(...)]

And that would be compiled into something like:

    a = gettable(_ENV, "sometable")
    b = gettable(_ENV, "somekey")
    c... = b(...)
    d = gettable(_ENV, "anothertable")
    e = gettable(_ENV, "anotherkey")
    f... = e(...)
    g... = gettable(d, f...)
    settable(a, c..., g...)

That last one is a problem. What is the signature of an opcode that takes two
variable lists of values?

I don't like either of these proposals, or the often mentioned tuple type. I
even used to be an advocate of tuples. But today's discussion has made me
doubt if it can be implemented efficiently. Too many variadic values will run
roughshod over register allocation.

--
tom <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: Multiple indexing (was: 'in' keyword today)

Thomas Jericke
In reply to this post by Sean Conner
On 04/10/2014 10:04 PM, Sean Conner wrote:

> It was thus said that the Great Thomas Jericke once stated:
>>
>> -----Original Message-----
>>> From: "Sean Conner" <[hidden email]>
>>>    How about:
>>>
>>>       foo = { a = 1 , b = 2 , c = 3 }
>>>       bar = { x = 'one' , y = 'two' , z = 'three' }
>>>       baz = { one = 'alpha' , two = 'beta' , three = 'gamma' }
>>>
>>>       a,b,c in foo = x,y,z in bar in baz
>> Depends on the order of the in operarator, IMO it should be right to left:
>>
>> foo["a", "b", "x"] = baz["bar"]["x", "y", "z"]
>>
>> As  baz["bar"] is nil, you will get:
>>
>> attempt to index field bar (a nil value)I think what you wanted to write is:
>>
>> a,b,c in foo =  baz[x,y,z in bar]
>    Interesting.  Because in my mind, I was parsing it as
>
> a,b,c in foo = (x,y,z in bar) in baz
>
>    (left to right) That is:
>
> foo.a = baz[bar.x]
> foo.b = baz[bar.y]
> foo.c = baz[bar.z]
>
>    I'm not saying I'm right or you are wrong, just how I would interpet it.
>
>    -spc (Anybody?  Anybody?  Bueller?  Bueller?)
>
>
You have a mistake in you inner interpreter right there

I wrote:
a,b,c in table -> table["a", "b", "c"]

If you want to expand left to right you get

a,b,c in foo = (x,y,z in bar) in baz

foo["a", "b", "c"] = (bar["x, y, z"]) in bat -- syntax error: name
expected near "(bar["x, y, z"])"

The statements in front of the in must be names not expressions, if you
start to mix them the code will get ambiguous. Example:

local t = {}
local table = { t = "lala" }
table[t] = "dada"

local test = t in table
print (test) -- lala or dada ?

--
Thomas


12