2016-07-14 17:21 GMT+03:00 Bram Moolenaar <[email protected]>:
>
> Ken Takata wrote:
>
>> 2016/7/14 Thu 15:43:11 UTC+9 mattn wrote:
>> > On Thursday, July 14, 2016 at 12:49:58 PM UTC+9, ZyX wrote:
>> > > 2016-07-13 19:17 GMT+03:00 mattn <[email protected]>:
>> > > > On Wednesday, July 13, 2016 at 4:11:59 AM UTC+9, Bram Moolenaar wrote:
>> > > >
>> > > > Well, I wonder this lambda will be useful. At the first, we hoped to 
>> > > > call statements in lambda. But the implementation you will include 
>> > > > into vim can't do because it only allow expressions. It's similar to 
>> > > > python's lambda. python's one doesn't allow statements. So usecase are 
>> > > > limited to use. I don't have strong opinion but I'm thinking that this 
>> > > > is an new expresssion or language for the lambda. It will demand to 
>> > > > learn the new expression for the users.
>> > >
>> > > Vim has `execute()`. Python-3 has `exec()` function (Python-2 has it
>> > > as a statement). Lambdas do not usually allow statements because they
>> > > are to be used in contexts which requires return value (e.g. in Python
>> > > this is sorted()/list.sort(), defaultdict(), re.sub[n] (BTW, it is
>> > > good idea to have `substitute(s, pattern, funcref, flags)` to work
>> > > like `substitute(s, pattern, '\=funcref(submatch(0), submatch(1), …)',
>> > > flags)`)). Lambdas are also used as a replacement for
>> > > `functools.partial` (python)/`function(fref, args, self)` (VimL) in
>> > > cases when they do not apply (e.g. when one needs to fix not the
>> > > first, but second or other arguments), but this requires closures.
>> >
>> > execute() doesn't have scope. So:
>> >
>> > call execute("let a = 1")
>> > echo 1
>> >
>> > This define new variable in global scope. I want anonymous function. If 
>> > execute() works with the scope, for example "let a = 1" mean "let l:a = 
>> > 1", It's so great.
>>
>> Currently "{args -> expr}" has its own scope.
>>
>>   :echo {-> execute("let a = 1")}()
>>   :echo a
>>   E121: Undefined variable: a
>>   E15: Invalid expression: a
>>
>>
>> BTW, because of its own scope, the following code doesn't work:
>>
>>   let list = [ /* some data */ ]
>>   let l:threshold = 10
>>   filter(list, {idx, val -> val > l:threshold})
>>
>> As ZyX pointed out, function() can be used (but redundant):
>>
>>   filter(list, function({th, idx, val -> val > th}, [l:threshold]))
>>
>> Closure might be useful for this, but it would be the next step.
>
> The question is, once we do implement closures, are all lambda's a
> closure or does it need to be defined?  In the last case we may wanto to
> explore now how that's done.
>
> If a closure is really cheap we may just make all lambda's a closure.
> But when it's not cheap, and they are used in something long-living like
> a callback, we should make it optional.
>
> I suspect it's not cheap, especially when lambda's live longer.  And
> they are created in a bigger function (e.g. to start a job).
>
> Instead of keeping the whole context, another way is to explicitly
> specify what to take from the context:
>    {arg, USE var -> expr}
> But that will look ugly to anyone using closures elsewhere.
>
> So long as we only use variables from the context, we could use a
> prefix, like in your example:
>    let l:threshold = 5
>    filter(list, {idx, val -> val > @l:threshold})
>
> But this requires parsing the expression to find out what is used from
> the context, which is tricky.
>
> So it might be best to have some way to specify a function or labmda is
> a closure.  For a function we can just add an argument, like we alrady
> have "dict" and "abort".
>
> Some alternatives:
>         { arg => expr }    (probably too subtle)
>         {@ arg -> expr }
>         { arg CTX => expr }
>         {{ arg -> expr }}
>
> Can't say any of these is nice.  At least none of them mean we have to
> change the syntax of lambda.

Parsing *expressions* is not that hard, so Python variant (“just catch
only those outer variables that are referenced there”) is completely
possible to implement. Rather easy if you are OK with yet another
global, requires passing additional argument through the evalN stack
if not. `{-> eval('outer_var')}` or `{-> get(l:, 'outer_var', 0)}` is
not going to work in this case though, but I would not say that Python
users have any problems with this.

Note: I mean that

    let l = []
    return {-> l}

will copy_tv value from outer scope’s l to lambda scope’s l without
any extensions to syntax at all. With global this needs only a small
extension to eval.c/eval7()/if() after switch()/if(len<=0)else to not
simply return `OK`, but to check whether some global (e.g. garray_T
with variable names) is not NULL and, if yes, determine the scope of
the variable and, if it appears to be l:, record variable name there.
Dealing with the resulting garray_T is trivial.

>
>
> --
>    GALAHAD hurries to the door and pushes through it.  As he leaves the room
>    we CUT TO the reverse to show that he is now in a room full of bathing
>    and romping GIRLIES, all innocent, wide-eyed and beautiful.  They smile
>    enchantingly at him as he tries to keep walking without being diverted by
>    the lovely sights assaulting his eyeballs.
>                  "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
>
>  /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
> ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
> \\\  an exciting new programming language -- http://www.Zimbu.org        ///
>  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
>
> --
> --
> You received this message from the "vim_dev" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> ---
> You received this message because you are subscribed to the Google Groups 
> "vim_dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui