Comments 25
Отсутствие pattern matching — на мой взгляд основной недостаток Coffeescript. Хорошо что он преодолен.
+1
UFO just landed and posted this here
Это очень плохо. Единственный нормальный вариант, как такое можно делать — создавая расширения для Coffee или, например, такими способами как sweetjs.org/. Но не дай бог такое использовать в продакшене.
+3
Скажите, а чем принципиально в данном случае прекомпилированный код отличается от сгенерированного на лету? И неужели установить расширение для Coffee и затем прекомпилировать файл удобнее и легче чем просто подключить библиотеку (при том что она весит 11к не пожатая)?
0
Достаточно того, что в таком коде теряется доступ к замыканию, остаётся доступ только к глобальным объектам. Производительность с таким подходом оставляет желать лучшего, особенно если подобная функция создаётся неоднократно. Зачем здесь перекомпиляция — вообще не ясно. Библиотека, ссылка на которую чуть ниже, прекрасно обходится и без этого.
+1
Простите, а Вы код читали? Он вот здесь github.com/nogizhopaboroda/f_context/blob/master/src/f_context.coffee
Вас не затруднит показать мне в каком месте теряется доступ к замыканию и где функция создается неоднократно?
Вас не затруднит показать мне в каком месте теряется доступ к замыканию и где функция создается неоднократно?
-3
Я читал код из статьи, мне его хватило, что бы пропало всё желание читать код самой библиотеки. Здесь, например, ошибки не видите?
Да без проблем. Добавим к примеру с факториалом применение произвольной функции из замыкания:
Результат — Uncaught ReferenceError: mod is not defined.
var new_function = Function.apply(null, fn_body, /*именованные аргументы*/ 'fact', 'N');
Вас не затруднит показать мне в каком месте теряется доступ к замыканию
Да без проблем. Добавим к примеру с факториалом применение произвольной функции из замыкания:
( ->
mod = (it)-> it | 0
O = f_context ->
fact(0) -> mod 1
fact(N) -> mod N * fact(N - 1)
console.log O.fact 10
)()
Результат — Uncaught ReferenceError: mod is not defined.
+2
Такое заявление без аргументации является попыткой набросить. Библиотека работает и решает свою работу, просадки по производительности не создает. Так в чем проблема?
-3
Вот вам еще паттерн матчинг для Coffeescript с чуть более приятным конструкциями: github.com/CRogers/pun
Автозаменяемый на лету код очень сложно дебажить и предсказать его поведение. Если уж хочется функциональщины, то есть множество вариантов вроде Clojurescript, Elm и тд — можно использовать на ура, принеся в жертву незаменимый дебаггер. И не говорите про source maps, их предельный максимум — чтение кода, вменяемую отладку на них никогда не построить.
Автозаменяемый на лету код очень сложно дебажить и предсказать его поведение. Если уж хочется функциональщины, то есть множество вариантов вроде Clojurescript, Elm и тд — можно использовать на ура, принеся в жертву незаменимый дебаггер. И не говорите про source maps, их предельный максимум — чтение кода, вменяемую отладку на них никогда не построить.
+1
вменяемую отладку на них никогда не построить
Это еще почему?
0
А как? На выходе это просто символьная карта, которая при отладке ведет себя непредсказуемо, не связывая цепочку выполнения с оригинальным кодом. Тот же coffeescript не отладить, потому что в половине случаев я просто не могу поставить брейк поинт в нужное мне место. Плюс ко всему dev tools подвисает секунд на 30 при разбивке кода по этим самым source maps.
-2
Автозаменяемый на лету код очень сложно дебажить и предсказать его поведение
Конкретно в случае данной библиотеки — вы заблуждаетесь. И вот почему:
1) Вот пример (Вы уж простите за этот преславутый факториал, но он самый короткий и наглядный):
f_fact(0) -> 1
f_fact(N) ->
debugger
N * f_fact(N - 1)
Сгенерированный библиотекой код:
...
var f_fact_local_0 = function(){
return 1;
};
var f_fact_local_1 = function(N){
debugger; //вот ваш дебаггер, все нужные переменные на месте
return N * f_fact(N - 1);
};
var f_fact = function(){
if(arguments[0] === 0 && arguments.length === 1){
return f_fact_local_0();
}
if(arguments.length === 1){
return f_fact_local_1(arguments[0]);
}
...
Весь код как на ладони.
2) Это ведь просто функция, у нее нет состояния, а значит ее результат выполнения зависит только от входных параметров, а значит ее очень легко покрыть тестами и ничего не надо дебажить.
Но спасибо за идею, дипишу в ридми про легкость отладки.
0
Как сгенерированный налету код можно увидеть в отладчике без прописывания debugger? По факту это дополнительный постпроцессинг в в браузере после сборки coffee кода, производительность не измерялась?
0
Без прописывания debugger никак. Но зачем Вам это? Я не потроллить, мне просто интересно.
По производительности — обычная рекурсия. Лупам, конечно, проигрывает, но как раз над этим я сейчас работаю.
По производительности — обычная рекурсия. Лупам, конечно, проигрывает, но как раз над этим я сейчас работаю.
0
Для прозрачности и четкого понимания следования выполнения кода. Не вылажу из дебагера, поэтому не понимаю как работать с «невидимым» кодом при пошаговой отладке. Про производительность выше уже подметили.
0
Погодите, то есть Вы перечитываете все скрипты перед запуском или как?
Вас, как человека, не вылазящего из дебагера, наверное не должно удивить, что как только, при пошаговой отладке, дебагер дойдет до исполнения функции, сгенерированной данной библиотекой, он откроет код всего сгенерированного модуля в новой вкладке и выставит курсор ровно на строчке с этой самой функцией.
Хотите, я для Вас маленький скринкаст запишу раз уж Вы на слово не верите?
Вас, как человека, не вылазящего из дебагера, наверное не должно удивить, что как только, при пошаговой отладке, дебагер дойдет до исполнения функции, сгенерированной данной библиотекой, он откроет код всего сгенерированного модуля в новой вкладке и выставит курсор ровно на строчке с этой самой функцией.
Хотите, я для Вас маленький скринкаст запишу раз уж Вы на слово не верите?
-2
Попробовал, не впечатлило. Действительно есть заход в сгенерированный модуль, но как дальше быть с этим самостоятельным островком кода, который ничего не знает о контексте, не понятно. Единственный вариант работы с библиотекой — это придерживаться чистоты функций путем прокидывания в них контекста и прочих параметров, а это уже каноническое ФП и прощайте замыкания. Тот же require придется прокидывать внутрь окружения f_context.
0
В Clojure pattern matching тоже не встроенный, а сделанный отдельной библиотекой.
0
Спасибо за ссылку.
Но все же синтаксис pattern matching у pun менее понятен.
Но все же синтаксис pattern matching у pun менее понятен.
0
Благодарю за статью,
На мой взгляд реализация функциональных конструкций, особенно pattern matching, получилась громоздкой.
На мой взгляд реализация функциональных конструкций, особенно pattern matching, получилась громоздкой.
0
Sign up to leave a comment.
Функциональное программирование на CoffeeScript с библиотекой f_context