MoonyLambda
Вы наверное знаете что сейчас проходит конкурс MoonJam. В общем суть в том что бы написать что-нибудь на MoonScript за неделю. Как говорил уже тотора, что-то серьезное за неделю не написать, но попробовать, поразвлечься, и написать что-нибудь интересное можно. В общем в этой теме буду показывать мой проект. И это... Библиотека для функционального программирования (далее просто - ФП)! Луа не предоставляет стандартных средств для ФП, потому я написал свою библиотеку. Чем то она похожа на реализацию такового функционала в языке Python, а чем то нет. Суть в том что функциональное программирование очень сильно упрощает работу с данными, например вместо пяти строк мы напишем одну строку.
Все примеры в MoonScript, но в спойлерах будет эквивалент на луа. f - библиотека подключенная через require
Начнем с самого простого, сложить массив чисел.
f.reduce f.add, {1, 2, 3} --> 6
Точно таким же образом, мы можем перемножить все числа f.mul вместо f.add, или соответственно разделить, вычесть или возвести в степень - f.div, f.sub и f.pow
А если, к примеру, нам нужно взять массив и выкинуть из него все нечетные числа. Это тоже возможно.
f.filter f.even, {1, 2, 3, 4} --> {2, 4}
А теперь, достанем все числа которые одновременно и меньше пяти, и четные. Это не составит труда
f.filter f.even, f.filter ((a) -> a < 5), {1, 2, 4, 5, 6, 7} --> {2, 4}
Хочу отметить, что нам не обязательно постоянно писать огромные цепочки из вызовов. Все функции в библиотеке каррированы.
selectEven = f.filter f.even
selectEven {1, 2, 3, 4, 5} --> {2, 4}
...Но мы можем каррировать свою функцию!
pow = f.curry (a, b) -> a ^ b
pow2 = pow 2
pow 3, 3 --> 27
pow2 3 --> 8
К слову, именно так определена в библиотеке функция f.pow.
Каррированная функция сама определяет, что ей вернуть, функцию которая примет недостающие аргументы, или результат. Мы можем каррировать функцию с любым количеством аргументов, так просто!
Реверс таблицы - легко, расплющить таблицу - легко, изменить таблицу - легко.
Но самое главное... Все функции чистые. Ни одна функция этой библиотеки не изменяет данные, и не зависит от внешних данных.
Вполне продакшен-ready пример:
first_letter = (a) -> a\sub 1, 1
f.group first_letter, {"Miku Chan", "Mayonnaise", "LeshaInc", "Loli", "Totoro"}
--> {M: {"Miku Chan", "Mayonnaise"}, L: {"LeshaInc", "Loli"}, T: {"Totoro"}}
И все это становится таким простым используя библиотеку MoonyLambda.
Скачать
Исходный код: pastebin.com/fFEFvX5D
Скомпилированная и минифицированная версия: pastebin.com/K4b9sREs
Документация
...будет постепенно писаться в этой теме. Ссылки будут тут.
Функциональный стиль выглядит гораздо читаймей, чем императивней стиль. Когда в императивном стиле мы пишем непонятный цикл, который непонятно что делает, тут мы пишем несколько строк кода, который понятен с первого взгляда.