OneScript
OneScript copied to clipboard
Лямбды
Лямбда-функции решат все ваши проблемы (с)
Концепт
МойМассив = Новый Массив;
МойМассив.Добавить(1);
МойМассив.Добавить(2);
МойМассив.ДляКаждого( (Элемент) => Сообщить(Элемент))
// 1
// 2
МойМассив.ДляКаждого( (Элемент) =>
Лямбда
Сообщить("Я многострочная лямбда");
Сообщить(Элемент);
КонецЛямбды
);
// вместо Лямбда...КонецЛямбды можно попробовать Процедура...КонецПроцедуры, но имхо это смерть для парсера
//в порядке бреда
Процедура МояЛямбда(Элемент)
Сообщить(Элемент);
КонецПроцедуры
МойМассив.ДляКаждого(МояЛямбда);
// Да-да, функции высшего порядка
СП в духе Массив.ДляКаждого(Лямда(Элемент)); --- процедура ДляКаждого принимает в качестве аргумента Лямбда-функцию с одним параметром. В качестве параметра передаётся элемент коллекции.
Аналогично для структуры и КлючИЗначение и прочих Соответствий
//в порядке бреда
Процедура МояЛямбда(Элемент)
Сообщить(Элемент);
КонецПроцедуры
МойМассив.ДляКаждого(МояЛямбда);
вот это не сработает. МояЛямбда - это имя переменной. такой вот затык в жёлтом синтаксисе
МояЛямбда - это имя переменной. такой вот затык в жёлтом синтаксисе
Почему нельзя расширить поиск по именам функций? Ты же не сможешь объявить переменную с именем, совпадающим с уже имеющейся процедурой
Мне давно хочется вариант МойМассив.ДляКаждого(МояЛямбда);
но как отличить от переменной?
в 1С и 1скрипте вроде как разрешено иметь одно имя для переменной и метода
Ты же не сможешь объявить переменную с именем, совпадающим с уже имеющейся процедурой
могу же
Мне как раз больше нравятся функции высшего порядка. ИМХО они лучше на язык 1С ложатся.
Хотя и варианты с лямбдой очень интересны.
Как раз нужно избавиться от всяких обработок оповещения и т.п.
а мне нравятся обработки оповещения :) они код делают площе. Повидал я говногода, полюбил 1С за отсутствие всего на свете.
Да, дает объявить переменную и функцию с одинаковым именем...
Уймитесь, нехристи! Пишите на ноде :)
А вообще, если вспомнить, что язык 1С - это Basic, переведенный промтом, то кошерный синтаксис должен выглядеть вот-так: https://msdn.microsoft.com/ru-ru/library/bb531253.aspx
@EvilBeaver если я правильно понимаю, то в 1с-варианте для многострочной лямбды это будет примерно так:
МойМассив.ДляКаждого( Функция (Параметр)
Сообщить(Параметр);
Сообщить("я многострочная лямбда");
КонецФункции);
Либо надеяться на корректную расстановку скобок, тогда можно опустить КонецФункции
Во-первых, предлагаю различать лямбды и функции-объекты.
Лямбда-функция - это вложенная функция, которая видит контекст родительской функции и может "захватывать" (по умному - "делать замыкание") переменных родительской функции. Тут вылезают сразу уши областей видимости, правила замыкания переменных и прочее. См. правила видимости в жаваскрипте.
Тут выходит несложная доработка компилятора и очень большая доработка самой виртуальной машины, ибо там все сложно с областями переменных.
И более простой вариант: объявлять функции как и сейчас, но иметь возможность их передать куда-либо. Т.е. реализовать что-то типа делегатов из мира C#. Это проще, ибо без замыканий. Доработка машины вроде бы не потребуется.
Процедура МоеДействие()
Сообщить("Привет");
КонецПроцедуры
Действие = Функция(МоеДействие); // чтобы не ломать обратную совместимость Массив = Массив();
Действие(); // вызов
Процедура МоеДействие()
Сообщить("Привет");
КонецПроцедуры
Процедура Действие()
// ага, привет!!!
КонецПроцедуры
Действие = Функция(МоеДействие); // чтобы не ломать обратную совместимость Массив = Массив();
Действие(); // вызов
Тогда и вызов нужно делать типа
Действие = Функция(МоеДействие); // чтобы не ломать обратную совместимость Массив = Массив();
Вызвать Действие(); // вызов
@dmpas почему?
Ааа. понял. Ну тот можно пойти по тому пути, что ввести правила вызова:
- По скобкам сначала вызывается обычная функция (как раньше)
- Если таковой нет и скобки применены к делегату - вызываем его
- Если скобки применены к неделегату (Числу, например) - выбрасываем исключение
По скобкам сначала вызывается обычная функция (как раньше)
Может наоборот лучше делегата сперва вызывать? Перегрузка метода и все такое
@Stepa86 пример привести можешь, когда именно такое поведение нужно?
@EvilBeaver Сходу не могу. Но мне кажется более логичным вызывать сперва делегата или вообще падать в исключение в этой ситуации
У меня один аргумент: описанное мной поведение реализовать проще. Ну и второй аргумент - не доказано (примером) что нужно иное поведение.
@EvilBeaver для эксперементальной штуки первого аргумента более, чем достаточно
Оставлю тут ссылку на параллельное обсуждение: https://github.com/tsukanov-as/OneShell/issues/13