_SELF and _SUPER

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

_SELF and _SUPER

Soni "They/Them" L.
Can we get _SELF and _SUPER?

local x = 1
function f()
  local x = 2
  print(_SUPER.x) --> 1
end
print(f())

pcall(function(x)
  if x < 0 then error() end
  if x == 0 then return end
  print(x)
  _SELF(x-1)
end, 3) --> 3; 2; 1;

For performance, they would be translated by the compiler. Passing _SUPER around would copy all upvalues into a table, but for simplicity changing this table wouldn't change upvalues (e.g. no current syntactic construct can create a metatable).

_SELF and _SUPER would be indexable and callable.

(No idea what to say next. Idk, I'm just rambling I guess .-.)
-- 
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.
Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Dirk Laurie-2
2016-08-04 18:54 GMT+02:00 Soni L. <[hidden email]>:

> (No idea what to say next. Idk, I'm just rambling I guess .-.)

+1

Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Nagaev Boris
In reply to this post by Soni "They/Them" L.
On Thu, Aug 4, 2016 at 7:54 PM, Soni L. <[hidden email]> wrote:

> Can we get _SELF and _SUPER?
>
> local x = 1
> function f()
>   local x = 2
>   print(_SUPER.x) --> 1
> end
> print(f())
>
> pcall(function(x)
>   if x < 0 then error() end
>   if x == 0 then return end
>   print(x)
>   _SELF(x-1)
> end, 3) --> 3; 2; 1;
>
> For performance, they would be translated by the compiler. Passing _SUPER
> around would copy all upvalues into a table, but for simplicity changing
> this table wouldn't change upvalues (e.g. no current syntactic construct can
> create a metatable).
>
> _SELF and _SUPER would be indexable and callable.

Let me check that I understand you correctly.

_SELF would be callable and _SUPER would be indexable.

Can _SUPER be indexed with a value not known at compile time?

local xx = 1
do
  print(_SUPER[string.rep("x", 2)])
end

>
> (No idea what to say next. Idk, I'm just rambling I guess .-.)
>
> --
> Disclaimer: these emails may be made public at any given time, with or
> without reason. If you don't agree with this, DO NOT REPLY.



--


Best regards,
Boris Nagaev

Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 04/08/16 04:47 PM, Nagaev Boris wrote:

> On Thu, Aug 4, 2016 at 7:54 PM, Soni L. <[hidden email]> wrote:
>> Can we get _SELF and _SUPER?
>>
>> local x = 1
>> function f()
>>    local x = 2
>>    print(_SUPER.x) --> 1
>> end
>> print(f())
>>
>> pcall(function(x)
>>    if x < 0 then error() end
>>    if x == 0 then return end
>>    print(x)
>>    _SELF(x-1)
>> end, 3) --> 3; 2; 1;
>>
>> For performance, they would be translated by the compiler. Passing _SUPER
>> around would copy all upvalues into a table, but for simplicity changing
>> this table wouldn't change upvalues (e.g. no current syntactic construct can
>> create a metatable).
>>
>> _SELF and _SUPER would be indexable and callable.
> Let me check that I understand you correctly.
>
> _SELF would be callable and _SUPER would be indexable.

No you can use _SELF.name as an alias for the local `name` (simple
compiler optimizations can turn `_SELF.name` (as well as
`_SELF["name"]`) into just `name`).

You can also call _SUPER.

You can also do _SUPER._SUPER.

Note that the main chunk wouldn't have _SUPER (but it would have _SELF).

>
> Can _SUPER be indexed with a value not known at compile time?
>
> local xx = 1
> do
>    print(_SUPER[string.rep("x", 2)])
> end

Except for the do..end and _SUPER part, yes, that would work.

This wouldn't:

local xx = 1
_SELF[string.rep("x", 2)] = 3
print(xx) --> 1, not 3

Because for dynamic assignments _SELF would need a metatable. No current
Lua opcode ever produces a table that already has a metatable. _SELF and
_SUPER are special names however, which means they can behave specially
(e.g. one behaviour for _SELF.x and other compile-time constants,
another behaviour for _SELF[x] and other runtime values).

Another option would be to introduce "indirection" opcodes. E.g.

_SELF[x] = other

would translate into

GETTABLE (internal) [x] reg -- plain old gettable, I forgot the syntax;
(internal) would be a reserved table the compiler generates for things
using _SELF/_SUPER.
MOVEI reg [other] -- R(R(A)) =: R(B)

Note the R(R(A)) part.

>
>> (No idea what to say next. Idk, I'm just rambling I guess .-.)
>>
>> --
>> Disclaimer: these emails may be made public at any given time, with or
>> without reason. If you don't agree with this, DO NOT REPLY.
>
>

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Luiz Henrique de Figueiredo
In reply to this post by Soni "They/Them" L.
>  Can we get _SELF and _SUPER?

If you want to experiment with ideas like these, try writing a token filter
with my ltokenp. See http://lua-users.org/lists/lua-l/2016-05/msg00028.html

Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 04/08/16 07:23 PM, Luiz Henrique de Figueiredo wrote:
>>   Can we get _SELF and _SUPER?
> If you want to experiment with ideas like these, try writing a token filter
> with my ltokenp. See http://lua-users.org/lists/lua-l/2016-05/msg00028.html
>
That wouldn't really work here as I'd need some sort of indirect MOVE
opcode...

Also that wouldn't really solve the problem with upvalues with same name
as locals...

It has to be built into the parser/compiler/VM. But thanks anyway. :)

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Thomas Jericke
On 05.08.2016 00:47, Soni L. wrote:
>
>
> Also that wouldn't really solve the problem with upvalues with same
> name as locals...
>
>
>
 > Doctor, when I put the finger into my own eye it hurts!

 > Then don't put it there.

--
Thomas


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

steve donovan
On Fri, Aug 5, 2016 at 8:34 AM, Thomas Jericke <[hidden email]> wrote:
>> Doctor, when I put the finger into my own eye it hurts!
>
>> Then don't put it there.

Exactly.  Addiction to very short variable names leads to these symptoms.

Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Rain Gloom
Just do your own debug.* hacks, I'm fairly positive you can embedd some debug.getinfo and .getlocal in your _ENV's __index and do it.

On Fri, Aug 5, 2016 at 8:38 AM, steve donovan <[hidden email]> wrote:
On Fri, Aug 5, 2016 at 8:34 AM, Thomas Jericke <[hidden email]> wrote:
>> Doctor, when I put the finger into my own eye it hurts!
>
>> Then don't put it there.

Exactly.  Addiction to very short variable names leads to these symptoms.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 05/08/16 05:32 PM, Rain Gloom wrote:

> Just do your own debug.* hacks, I'm fairly positive you can embedd
> some debug.getinfo and .getlocal in your _ENV's __index and do it.
>
> On Fri, Aug 5, 2016 at 8:38 AM, steve donovan
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On Fri, Aug 5, 2016 at 8:34 AM, Thomas Jericke <[hidden email]
>     <mailto:[hidden email]>> wrote:
>     >> Doctor, when I put the finger into my own eye it hurts!
>     >
>     >> Then don't put it there.
>
>     Exactly.  Addiction to very short variable names leads to these
>     symptoms.
>
>
load(string.dump(chunk, true))() --> works with proposal, fails with
debug.* (not counting sandbox support, compile-time optimizations, etc)

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Sean Conner
It was thus said that the Great Soni L. once stated:

>
> On 05/08/16 05:32 PM, Rain Gloom wrote:
> >Just do your own debug.* hacks, I'm fairly positive you can embedd
> >some debug.getinfo and .getlocal in your _ENV's __index and do it.
> >
> >On Fri, Aug 5, 2016 at 8:38 AM, steve donovan
> ><[hidden email] <mailto:[hidden email]>> wrote:
> >
> >    On Fri, Aug 5, 2016 at 8:34 AM, Thomas Jericke <[hidden email]
> >    <mailto:[hidden email]>> wrote:
> >    >> Doctor, when I put the finger into my own eye it hurts!
> >    >
> >    >> Then don't put it there.
> >
> >    Exactly.  Addiction to very short variable names leads to these
> >    symptoms.
> >
> >
> load(string.dump(chunk, true))() --> works with proposal, fails with
> debug.* (not counting sandbox support, compile-time optimizations, etc)

  Why does this fail?  What doesn't work with debug.*?  What is the problem
you are trying to solve?  Just saying "it doesn't work" doesn't tell  *us*
much about what this is trying to do.

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 05/08/16 08:51 PM, Sean Conner wrote:

> It was thus said that the Great Soni L. once stated:
>> On 05/08/16 05:32 PM, Rain Gloom wrote:
>>> Just do your own debug.* hacks, I'm fairly positive you can embedd
>>> some debug.getinfo and .getlocal in your _ENV's __index and do it.
>>>
>>> On Fri, Aug 5, 2016 at 8:38 AM, steve donovan
>>> <[hidden email] <mailto:[hidden email]>> wrote:
>>>
>>>     On Fri, Aug 5, 2016 at 8:34 AM, Thomas Jericke <[hidden email]
>>>     <mailto:[hidden email]>> wrote:
>>>     >> Doctor, when I put the finger into my own eye it hurts!
>>>     >
>>>     >> Then don't put it there.
>>>
>>>     Exactly.  Addiction to very short variable names leads to these
>>>     symptoms.
>>>
>>>
>> load(string.dump(chunk, true))() --> works with proposal, fails with
>> debug.* (not counting sandbox support, compile-time optimizations, etc)
>    Why does this fail?  What doesn't work with debug.*?  What is the problem
> you are trying to solve?  Just saying "it doesn't work" doesn't tell  *us*
> much about what this is trying to do.
>
>    -spc
>
>
_SELF and _SUPER would make the compiler insert some things into the
bytecode that don't get erased/don't count as "debug info".

Using debug.* is literally relying on debug info. And order of
locals/upvalues. And so on. None of that is guaranteed, while the
proposal can use mechanisms not yet available and stuff.

For example, this code:

local x;
print(_SELF["x"])

Could produce a sequence of opcodes like:

R(1) = nil -- e.g. LOADNIL
R(2) = Upval[1][K(1)] -- e.g. GETTABUP
R(3) = K(2)[K(3)] -- e.g. GETTABLEK / GETTABLE with a statically
allocated table constant
R(3) = R(R(3)) -- e.g. MOVEI / move from indirect register (because the
I is on the right, and the RHS is the source)
R(2)(R(3)) -- e.g. CALL

where:

K(1) = "print"
K(2) = statically allocated table: {["x"] = 1}
K(3) = "x"

This would be for reading only. For writing, it'd use R(R(x)) = R(y)
(e.g. IMOVE) instead. For calling, it'd retrieve the current function
from the call stack or something. For passing it around, it'd copy all
locals into a table, maybe set a __call metamethod as well.

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Sean Conner
It was thus said that the Great Soni L. once stated:

>
> _SELF and _SUPER would make the compiler insert some things into the
> bytecode that don't get erased/don't count as "debug info".
>
> Using debug.* is literally relying on debug info. And order of
> locals/upvalues. And so on. None of that is guaranteed, while the
> proposal can use mechanisms not yet available and stuff.
>
> For example, this code:
>
> local x;
> print(_SELF["x"])
>
> Could produce a sequence of opcodes like:
>
> R(1) = nil -- e.g. LOADNIL
> R(2) = Upval[1][K(1)] -- e.g. GETTABUP
> R(3) = K(2)[K(3)] -- e.g. GETTABLEK / GETTABLE with a statically
> allocated table constant
> R(3) = R(R(3)) -- e.g. MOVEI / move from indirect register (because the
> I is on the right, and the RHS is the source)
> R(2)(R(3)) -- e.g. CALL
>
> where:
>
> K(1) = "print"
> K(2) = statically allocated table: {["x"] = 1}
> K(3) = "x"
>
> This would be for reading only. For writing, it'd use R(R(x)) = R(y)
> (e.g. IMOVE) instead. For calling, it'd retrieve the current function
> from the call stack or something. For passing it around, it'd copy all
> locals into a table, maybe set a __call metamethod as well.

  To what end?  What problem does this solve?  What you one use this for?

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 05/08/16 11:44 PM, Sean Conner wrote:

> It was thus said that the Great Soni L. once stated:
>> _SELF and _SUPER would make the compiler insert some things into the
>> bytecode that don't get erased/don't count as "debug info".
>>
>> Using debug.* is literally relying on debug info. And order of
>> locals/upvalues. And so on. None of that is guaranteed, while the
>> proposal can use mechanisms not yet available and stuff.
>>
>> For example, this code:
>>
>> local x;
>> print(_SELF["x"])
>>
>> Could produce a sequence of opcodes like:
>>
>> R(1) = nil -- e.g. LOADNIL
>> R(2) = Upval[1][K(1)] -- e.g. GETTABUP
>> R(3) = K(2)[K(3)] -- e.g. GETTABLEK / GETTABLE with a statically
>> allocated table constant
>> R(3) = R(R(3)) -- e.g. MOVEI / move from indirect register (because the
>> I is on the right, and the RHS is the source)
>> R(2)(R(3)) -- e.g. CALL
>>
>> where:
>>
>> K(1) = "print"
>> K(2) = statically allocated table: {["x"] = 1}
>> K(3) = "x"
>>
>> This would be for reading only. For writing, it'd use R(R(x)) = R(y)
>> (e.g. IMOVE) instead. For calling, it'd retrieve the current function
>> from the call stack or something. For passing it around, it'd copy all
>> locals into a table, maybe set a __call metamethod as well.
>    To what end?  What problem does this solve?  What you one use this for?
>
>    -spc
>
>
-- Example 1
print((function(x, y) return x == 0 and (y or 1) or _SELF(x-1, x*(y or
1)) end)(3)) --> 6

-- Example 2
local function a()
end
local function b()
end
local function c()
end

return function(x)
   for i, opcode in ipairs(x) do
     local op, arg1, arg2, arg3 = table.unpack(opcode)
     _SUPER[op](arg1, arg2, arg3)
   end
end

Etc. _SELF is more useful than _SUPER, all things considered.

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Sean Conner
It was thus said that the Great Soni L. once stated:
>
>
> On 05/08/16 11:44 PM, Sean Conner wrote:
> >   To what end?  What problem does this solve?  What you one use this for?
> >
> -- Example 1
> print((function(x, y) return x == 0 and (y or 1) or _SELF(x-1, x*(y or
> 1)) end)(3)) --> 6

  Let me make myself perfectly clear---WHY do I want this?  WHAT does this
buy ME?  Not fake examples like the above which doesn't make a whole lot of
sense.  A REAL PROBLEM!  A debugger without the debug module?  What?

  -spc

Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Tim Hill
In reply to this post by Soni "They/Them" L.

On Aug 4, 2016, at 9:54 AM, Soni L. <[hidden email]> wrote:

Can we get _SELF and _SUPER?

local x = 1
function f()
  local x = 2
  print(_SUPER.x) --> 1
end
print(f())

pcall(function(x)
  if x < 0 then error() end
  if x == 0 then return end
  print(x)
  _SELF(x-1)
end, 3) --> 3; 2; 1;

For performance, they would be translated by the compiler. Passing _SUPER around would copy all upvalues into a table, but for simplicity changing this table wouldn't change upvalues (e.g. no current syntactic construct can create a metatable).

_SELF and _SUPER would be indexable and callable.

(No idea what to say next. Idk, I'm just rambling I guess .-.)

A more interesting question .. why do you need this? And, for your need, have you explored other ways to solve the problem within the existing Lua language?

For example, _SELF for functions is trivial…

do
local _SELF = function() … end
x = _SELF
end

—Tim


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 06/08/16 06:19 AM, Tim Hill wrote:

>
>> On Aug 4, 2016, at 9:54 AM, Soni L. <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> Can we get _SELF and _SUPER?
>>
>> local x = 1
>> function f()
>>   local x = 2
>>   print(_SUPER.x) --> 1
>> end
>> print(f())
>>
>> pcall(function(x)
>>   if x < 0 then error() end
>>   if x == 0 then return end
>>   print(x)
>>   _SELF(x-1)
>> end, 3) --> 3; 2; 1;
>>
>> For performance, they would be translated by the compiler. Passing
>> _SUPER around would copy all upvalues into a table, but for
>> simplicity changing this table wouldn't change upvalues (e.g. no
>> current syntactic construct can create a metatable).
>>
>> _SELF and _SUPER would be indexable and callable.
>>
>> (No idea what to say next. Idk, I'm just rambling I guess .-.)
>
> A more interesting question .. why do you need this? And, for your
> need, have you explored other ways to solve the problem within the
> existing Lua language?
>
> For example, _SELF for functions is trivial…
>
> do
> local _SELF = function() … end
> x = _SELF
> end
>
> —Tim
>
>

Well, you actually need to use "local function _SELF"

Also:

do
local function _SELF() print(_SELF) end
x = _SELF
_SELF = nil
end

x() --> nil

While a proper _SELF would be safe from such things.

I've used recursive pseudo-anonymous functions before. _SELF would make
them easier to use.

f((function()
   local function inside_anonymous(args, I, should, take)
   end
   return inside_anonymous
end)())

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Sean Conner
It was thus said that the Great Soni L. once stated:

> On 06/08/16 06:19 AM, Tim Hill wrote:
> >
> >A more interesting question .. why do you need this? And, for your
> >need, have you explored other ways to solve the problem within the
> >existing Lua language?
>
> I've used recursive pseudo-anonymous functions before. _SELF would make
> them easier to use.
>
> f((function()
>   local function inside_anonymous(args, I, should, take)
>   end
>   return inside_anonymous
> end)())

  You just need a Y-combinator:

        function Y(f)
          local function g(...) return f(g,...) end
          return g
        end

        print(Y(function(rec, x)
                        if x < 2 then
                                return 1
                        else
                                return x * rec(x-1)
                        end
                end)(5))

  That will allow you to call an anonymous function recurively from within
the anonymous function.  No need for _SELF in this case.

  -spc (Now, about that _SUPER ...  )


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Soni "They/Them" L.


On 06/08/16 05:30 PM, Sean Conner wrote:

> It was thus said that the Great Soni L. once stated:
>> On 06/08/16 06:19 AM, Tim Hill wrote:
>>> A more interesting question .. why do you need this? And, for your
>>> need, have you explored other ways to solve the problem within the
>>> existing Lua language?
>> I've used recursive pseudo-anonymous functions before. _SELF would make
>> them easier to use.
>>
>> f((function()
>>    local function inside_anonymous(args, I, should, take)
>>    end
>>    return inside_anonymous
>> end)())
>    You just need a Y-combinator:
>
> function Y(f)
>  local function g(...) return f(g,...) end
>  return g
> end
>
> print(Y(function(rec, x)
> if x < 2 then
> return 1
> else
> return x * rec(x-1)
> end
> end)(5))
>
>    That will allow you to call an anonymous function recurively from within
> the anonymous function.  No need for _SELF in this case.
>
>    -spc (Now, about that _SUPER ...  )
>
>

That doesn't solve the dynamic variable indexing issue.

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: _SELF and _SUPER

Sean Conner
It was thus said that the Great Soni L. once stated:

>
> On 06/08/16 05:30 PM, Sean Conner wrote:
> >   You just need a Y-combinator:
> >
> > function Y(f)
> >  local function g(...) return f(g,...) end
> >  return g
> > end
> >
> > print(Y(function(rec, x)
> > if x < 2 then
> > return 1
> > else
> > return x * rec(x-1)
> > end
> > end)(5))
> >
> >   That will allow you to call an anonymous function recurively from within
> >the anonymous function.  No need for _SELF in this case.
>
> That doesn't solve the dynamic variable indexing issue.

  Oh, I'm sorry I failed to read your mind again.  I thought that was what
_SUPER was for.  I'm so sorry you have to reject MY ATTEMPT to give you
something you could use and grovel that I have to have your proposal
explained to me like I'm five.

  -spc (Why do I even bother?)


12