LeshaInc 625 Опубликовано: 16 июля, 2016 (изменено) MoonyLambda Вы наверное знаете что сейчас проходит конкурс MoonJam. В общем суть в том что бы написать что-нибудь на MoonScript за неделю. Как говорил уже тотора, что-то серьезное за неделю не написать, но попробовать, поразвлечься, и написать что-нибудь интересное можно. В общем в этой теме буду показывать мой проект. И это... Библиотека для функционального программирования (далее просто - ФП)! Луа не предоставляет стандартных средств для ФП, потому я написал свою библиотеку. Чем то она похожа на реализацию такового функционала в языке Python, а чем то нет. Суть в том что функциональное программирование очень сильно упрощает работу с данными, например вместо пяти строк мы напишем одну строку. Все примеры в MoonScript, но в спойлерах будет эквивалент на луа. f - библиотека подключенная через require Начнем с самого простого, сложить массив чисел. f.reduce f.add, {1, 2, 3} --> 6 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, {1, 2, 3, 4}) --> {2, 4} А теперь, достанем все числа которые одновременно и меньше пяти, и четные. Это не составит труда f.filter f.even, f.filter ((a) -> a < 5), {1, 2, 4, 5, 6, 7} --> {2, 4} f.filter(f.even, f.filter((function(a) return a < 5 end), {1, 2, 4, 5, 6, 7})) --> {2, 4} Хочу отметить, что нам не обязательно постоянно писать огромные цепочки из вызовов. Все функции в библиотеке каррированы. selectEven = f.filter f.even selectEven {1, 2, 3, 4, 5} --> {2, 4} local 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 local pow = f.curry(function (a, b) a ^ b end) local 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"}} local first_letter = function(a) return a:sub(1, 1) end 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 Документация ...будет постепенно писаться в этой теме. Ссылки будут тут. Функциональный стиль выглядит гораздо читаймей, чем императивней стиль. Когда в императивном стиле мы пишем непонятный цикл, который непонятно что делает, тут мы пишем несколько строк кода, который понятен с первого взгляда. Изменено 17 июля, 2016 пользователем LeshaInc 3 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах