Chaining methods

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

Chaining methods

LunaticCoder
Hi,

I am having fun chaining string functions to process text in Textadept. This is not for the purists as I have been adding to the standard string library e.g.

    function string.pre(text,prefix)
        -- Prefix each line assuming "\n" for end of line
        return prefix..text:gsub("\n","\n"..prefix)
    end

Adding a few global functions to select and insert text (and define undo_action boundaries), I can then type in the command entry line "macros" e.g.

    selection():pre("--  "):gsub("Python ","Lua "):insert()
   
Repeatable and undo-able macros and not quite as unreadable as TECO commands :) 

Q1. Is there a limit to the number of chained string methods Lua 5.3 can process?

Q2. Is there any way to use chained methods for tables - in standard Lua 5.3?  
      This syntax appeals to me: 

    t = {"one","two","three"}
    print(t:insert("four"):sort():concat("\n"))

Kind Regards Gavin 
Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Felipe Tavares
For Q2, it is not possible  for all tables created with simple t={} syntax. It is possible if you create your tables with a custom constructor.

Em seg., 10 de fev. de 2020 às 17:53, Gavin Holt <[hidden email]> escreveu:
Hi,

I am having fun chaining string functions to process text in Textadept. This is not for the purists as I have been adding to the standard string library e.g.

    function string.pre(text,prefix)
        -- Prefix each line assuming "\n" for end of line
        return prefix..text:gsub("\n","\n"..prefix)
    end

Adding a few global functions to select and insert text (and define undo_action boundaries), I can then type in the command entry line "macros" e.g.

    selection():pre("--  "):gsub("Python ","Lua "):insert()
   
Repeatable and undo-able macros and not quite as unreadable as TECO commands :) 

Q1. Is there a limit to the number of chained string methods Lua 5.3 can process?

Q2. Is there any way to use chained methods for tables - in standard Lua 5.3?  
      This syntax appeals to me: 

    t = {"one","two","three"}
    print(t:insert("four"):sort():concat("\n"))

Kind Regards Gavin 


--
--
Felipe Tavares
Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Coda Highland
In reply to this post by LunaticCoder


On Mon, Feb 10, 2020 at 2:53 PM Gavin Holt <[hidden email]> wrote:
Hi,

I am having fun chaining string functions to process text in Textadept. This is not for the purists as I have been adding to the standard string library e.g.

    function string.pre(text,prefix)
        -- Prefix each line assuming "\n" for end of line
        return prefix..text:gsub("\n","\n"..prefix)
    end

Adding a few global functions to select and insert text (and define undo_action boundaries), I can then type in the command entry line "macros" e.g.

    selection():pre("--  "):gsub("Python ","Lua "):insert()
   
Repeatable and undo-able macros and not quite as unreadable as TECO commands :) 

Q1. Is there a limit to the number of chained string methods Lua 5.3 can process?

There's no real limit, no. It's just a normal expression, and there's not an arbitrary limit for how deeply expressions can nest.
 
Q2. Is there any way to use chained methods for tables - in standard Lua 5.3?  
      This syntax appeals to me: 

    t = {"one","two","three"}
    print(t:insert("four"):sort():concat("\n"))

Unfortunately, that doesn't work nearly so well in the generic case, because tables are Lua's fundamental compound data type. However, if you want to make a specific "list" structure that offers those things through the metatable (you could have a syntax like `t = list{"one", "two", "three"}`) that would be easy with no real limitations.

/s/ Adam
Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Pavel
In reply to this post by LunaticCoder
I like the idea of having a "table-type" default metatable, like for numbers
and strings.
And to set this metatable to "table" library (like for strings).
then things like t = {"one","two","three"}:insert("four"):sort(...) should
work.
patch is here: http://lua-users.org/lists/lua-l/2019-03/msg00080.html

Creating tables with special function that sets the metatable correctly also
fine, but would be nice to have an option to set it once for all the newly
created tables.

function list(t) return setmetatable(t, {__index = table}) end

t = list{"one","two"}:insert(...):




--
Sent from: http://lua.2524044.n2.nabble.com/Lua-l-f2524044.html

Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Sam Putman


On Wed, Feb 12, 2020 at 4:59 AM Pavel <[hidden email]> wrote:
I like the idea of having a "table-type" default metatable, like for numbers
and strings.
And to set this metatable to "table" library (like for strings).
then things like t = {"one","two","three"}:insert("four"):sort(...) should
work.
patch is here: http://lua-users.org/lists/lua-l/2019-03/msg00080.html

Creating tables with special function that sets the metatable correctly also
fine, but would be nice to have an option to set it once for all the newly
created tables.


 This is a reasonable patch, and would certainly constitute a convenience under some circumstances.

I think the reason Lua doesn't work this way, is that it imposes a speed penalty on any nil-returning lookup, to every table so created.

I can imagine realistic workflows in which a negative table lookup happens hundreds of thousands of times in a hot loop, like searching a large file for a single hash.  With this patch, the runtime would have to check the special table metatable for every one of those lookups, which would impact performance. 

Strings are different, any method chain that returns nil (e.g. ("foo"):not_defined()) is going to be a bug. 

Again, making a personal copy of Lua work this way is perfectly reasonable. But I don't think it should be added to the language, for this reason.

cheers,
-Sam.
Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Pavel
Sam Putman wrote
> On Wed, Feb 12, 2020 at 4:59 AM Pavel &lt;

> temp213@

> &gt; wrote:
> I think the reason Lua doesn't work this way, is that it imposes a speed
> penalty on any nil-returning lookup, to every table so created.

Good point, G(L)->mt[LUA_TTABLE], when used as default metatable for new
tables could still be equal to NULL by default.
But at least there would be an option to set it to table library or
whatsoever when required.



--
Sent from: http://lua.2524044.n2.nabble.com/Lua-l-f2524044.html

Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Sam Putman


On Sun, Feb 16, 2020 at 4:52 PM Pavel <[hidden email]> wrote:
Sam Putman wrote
> On Wed, Feb 12, 2020 at 4:59 AM Pavel &lt;

> temp213@

> &gt; wrote:
> I think the reason Lua doesn't work this way, is that it imposes a speed
> penalty on any nil-returning lookup, to every table so created.

Good point, G(L)->mt[LUA_TTABLE], when used as default metatable for new
tables could still be equal to NULL by default.
But at least there would be an option to set it to table library or
whatsoever when required.


`t()` is one more character than `{}` and could be defined like so:

local function t(tab) -- can be global in a long/complex program
   tab = tab or {}
   return setmetatable({}, table)
end

and you could call it with `t{}` to remind yourself what it does. 

This is what I'd do if I were planning to use such tables frequently.

cheers,
-Sam. 
Reply | Threaded
Open this post in threaded view
|

Re: Chaining methods

Pavel
Sure, it just looks a bit ugly when you have Lua based DSL and only such a
tables and still have to declare all of them like that. Global single
character function not the most beautiful thing.


Sam Putman wrote
> On Sun, Feb 16, 2020 at 4:52 PM Pavel &lt;

> temp213@

> &gt; wrote:
> `t()` is one more character than `{}` and could be defined like so:
>
> local function t(tab) -- can be global in a long/complex program
>    tab = tab or {}
>    return setmetatable({}, table)
> end
>
> and you could call it with `t{}` to remind yourself what it does.
>
> This is what I'd do if I were planning to use such tables frequently.
>
> cheers,
> -Sam.





--
Sent from: http://lua.2524044.n2.nabble.com/Lua-l-f2524044.html