Pull to refresh

Comments 25

Отсутствие pattern matching — на мой взгляд основной недостаток Coffeescript. Хорошо что он преодолен.
я думаю, люди так считают про любой язык где нет pattern matching'a, когда узнают, что это такое
UFO just landed and posted this here
Не имя красит человека)
Это очень плохо. Единственный нормальный вариант, как такое можно делать — создавая расширения для Coffee или, например, такими способами как sweetjs.org/. Но не дай бог такое использовать в продакшене.
Скажите, а чем принципиально в данном случае прекомпилированный код отличается от сгенерированного на лету? И неужели установить расширение для Coffee и затем прекомпилировать файл удобнее и легче чем просто подключить библиотеку (при том что она весит 11к не пожатая)?
Достаточно того, что в таком коде теряется доступ к замыканию, остаётся доступ только к глобальным объектам. Производительность с таким подходом оставляет желать лучшего, особенно если подобная функция создаётся неоднократно. Зачем здесь перекомпиляция — вообще не ясно. Библиотека, ссылка на которую чуть ниже, прекрасно обходится и без этого.
Я читал код из статьи, мне его хватило, что бы пропало всё желание читать код самой библиотеки. Здесь, например, ошибки не видите?

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.
Такое заявление без аргументации является попыткой набросить. Библиотека работает и решает свою работу, просадки по производительности не создает. Так в чем проблема?
Вот вам еще паттерн матчинг для Coffeescript с чуть более приятным конструкциями: github.com/CRogers/pun
Автозаменяемый на лету код очень сложно дебажить и предсказать его поведение. Если уж хочется функциональщины, то есть множество вариантов вроде Clojurescript, Elm и тд — можно использовать на ура, принеся в жертву незаменимый дебаггер. И не говорите про source maps, их предельный максимум — чтение кода, вменяемую отладку на них никогда не построить.
вменяемую отладку на них никогда не построить

Это еще почему?
А как? На выходе это просто символьная карта, которая при отладке ведет себя непредсказуемо, не связывая цепочку выполнения с оригинальным кодом. Тот же coffeescript не отладить, потому что в половине случаев я просто не могу поставить брейк поинт в нужное мне место. Плюс ко всему dev tools подвисает секунд на 30 при разбивке кода по этим самым source maps.
Вы что-то делает не так. У меня на проекте гораздо более сложные трансформации, чем просто coffee и все отлично дебажится.
Поверю на слово. Мне не так с этим везет, отключаю все map файлы и дебажу чистый js.
Автозаменяемый на лету код очень сложно дебажить и предсказать его поведение

Конкретно в случае данной библиотеки — вы заблуждаетесь. И вот почему:

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) Это ведь просто функция, у нее нет состояния, а значит ее результат выполнения зависит только от входных параметров, а значит ее очень легко покрыть тестами и ничего не надо дебажить.

Но спасибо за идею, дипишу в ридми про легкость отладки.
Как сгенерированный налету код можно увидеть в отладчике без прописывания debugger? По факту это дополнительный постпроцессинг в в браузере после сборки coffee кода, производительность не измерялась?
Без прописывания debugger никак. Но зачем Вам это? Я не потроллить, мне просто интересно.
По производительности — обычная рекурсия. Лупам, конечно, проигрывает, но как раз над этим я сейчас работаю.
Для прозрачности и четкого понимания следования выполнения кода. Не вылажу из дебагера, поэтому не понимаю как работать с «невидимым» кодом при пошаговой отладке. Про производительность выше уже подметили.
Погодите, то есть Вы перечитываете все скрипты перед запуском или как?
Вас, как человека, не вылазящего из дебагера, наверное не должно удивить, что как только, при пошаговой отладке, дебагер дойдет до исполнения функции, сгенерированной данной библиотекой, он откроет код всего сгенерированного модуля в новой вкладке и выставит курсор ровно на строчке с этой самой функцией.
Хотите, я для Вас маленький скринкаст запишу раз уж Вы на слово не верите?
Попробовал, не впечатлило. Действительно есть заход в сгенерированный модуль, но как дальше быть с этим самостоятельным островком кода, который ничего не знает о контексте, не понятно. Единственный вариант работы с библиотекой — это придерживаться чистоты функций путем прокидывания в них контекста и прочих параметров, а это уже каноническое ФП и прощайте замыкания. Тот же require придется прокидывать внутрь окружения f_context.
В Clojure pattern matching тоже не встроенный, а сделанный отдельной библиотекой.
Спасибо за ссылку.
Но все же синтаксис pattern matching у pun менее понятен.
Благодарю за статью,

На мой взгляд реализация функциональных конструкций, особенно pattern matching, получилась громоздкой.
Спасибо за комментарий. Постараюсь сделать лаконичнее в следующем релизе.
Sign up to leave a comment.

Articles