On 7/2/06, Hari Krishna Dara <[EMAIL PROTECTED]> wrote:

On Thu, 29 Jun 2006 at 10:50pm, Eric Arnold wrote:

> Ok.  For starters, it seems that you *can* call a numbered function
> from anywhere:
>
>
>
> function! s:T()
>     echomsg "here"
>     echomsg 'SID=' . expand( '<sfile>' )
> endfunction
>
> let F=function('s:T')
> echomsg F()
>
> let F1 = function( '<SNR>66_T' )
> echomsg F1()
>
> echomsg string( F )
>
> let s:dict = {}
> function s:dict.init() dict
>     echomsg "in dict function"
> endfunction
>
> unlet! F2
> let F2 = s:dict.init
>
> call call(F2,[],{})
> " Note:  F2  is a global, so the numbered function declared for a local dict
> " is available to call globally.

Right, and that is what I intended by saying the Funcref's are behaving
as the original functions. Since numbered functions are accessible
globally, their Fucrefs are too (for that matter, I don't think you can
even call numbered functions directly, so this situation is not
completely same).


I'm still not getting it, I think.  Do you have a case where the
numbered function scheme will break down, or is it about the
callbacks, described below?


>
>
> On 6/29/06, Hari Krishna Dara <[EMAIL PROTECTED]> wrote:
> >
> > When Funcref's were introduced in Vim7, I expected them to work for
> > script-local functions, across scripts. The documentation didn't say
> > that, but it didn't say that it wouldn't either, and I thought that that
> > is one of its biggest uses (other than the actual intended
> > functionality, which is for implementing numbered functions). However, I

I'm not sure that there is a problem.  As with   C   code, if you have
the option of declaring a function global/local, public/private, etc.
I think Vim script is allowing these options.

Are you saying that you want to override the private script
declarations by declaring a function reference to a low enough level
pointer that it goes under the scope checker?


> > found that the Funcref references for such functions can't actually be
> > passed out to other scripts. This reduces the usefulness of this feature
> > as we can't register private functions to receive callbacks from other
> > scripts.


I think this is probably a request that it be more object oriented
than it is, ie. you really want object-scoped functions, not
script-scoped.  You seem to want the script localized, so it can't be
access generally, but then be public for registering callbacks.  This
seems like an object-scope problem.

I think that the numbered functions are allowed globally, probably
because they are intended to be used as you describe, for callbacks
from other scripts, since they are only created for the 'dict'
"object" functions, as far as I can tell.

> >
> > What is weird is that the the Funcref() actually behaves exactly like
> > the function name itself. Say you have a function called s:T() and say
> > the script id is 60. The Funcref obtained via function('s:T') can't be
> > called from outside the script, but if the Funcref is obtained using
> > function('<SNR>60_T'), then it will be fine. Also, a Funcref obtained


Both of these examples seem reasonable to me.  If you declare a
function reference to a script-local object,   s:T   then you don't
want it being accessed outside the script.  If you declare a
'<SNR>60_T'    reference, then you probably wanted to use it outside
the script, otherwise you wouldn't have gone through the trouble of
finding the script id.


> > using these two methods will not be to the same object, though you would
> > expect them to be. The below echoes 0:


How did you test what the object was?  Actually, I wouldn't expect it
to be the same object in any case, since each reference to it should
crease a new instance.   They both might refer to the same function
definition stored internally, but I don't know.

Also, we aren't talking about true "objects", just to be clear, but an
enhancment that allows object-oriented-like functional access.  This
limits the expectations we can have.


> >
> > echomsg function('s:T') is function('<SNR>60_T')
> >
> > where as the below echoes 1:
> >
> > echomsg function('s:T') is function('s:T')
>
>
> In this case you are *not* creating numbered functions, so the string
> value you use is what gets stored.

I think you misunderstood me, I didn't mean this.

>
> > The above two facts make Funcref counter-intuitive to understand. I
> > actually wonder why even a special function called function() was
> > required to obtain the Funcref in the first place (unlike in Python).


I suppose the Funcref function was probably created as a shortcut to
adding a more complex syntax modification to the language.


> >
> > There are other aspects of the new features that are very
> > counter-intuitive to me, whether I think in terms of Python or generic
> > "objects" in any language. The one which gets me the most is the
> > implicit typing of variables based on the initializer. For basic types
> > prior to Vim7 (integer and string), you could easily switch the value of
> > the variable from integer to string or vice versa, and the type() of the
> > variable would change, suggesting that it behaves like "duck typing" (as
> > per (wikipedia). But this observation can't be extended to the newer
> > object types, as the below will fail:
>
>
> The whole auto-initialize thing is a sticky wicket as far as I see it.
>  I'd love to have it initialize *all* cases where a name is
> references, either on RHS or LHS.
>
> However, I don't know whether this was intended by Bram as a way to
> implement type checking.

Do you mean E706 is probably unintentional in this case?


No, it is clearly intentional.  What I'm not sure about is whether
Bram intends Vim script to become more or less 'typed'.  Right now, it
isn't really consistent, since string and numbers are pretty loosely
typed, whereas the new Dict/List/Funcref are not.

I'm suspecting that this didn't fit into the schedule when Vim7 was released.



>
>
> > let a = {}
> > let a = []
> >
> > If the type of value determines the type of the variable, and if we are
> > merely dealing with references (assigning references instead of copying
> > objects), then why should the second statement above generate the below
> > error?
> >
> > E706: Variable type mismatch for: a
> >
> > Is there a standard for this type of language behavior? I didn't find
> > anything at this page: http://en.wikipedia.org/wiki/Dynamically_typed
> >
> > I declare all my script variables before they are used, and it hurts me
> > for the fact that you have to create an empty array or hash such that
> > these variable types are established correctly. But when it comes to a
> > Funcref type, it is lousy that you have to initialize the variable with
> > the Funcref of some random function so that the type of variable gets
> > established as Funcref.
>
>
> I'm not sure I see the problem in practice.  The only time you'd have
> to pre-define a funcref variable would be if you intended to try to
> use it when it was empty.  Are you really doing this?

No, that is not what I was saying. If there is a way to declare
variables without initializing them, I would have said something like:

Funcref var

However, the equivalent of the above is to say:

let var = function('somefunc')

The alternative is of course to just initialize the variable as and when
it is required, but I generally don't like this approach, as it is not
clear which variables are being used.


I want to have it auto-initialize whether in a "let" statement, or an
implicit setting via a function call argument.  And I'd like to be
able to test a value that hasn't been explicitly initialized, i.e.

if var1[1].elem1 > 0
...

where nothing about "var1" has been defined, but is used such that
automatic NULL elements would have to be created manually in any case.
If I really want it to fail if    [1]   or   .elem1   are not
defined, I can use 'exists()'  or 'has()'.  As I said elsewhere, it
should be an option, for backward compatibility.

Reply via email to