vim9 script and dictionary functions

115 views
Skip to first unread message

Christian Brabandt

unread,
May 7, 2021, 5:39:14 PM5/7/21
to vim...@vim.org
Hi,
I am starting to convert vim-airline to use vim9 script. vim-airline
makes much use of dictionary functions and I am not sure how to handle
this in vim9 script. Essentially, this comes down to the following
example:

function! Mylen() dict
return len(self.data)
endfunction

def! MyFun(dct: dict<any>): number
let length=dct.len()
return length
enddef

function! DoIt()
let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
call MyFun(mydict)
endfunction

call DoIt()

When sourcing this I get this error message:
Error detected while processing vim9script.vim[19]..function DoIt[2]..MyFun:
line 1:
E725: Calling dict function without Dictionary: Mylen
0

Is that expected or are dictionary functions no longer supported?

For reference, the same as legacy vimscript works just fine:
function! Mylen() dict
return len(self.data)
endfunction

func! MyFun2(dct)
return a:dct.len()
endfunc

function! DoIt()
let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
let length=MyFun2(mydict)
echo length
endfunction

call DoIt()

This works correctly.

Thanks,
Christian
--
Gerade dem, der vielen Ruhm hat, erlaubt man nicht die Anmaßung
irgendeines kleinsten Verdienstes (Nebenrühmchens), das vielleicht
andere haben, sobald er es nicht wirklich verdient. Man hält es für
Geiz und Raubsucht.
-- Jean Paul

Bram Moolenaar

unread,
May 8, 2021, 8:36:05 AM5/8/21
to vim...@googlegroups.com, Christian Brabandt, vim...@vim.org

Christian wrote:

> I am starting to convert vim-airline to use vim9 script. vim-airline
> makes much use of dictionary functions and I am not sure how to handle
> this in vim9 script. Essentially, this comes down to the following
> example:
>
> function! Mylen() dict
> return len(self.data)
> endfunction
>
> def! MyFun(dct: dict<any>): number
> let length=dct.len()
> return length
> enddef
>
> function! DoIt()
> let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
> call MyFun(mydict)
> endfunction
>
> call DoIt()
>
> When sourcing this I get this error message:
> Error detected while processing vim9script.vim[19]..function DoIt[2]..MyFun:
> line 1:
> E725: Calling dict function without Dictionary: Mylen
> 0
>
> Is that expected or are dictionary functions no longer supported?

Yes, in Vim9 script we try to avoid inventing mechanisms that don't
exist in other languages. Dict functions were a kind of cheap fix to
get object-like behavior. I don't think this exists in this form in any
popular language. Python comes closest, passing "self" as the first
argument. Which I actually don't like. And it's one of the reasons why
Python can be slow.

What we also need to avoid is that methods on a dict can be added and
removed at runtime. That makes it slow, the function can't be found at
compile time, it might not be there (yet).

The vague plan was to implement classes properly. Then we can have type
checking, compile the functions, etc. That's quite a bit of work, thus
I have been postponing it.

> For reference, the same as legacy vimscript works just fine:
> function! Mylen() dict
> return len(self.data)
> endfunction
>
> func! MyFun2(dct)
> return a:dct.len()
> endfunc
>
> function! DoIt()
> let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
> let length=MyFun2(mydict)
> echo length
> endfunction
>
> call DoIt()
>
> This works correctly.

Perhaps we need to keep this as legacy functions for now. That at least
seems like a better solution than making a quick ugly fix in Vim9 script.

--
hundred-and-one symptoms of being an internet addict:
247. You use www.switchboard.com instead of dialing 411 and 555-12-12
for directory assistance.

/// 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 ///
Reply all
Reply to author
Forward
0 new messages