Vim9: Difference in output returned by function() and funcref()

16 views
Skip to first unread message

Yegappan Lakshmanan

unread,
Dec 8, 2021, 10:13:31 PM12/8/21
to vim_dev
Hi,

If you run the below script:

--------------------------------------------
vim9script
def g:Test1(): void
enddef
echomsg function('g:Test1')
echomsg funcref('g:Test1')
--------------------------------------------

The following output is produced:

function('g:Test1')
function('Test1')

Note that in the second line the scope "g:" is missing. I expected that the
same output will be produced by both function() and funcref().

Regards,
Yegappan

Yegappan Lakshmanan

unread,
Dec 8, 2021, 10:31:00 PM12/8/21
to vim_dev
Hi,
I see the same problem with legacy scripts also. So this is not related to Vim9.

---------------------------------------------------------------------
func g:Test1()
endfunc
echomsg function('g:Test1')
echomsg funcref('g:Test1')
---------------------------------------------------------------------

- Yegappan

Bram Moolenaar

unread,
Dec 9, 2021, 4:27:46 AM12/9/21
to vim...@googlegroups.com, Yegappan Lakshmanan
With a funcref a pointer to the function is used, thus the scope is not
directly relevant. With function() it stores the name as it was given,
to be looked up later. Thus it should be OK to get a different name.

But it would be clearer for the funcref to output funcref('Test1').
I wonder what trouble it would cause if we change that now.
Unless there is a practical reason, I rather leave it as it is.

--
hundred-and-one symptoms of being an internet addict:
10. And even your night dreams are in HTML.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Yegappan Lakshmanan

unread,
Dec 9, 2021, 10:09:17 AM12/9/21
to Bram Moolenaar, vim_dev
Hi Bram,

On Thu, Dec 9, 2021 at 1:27 AM Bram Moolenaar <Br...@moolenaar.net> wrote:
>
>
> Yegappan wrote:
>
> > If you run the below script:
> >
> > --------------------------------------------
> > vim9script
> > def g:Test1(): void
> > enddef
> > echomsg function('g:Test1')
> > echomsg funcref('g:Test1')
> > --------------------------------------------
> >
> > The following output is produced:
> >
> > function('g:Test1')
> > function('Test1')
> >
> > Note that in the second line the scope "g:" is missing. I expected that the
> > same output will be produced by both function() and funcref().
>
> With a funcref a pointer to the function is used, thus the scope is not
> directly relevant. With function() it stores the name as it was given,
> to be looked up later. Thus it should be OK to get a different name.
>
> But it would be clearer for the funcref to output funcref('Test1').
> I wonder what trouble it would cause if we change that now.
> Unless there is a practical reason, I rather leave it as it is.
>

This causes a problem in Vim9 when setting an option like 'omnifunc'
to a funcref(). I am working on adding the support for setting these
options to a funcref/lambda in Vim9 (before patch 8.2.3765). When this
option is set to a global funcref:

var Fn: func = funcref('g:Myomnifunc')
&omnifunc = Fn

This fails with the error 'Myomnifunc' function is not found. This works
if function() is used instead of funcref(). This is because, when funcref()
is converted to a string (by tv2string()), the scope is not retained.
In a legacy script this works as the scope is global by default.
In Vim9, this fails as the default scope is script local and the function
is a global function. So the function is not found.

Regards,
Yegappan

Bram Moolenaar

unread,
Dec 9, 2021, 11:42:55 AM12/9/21
to vim...@googlegroups.com, Yegappan Lakshmanan
Oh, this is not about using funcref() instead of function(), but
prepending "g:". That should be OK.

--
hundred-and-one symptoms of being an internet addict:
18. Your wife drapes a blond wig over your monitor to remind you of what she
looks like.
Reply all
Reply to author
Forward
0 new messages