lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I don't really understand how to use this mail list correctly from gmail. But

I just want something like this not as crutch but as usual case for regular use.

function pure_function(fn)
    return load("local _ENV={} return function "..fn.." end")()
end

function strict_pure_function(fn)
    return load([[
        function strict(s)
            return setmetatable({},{
                __index=function(t,n)
                    if s[n]==nil then error("no "..n.." defined",3) end
                    return s[n]
                end,
                __newindex=function(t,n,v)
                    if s[n]==nil then error("no "..n.." defined",3) end
                    s[n]=v
                end,
            })
        end
        local _ENV=strict{} return function ]]..fn.." end")()
end


local a=0
b=0

f1=pure_function[[ (print)
    print(" 1) f1.a=",a)
    print(" 2) f1.b=",b)
    a=1
    b=1
    print(" 3) f1.a=",a)
    print(" 4) f1.b=",b)
]]

f1(_G.print,a,b)
print(" 5) a=",a)
print(" 6) b=",b)

print()

function f2()
    print(" 7) f2.a=",a)
    print(" 8) f2.b=",b)
    a=2
    b=2
    print(" 9) f2.a=",a)
    print("10) f2.b=",b)
end

f2()
print("11) a=",a)
print("12) b=",b)

print()

f3=strict_pure_function[[ (G,a,d)
    G.print("13) f3.a=",a)
    G.print("14) f3.b=",b)
    a=3
    b=3
    G.print("15) f3.a=",a)
    G.print("16) f3.b=",b)
]]

f3(_G,a,b) -- cause error: no b defined because mistyping argument

output:
 1) f1.a=    nil
 2) f1.b=    nil
 3) f1.a=    1
 4) f1.b=    1
 5) a=    0
 6) b=    0

 7) f2.a=    0
 8) f2.b=    0
 9) f2.a=    2
10) f2.b=    2
11) a=    2
12) b=    2

13) f3.a=    2
lua: /home/kovserg/Documents/sample.lua:65: no b defined
stack traceback:
    [C]: in function 'error'
    [string "        function strict(s)..."]:4: in metamethod '__index'
    [string "        function strict(s)..."]:15: in function 'f3'
    /home/kovserg/Documents/sample.lua:65: in main chunk
 


сб, 6 апр. 2019 г. в 14:00, <lua-l-request@lists.lua.org>:
Send lua-l mailing list submissions to
        lua-l@lists.lua.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/lua-l-lists.lua.org

or, via email, send a message with subject or body 'help' to
        lua-l-request@lists.lua.org

You can reach the person managing the list at
        lua-l-owner@lists.lua.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of lua-l digest..."


Today's Topics:

   1. Re: New feature for lua (Roberto Ierusalimschy)
   2. Re: lua-l Digest, Vol 105, Issue 12 (Sergey Kovalev)
   3. Re: New feature for lua (Sean Conner)
   4. Re: lua-l Digest, Vol 105, Issue 12 (Sean Conner)
   5. Re: Fun math puzzle: cin(X) (Dirk Laurie)


----------------------------------------------------------------------

Message: 1
Date: Fri, 5 Apr 2019 09:51:07 -0300
From: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Subject: Re: New feature for lua
To: Lua mailing list <lua-l@lists.lua.org>
Message-ID: <20190405125107.GB6116@arraial.inf.puc-rio.br" target="_blank">20190405125107.GB6116@arraial.inf.puc-rio.br>
Content-Type: text/plain; charset=us-ascii

> It should work similar to usual function except
> all variables used inside are implicitly local
> no access to any upvalues or global namespace _G
> So it could interact with arguments it was passed.
>
> This allows to isolate parts of code from whole program.
>
> In lua 5.3.4 there is no way to do it.
>
> [...]

I don't see why one needs this, and how it is related to sandboxing.

A function can only access an upvalue if it is physically written inside
its scope. Any code coming from outside cannot access any upvalue in
your code. It looks like you want to protect your code from itself. As
already said, if you don't want to access an upvalue in your own code,
just don't do it. (For globals, _ENV seems to solve the issue.)

Anyway, if your code is so convoluted that you don't know what is what,
just write that function as the first thing in its chunk, before any
local declaration:

    -- first line in your chunk
    do
      local _ENV = nil
      function aSoCalledPureFunction ()
        ...
      end
    end

-- Roberto



------------------------------

Message: 2
Date: Fri, 5 Apr 2019 21:20:00 +0300
From: Sergey Kovalev <kovserg33@gmail.com>
Subject: Re: lua-l Digest, Vol 105, Issue 12
To: lua-l@lists.lua.org
Message-ID:
        <CALDKP3118A6eFp5YzF55C6An8PnLhAsD+GB9ytUJqmnxJ-KkyA@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

SXQgd2lsbCBub3Qgc3VycHJpc2UgcGVvcGxlLiBUaGV5IHdpbGwgdXNlIGZ1bmN0aW9ucyBhcyBi
ZWZvcmUuCiJwdXJlX2Z1bmN0aW9uIiBpcyBhZGRpdGlvbmFsIGZlYXR1cmUgZm9yIHNwZWNpYWwg
Y2FzZXMKSXQgY291bGQgaXNvbGF0ZSBwb3NzaWJsZSBzaWRlIGVmZmVjdHMsIGR1ZSB0byBtaXNz
IHR5cGluZyBvciBmb3JnZXQgdG8KZGVmaW5lIGxvY2FsIHZhcmlhYmxlIG9yIGFueSBvdGhlciBy
ZWFzb25zLgpNb3Jlb3ZlciBpdCBjb3VsZCBiZSBjb21iaW5lZCB3aXRoIGNvbW1vbiBmdW5jdGlv
biB0byBhY2hpZXZlIGRpZmZlcmVudAphaW1zLgpUaGUgc2ltcGxlcyB3YXkgaXMKCnB1cmVfZnVu
Y3Rpb24gZm4oYXJncykKLS0gLi4uCmVuZAoKY29udmVydGVkIGludG8gc29tZXRoaW5nIGxpa2Ug
dGhpcwoKaXNvbGF0ZV9hbGxfdXB2YWx1ZXMoYXJncywgLS0gc29tZWhvdyByZW1vdmUgYWxsIHVw
dmFsdWVzCmZ1bmN0aW9uIGZuKF9FTlYsYXJncykKLS0gLi4uCmVuZCkKCgrQv9GCLCA1INCw0L/R
gC4gMjAxOSDQsy4g0LIgMTQ6MDAsIDxsdWEtbC1yZXF1ZXN0QGxpc3RzLmx1YS5vcmc+OgoKPiBT
ZW5kIGx1YS1sIG1haWxpbmcgbGlzdCBzdWJtaXNzaW9ucyB0bwo+ICAgICAgICAgbHVhLWxAbGlz
dHMubHVhLm9yZwo+Cj4gVG8gc3Vic2NyaWJlIG9yIHVuc3Vic2NyaWJlIHZpYSB0aGUgV29ybGQg
V2lkZSBXZWIsIHZpc2l0Cj4KPiBodHRwOi8vbGlzdG1hc3Rlci5wZXBwZXJmaXNoLm5ldC9jZ2kt
YmluL21haWxtYW4vbGlzdGluZm8vbHVhLWwtbGlzdHMubHVhLm9yZwo+Cj4gb3IsIHZpYSBlbWFp
bCwgc2VuZCBhIG1lc3NhZ2Ugd2l0aCBzdWJqZWN0IG9yIGJvZHkgJ2hlbHAnIHRvCj4gICAgICAg
ICBsdWEtbC1yZXF1ZXN0QGxpc3RzLmx1YS5vcmcKPgo+IFlvdSBjYW4gcmVhY2ggdGhlIHBlcnNv
biBtYW5hZ2luZyB0aGUgbGlzdCBhdAo+ICAgICAgICAgbHVhLWwtb3duZXJAbGlzdHMubHVhLm9y
Zwo+Cj4gV2hlbiByZXBseWluZywgcGxlYXNlIGVkaXQgeW91ciBTdWJqZWN0IGxpbmUgc28gaXQg
aXMgbW9yZSBzcGVjaWZpYwo+IHRoYW4gIlJlOiBDb250ZW50cyBvZiBsdWEtbCBkaWdlc3QuLi4i
Cj4KPgo+IFRvZGF5J3MgVG9waWNzOgo+Cj4gICAgMS4gUmU6IE5ldyBmZWF0dXJlIGZvciBsdWEg
KHN0ZXZlIGRvbm92YW4pCj4KPgo+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPgo+IE1lc3NhZ2U6IDEKPiBEYXRl
OiBGcmksIDUgQXByIDIwMTkgMDg6MzA6MjQgKzAyMDAKPiBGcm9tOiBzdGV2ZSBkb25vdmFuIDxz
dGV2ZS5qLmRvbm92YW5AZ21haWwuY29tPgo+IFN1YmplY3Q6IFJlOiBOZXcgZmVhdHVyZSBmb3Ig
bHVhCj4gVG86IEx1YSBtYWlsaW5nIGxpc3QgPGx1YS1sQGxpc3RzLmx1YS5vcmc+Cj4gTWVzc2Fn
ZS1JRDoKPiAgICAgICAgIDwKPiBDQStaTVNfdnZQRzRwcmkxOHF3c3ZiUnRZZDBYWG43RzkwTmRf
M0ExZ3JQb3E3WmhvbXdAbWFpbC5nbWFpbC5jb20+Cj4gQ29udGVudC1UeXBlOiB0ZXh0L3BsYWlu
OyBjaGFyc2V0PSJVVEYtOCIKPgo+IE9uIEZyaSwgQXByIDUsIDIwMTkgYXQgODoxMiBBTSBTZXJn
ZXkgS292YWxldiA8a292c2VyZzMzQGdtYWlsLmNvbT4gd3JvdGU6Cj4gPgo+ID4gTGV0IGlucm9k
dWNlIG5ldyByZXNlcnZlZCB3b3JkICJwdXJlX2Z1bmN0aW9uIiBpbnRvIGx1YS4KPiA+IEl0IHNo
b3VsZCB3b3JrIHNpbWlsYXIgdG8gdXN1YWwgZnVuY3Rpb24gZXhjZXB0Cj4gPiBhbGwgdmFyaWFi
bGVzIHVzZWQgaW5zaWRlIGFyZSBpbXBsaWNpdGx5IGxvY2FsCj4gPiBubyBhY2Nlc3MgdG8gYW55
IHVwdmFsdWVzIG9yIGdsb2JhbCBuYW1lc3BhY2UgX0cKPiA+IFNvIGl0IGNvdWxkIGludGVyYWN0
IHdpdGggYXJndW1lbnRzIGl0IHdhcyBwYXNzZWQuCj4KPiBUaGUgJ2ltcGxpY2l0bHkgbG9jYWwn
IGJpdCB3aWxsIGJlIGEgc3VycHJpc2UgdG8gcGVvcGxlLCBJIHRoaW5rLgo+IEdsb2JhbC1hcy1k
ZWZhdWx0IGhhcyBtb3N0bHkgc2VydmVkIHVzIHdlbGwuCj4KPiBJJ20gd29uZGVyaW5nIGlmIHRo
aXMgY291bGQgbm90IGJlIGRvbmUganVzdCBhcyBhIGNoZWNrIHVzaW5nIGJ5dGVjb2RlCj4gLSBp
LmUuIGFubm90YXRlIGEgZnVuY3Rpb24gYXMgJ3B1cmUnIGluIHNvbWUgd2F5IGFuZCBsb29rIGF0
IHRoZQo+IGJ5dGVjb2RlIHRvIHNlZSBpZiBpdCBoYXMgYW55IHVwdmFsdWVzIG9yIGdsb2JhbHMg
cmVmZXJlbmNlZC4KPgo+Cj4KPiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPgo+IF9f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCj4gbHVhLWwgbWFp
bGluZyBsaXN0Cj4gbHVhLWxAbGlzdHMubHVhLm9yZwo+Cj4gaHR0cDovL2xpc3RtYXN0ZXIucGVw
cGVyZmlzaC5uZXQvY2dpLWJpbi9tYWlsbWFuL2xpc3RpbmZvL2x1YS1sLWxpc3RzLmx1YS5vcmcK
Pgo+Cj4gRW5kIG9mIGx1YS1sIERpZ2VzdCwgVm9sIDEwNSwgSXNzdWUgMTIKPiAqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKgo+Ci0tLS0tLS0tLS0tLS0tIG5leHQgcGFydCAt
LS0tLS0tLS0tLS0tLQpBbiBIVE1MIGF0dGFjaG1lbnQgd2FzIHNjcnViYmVkLi4uClVSTDogaHR0
cDovL2xpc3RtYXN0ZXIucGVwcGVyZmlzaC5uZXQvY2dpLWJpbi9tYWlsbWFuL3ByaXZhdGUvbHVh
LWwtbGlzdHMubHVhLm9yZy9hdHRhY2htZW50cy8yMDE5MDQwNS84NzY3MDMxZS9hdHRhY2htZW50
LTAwMDEuaHRtbAo=

------------------------------

Message: 3
Date: Fri, 5 Apr 2019 19:23:34 -0400
From: Sean Conner <sean@conman.org>
Subject: Re: New feature for lua
To: Lua mailing list <lua-l@lists.lua.org>
Message-ID: <20190405232334.GB26493@brevard.conman.org" target="_blank">20190405232334.GB26493@brevard.conman.org>
Content-Type: text/plain; charset=us-ascii

It was thus said that the Great Sergey Kovalev once stated:
> Let inroduce new reserved word "pure_function" into lua.
> It should work similar to usual function except
> all variables used inside are implicitly local
> no access to any upvalues or global namespace _G
> So it could interact with arguments it was passed.

  So having read the rest of the messages in this thread, I think I
following what you are trying to do.  So instead of the following:

function fromjulianday(jd)
  local a = jd + 32044
  local b = (4 * a + 3) // 146097
  local c = a - (b * 146097) // 4
  local d = (4 * c + 3) // 1461
  local e = c - (1461 * d) // 4
  local m = (5 * e + 2) // 153

  return {
    day   = e - (153 * m + 2) // 5 + 1,
    month = m + 3 - 12 * (m // 10),
    year  = b * 100 + d - 4800 + m // 10
  }
end

You could instead write this as:

pure_function fromjulianday(jd)
  a = jd + 32044
  b = (4 * a + 3) // 146097     
  c = a - (b * 146097) // 4       
  d = (4 * c + 3) // 1461     
  e = c - (1461 * d) // 4     
  m = (5 * e + 2) // 153     

  return {
    day   = e - (153 * m + 2) // 5 + 1,     
    month = m + 3 - 12 * (m // 10),     
    year  = b * 100 + d - 4800 + m // 10     
  }
end

Or would it have to be?

pure_function fromjulianday(_ENV,jd) -- I don't use _ENV
  a = jd + 32044
  b = (4 * a + 3) // 146097           
  c = a - (b * 146097) // 4             
  d = (4 * c + 3) // 1461           
  e = c - (1461 * d) // 4           
  m = (5 * e + 2) // 153           

  return {
    day   = e - (153 * m + 2) // 5 + 1,     
    month = m + 3 - 12 * (m // 10),     
    year  = b * 100 + d - 4800 + m // 10     
  }
end 

  Is this what you are proposing?

  To me, a "pure" function is one that only relies upon the parameters given
to it, it has no access to any data outside itself.  So for Lua, no globals
(or _ENV[]) or upvalues.  It a compiled langauge like Haskell such pure
functions can be replaced at compile time in certain circumstances with its
result.  For example:

        x = sin(math.pi)

at compile time x could be replaced with 0 with math.pi is a constant. [1]

  -spc

[1]     There's more to this optimization than what I've given here.
        Languages that support this type of optimization can track the
        contents of variables and find constants as parameters even if used
        through a variable, for example:

                pure function foo(x)
                  a = 5
                  b = 6
                  x = x * a + math.sin(b)
                  return x
                end

        The compiler can determine that a and b are not modified after
        assignment, so the function can be reduced to:

                -- replace variables with constants
                pure function foo(x)
                  x = x * 5 + math.sin(6)
                  return x
                end

                -- substitute results of pure functions
                pure function foo(x)
                  x = x * 5 + -0.27941549819893
                  return x
                end

                -- remove reassignment of x
                pure function foo(x)
                  return x * 5 - 0.27941549819893
                end

        Furthermore, if foo() is ever called with a constant, it too could
        be called at compile time, since it's marked as "pure" so it only
        depends upon values given to it.



------------------------------

Message: 4
Date: Fri, 5 Apr 2019 19:32:30 -0400
From: Sean Conner <sean@conman.org>
Subject: Re: lua-l Digest, Vol 105, Issue 12
To: Lua mailing list <lua-l@lists.lua.org>
Message-ID: <20190405233230.GC26493@brevard.conman.org" target="_blank">20190405233230.GC26493@brevard.conman.org>
Content-Type: text/plain; charset=us-ascii

It was thus said that the Great Sergey Kovalev once stated:
> It will not surprise people. They will use functions as before.
> "pure_function" is additional feature for special cases
> It could isolate possible side effects, due to miss typing or forget to
> define local variable or any other reasons.

  I use luacheck to prevent typos and forgetting to define local variables.
Running luacheck over this:

function fromjulianday(jd)
  a = jd + 32044
  b = (4 * a + 3) // 146097
  c = a - (b * 146097) // 4
  d = (4 * c + 3) // 1461
  e = c - (1461 * d) // 4
  m = (5 * e + 2) // 153

  return {
    day   = e - (153 * m + 2) // 5 + 1,
    month = m + 3 - 12 * (m // 10),
    year  = b * 100 + d - 4800 + m // 10
  }
end

produces

Checking jd.lua                                    21 warnings

    jd.lua:1:10: setting non-standard global variable fromjulianday
    jd.lua:2:3: setting non-standard global variable a
    jd.lua:3:3: setting non-standard global variable b
    jd.lua:3:12: accessing undefined variable a
    jd.lua:4:3: setting non-standard global variable c
    jd.lua:4:7: accessing undefined variable a
    jd.lua:4:12: accessing undefined variable b
    jd.lua:5:3: setting non-standard global variable d
    jd.lua:5:12: accessing undefined variable c
    jd.lua:6:3: setting non-standard global variable e
    jd.lua:6:7: accessing undefined variable c
    jd.lua:6:19: accessing undefined variable d
    jd.lua:7:3: setting non-standard global variable m
    jd.lua:7:12: accessing undefined variable e
    jd.lua:10:13: accessing undefined variable e
    jd.lua:10:24: accessing undefined variable m
    jd.lua:11:13: accessing undefined variable m
    jd.lua:11:27: accessing undefined variable m
    jd.lua:12:13: accessing undefined variable b
    jd.lua:12:23: accessing undefined variable d
    jd.lua:12:34: accessing undefined variable m

  I'm not aware of any tool that can check for global usage, but something
like luacheck could probably be written to report global and upvalue usage
by function. 

> Moreover it could be combined with common function to achieve different
> aims.
> The simples way is
>
> pure_function fn(args)
> -- ...
> end
>
> converted into something like this
>
> isolate_all_upvalues(args, -- somehow remove all upvalues
> function fn(_ENV,args)
> -- ...
> end)

  Could you give a better example of this?  I'm not following the example
given.  Are you just collecting any upvalues into a custom environment for a
function? 

  -spc




------------------------------

Message: 5
Date: Sat, 6 Apr 2019 08:45:40 +0200
From: Dirk Laurie <dirk.laurie@gmail.com>
Subject: Re: Fun math puzzle: cin(X)
To: Lua mailing list <lua-l@lists.lua.org>
Message-ID:
        <CABcj=tkrA_RVjVrC5g+jsXS_pj_7+UfKb_jb+st-=6QNjDhy8w@mail.gmail.com>
Content-Type: text/plain; charset="UTF-8"

Op Do. 4 Apr. 2019 om 23:25 het Egor Skriptunoff
<egor.skriptunoff@gmail.com> geskryf:
>
> On Thu, Apr 4, 2019 at 2:14 AM Albert Chan wrote:
>>
>> Comes across a fun math puzzle. :-)
>> Design a function cin(X), such that cin(cin(cin(X))) = sin(X)
>>
>
> The most straightforward approach is
> to build Taylor series of cin(x) one term at a time.
[code snipped]
> This implementation works only if x is in the range from (-0.7) to (+0.7)
> That's because of floating point arithmetic is approximate.
> Exact arithmetic of fractions (with arbitrary long numerator and denominator) must be used instead.

No, the reason is that the convergence radius of the Maclaurin series
is only about 0.7. There are at least two ways around that:

1. Use a nonlinear transformation (epsilon algorithm, Levin's U etc)
to sum the series.
2. Apply analytic continuation. E.g. use this method to calculate cin
and enough derivatives at say pi/6, then calculate a Taylor series
round pi/6, etc.

I can't guarantee that either approach will work. Unfortunately I am
travelling and am typing this in an idle half-hour, so I can't try it
out now.

Problems of this kind are subtle and often have no unique solution.
Additional hypotheses are sometimes needed. The convergence
acceleration method in effect assumes that cin has no singularities
worse than poles near the region of interest. The analytic
continuation approach works if for example cin is analytic in an
ellipse with foci at (0,0) and (2.019,0). There is no reason to
suppose that the two answers will be the same. The very neat trick
which the designer of the puzzle certainly wanted solvers to see, does
not require that cin is analytic anywhere except at 0. This answer may
well be different from the other two.

Personally, I am very fond of the U transform because it produces an
asymptotic series, i.e. the answers initially seem to converge but
then diverge. The user is thus warned that there is some non-polar
singularity or excessive roundoff propagation, and the point where
this happens is merely a "best practical" answer for the given data.

Sorry, we are straying from Lua, but since for example discussions on
finite state machines have been conducted on the list recently, a
little computational complex analysis can't hurt :-)

-- Dirk



------------------------------

_______________________________________________
lua-l mailing list
lua-l@lists.lua.org
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/lua-l-lists.lua.org


End of lua-l Digest, Vol 105, Issue 13
**************************************