Привет, коллеги. Эта заметка относится к серии "Скриптовый язык" и описывает нововведения Вим версии 8: лямбда-выражения и замыкания. Модные темы добрались и до Вим!
Проверить, что у вас это есть, можно так:
echo has('lambda')
В коде тоже так можно проверить наличие данной возможности: через has().
Итак, что такое безымянная функция, она же лямбда-выражение? Это функция, создаваемая по месту и присваиваемая переменной. Это как бы выражение, возможно, с параметрами, которое не вычисляется сразу. Синтаксис в Вим:
{аргументы -> выражение}
Например,
:let f = {x -> x*x+1}
echo f(1)
Или
:let f = {x,y -> sqrt(x*x+y*y)}
Или даже без параметров:
:let pi = {-> arccos(-1.0)}
Выражение справа от -> является выражением: команды Вим там доступны только через execute.
Параметры доступны по имени без префикса a:, в отличие от функций.
Замыканием называется доступ к переменным и другим объектам из области видимости, которая может уже и не существовать. Пример:
function F(x)
let y = 42
return {z -> a:x+y-z}
endfuntion
let f=F(6)
echo f(8)
Увидим 40. Дело в том, что параметр функции x и локальная переменная y уже не существуют (функция-то завершилась), но замыкание помнит их значения. Функция F возвращает функцию, которая принимает один аргумент и возвращает число.
Это может быть полезно для создания "решеток на окнах". Ведь в Вим нельзя "закрыть" переменную, сделав ее недоступной, как это можно в языках с поддержкой объектно-ориентированной парадигмы. Можно только защитить от записи.
А замыкание позволяет "спрятать" переменную вообще. Технически ее и нет уже, а замыканию она доступна. Например, функция может запросить у пользователя секретное слово, создать лямбду, которая с ним работает, и вернуть ее: создать замыкание. Вызывая эту безымянную функцию, мы можем что-то делать с секретом, но не можем его ни прочитать, ни изменить.
Безымянные функции очень удобны для фильтров, прогоняющих список через алгоритм. Вот алгоритм и задается лямбдой:
map([1, 2, 3], {idx, val -> val * val})
Функция map применяет выражение ко всем элементам списка. Вместо выражения и можно использовать лямбду:
sort([3,7,2,1,4], {a, b -> a - b})
Здесь мы указываем явно выражение, сравнивающее два элемента.
Конечно, можно выражение и без того указать, используя предопределенные переменные. Но лямбды могут быть удобнее, тем более что и имена параметров вы сами задаете.
В общем, возможность есть, а уж применять или нет - это вам решать.