On 19/10/13 12:01, Nikolay Pavlov wrote:
On Oct 19, 2013 10:05 AM, "Tony Mechelynck"
<[email protected] <mailto:[email protected]>> wrote:
>
> On 14/10/13 22:09, ZyX wrote:
>>
>> Since request for comments in thread with extended-funcref branch
patches has gone unnoticed I will repost it here. I currently have
somewhat working implementation of lambda functions in this branch and
want to discuss where to move on since any implementation I can imagine
has its downsides. “Somewhat working” implementation I have was done in
one of the easiest ways possible. Here is the doc I have written for new
lambdas:
>>
>>
>>
============================================================================================
>> lambda *expr-lambda*
>> ------
>> \arg1, ...: expr1 lambda function
>>
>> Lambda functions are the lightweight variant of |user-functions|.
Differences
>> between them are:
>>
>> 1. Body of the lambda function is an |expr1| and not a sequence of |Ex|
>> commands.
>> 2. Lambda function does not have its own scope dictionary. It does
have scope
>> dictionary for |a:var| though. |l:| scope dictionary is
inherited from the
>> place where lambda was defined (thus it is either |g:| scope
dictionary or
>> |l:| dictionary of the function that defined the lambda).
>> You see, it is poor man closure.
>> 3. If |a:var| is not found in lambda own scope dictionary it is
searched in
>> |a:| scope dictionary of the function where lambda was defined
(if any).
>> This does not apply to |a:000|, |a:0|, |a:1|, ... variables.
>> 4. There are no dictionary lambdas.
>> 5. Lambda is not globally recorded anywhere like |anonymous-function|.
>>
>> NOTE: lambda function records the whole scope dictionary in its body
and also
>> |a:| dictionary. That means that extensive generation of
lambdas and
>> exporting them outside of generator function may lead to a
huge memory
>> overhead.
>>
============================================================================================
>>
>> This is one of the easiest implementation. Commit with this
implementation was pushed to https://bitbucket.org/ZyX_I/vim, branch
extended-funcref-lambdas, but not to the mailing list (implementation is
mostly untested and definitely experimental). I have a few other
suggestion for lambdas:
>>
>> 0. Current state.
>>
>> Pros:
>> 1. Simplicity of implementation.
>> 2. No allocations for l: variables for lambdas.
>> 3. Has access to a: of the caller.
>> Cons:
>> 1. Lambda disallows freeing funccal structure until lambda is
deleted.
>> 2. No access to a:N variables. Requires modification of
find_var_in_ht to work. This likely may be worked around.
>> 3. No local variables. Though if one is using expressions it is
hard to manipulate with them.
>>
>> 1. Make lambdas have exactly one local dictionary allocated once at
creation. Modify eval7 to copy all used variables to this dictionary on
creation. Arguments still go to a: dictionary allocated on each lambda call.
>>
>> Pros:
>> 1. Does not hold funccal structure.
>> 2. Only those variables that are actually used will be recorded.
>> 3. It is a python-like closure.
>> 4. One less hash allocation compared to calling user function.
>> Cons:
>> 1. Requires likely not so trivial modifications of eval7 and also
modification of other eval* to pass down the reference to l: dictionary.
>> 2. One l: dictionary for all calls. Though if one is using … (see
cons 3. from p. 0.).
>> 3. No access to a: of the caller (or we will get cons 1. from p. 0.).
>>
>> 2. Like above, but arguments go to local dictionary. Dictionary
itself is copied on lambda invocation.
>>
>> Pros:
>> Same as above.
>> 4. Copying dictionary should probably be faster then creating and
populating a new one. Needs some profiling.
>> Cons:
>> Same as above.
>>
>> 3. Like the current state (0.), but also has its own l: dictionary.
>>
>> Pros:
>> Same as 0., except for 2.
>> 4. Own scope where you can place something.
>> 5. Adds a facility to create user functions that are real
closures (likely, but not necessary, limited to 2 nesting level; no
limit on nesting is a bit harder to implement, but it seems far from hard).
>> Cons:
>> Same as 0., except for 3.
>>
>>
>> // Note about the doc excerpt: anonymous functions are not recorded
anywhere *in extended-funcref branch*.
>>
>
> I don't understand the fundamental difference with setting a variable
to an expression in string form, so that it can later be :execute'd, as
is already done for several options: ":help expr'<Ctrl-D>" shows me ten
of those (not necessarily all different).
Expressions are invalid for :execute. I do not understand how &*expr
options are related.
:execute "let x =" lambda
Note that no string expressions take variable values with them. I am not
much fond of the workaround where expression accesses them from some
global variable.
Why not? I don't see this as a workaround: Write your expression as
using an argument with a predetermined name; then
:let lambda_arg = 123 * 456
:exe "let result =" lambda
:unlet lambda_arg " unless it has a persistent meaning
" one reason to omit the :unlet would be if you want to use
" the expression several times (possibly from different places)
" with the same argument (or one that changes less often than
" the expression is used); or else if the expression
" modifies its own argument (but the latter would be
" more appropriate for a full-fledged user function).
or for a number of arguments, the "argument" variable could be a List or
a Dictionary instead.
It is bad for GC: generally you cannot know when
expression and attached variables are no longer needed. Globals are
always bad for threading, if this will ever go into vim. It adds a bunch
of unneeded code: generate global name, record value there, put name
into the expression.
What is currently done for 'indentexpr' et al.? Even 'statusline' could
be regarded as a kind of "expression" with a peculiar syntax; but of
course it needs neither unletting nor garbage collection.
Best regards,
Tony.
--
<joost> Do you mean to say that I can read mail with vi too? ;-)
<Joey> Didn't you know that?
<Joey> :r /var/spool/mail/jk
-- Seen on #debian-mentors
--
--
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/groups/opt_out.