Pull to refresh
3
0
Ткачук Илья Михайлович @Strain

Пользователь

Send message
вопрос не касаемо сабжа в частности, а скорее в целом — почему XML?
почему не более компактный JSON или не более читаемый и простой YAML?
Ясно, спасибо
Видимо реально проще использовать fay или purescript :)
«Никаких указателей на переменную — присваивание всегда происходит по значению.»

Это конечно прекрасно :)

Но похоже что это не работает для списков и структур

но почему тогда вот тут

habrastorage.org/files/91d/83a/ad4/91d83aad404b4e6d8d19082e95e98c33.png

после строчки

f1 = () -> 123

f2 тоже не изменилась, если при присваивании функций данные передаются по указателю? Если в таком случае после второй строчки

f2 = new () -> f1

память всё же выделяется под новую функцию — то тогда почему в третьей строчке они равны?
точнее даже вот так. я думаю идея понятна :)
правда не знаю можно ли из этого извлечь что-то для моей задачи, подумаю над этим на досуге

я не хочу холиваров на хабре и вообще хочу конструктивного диалога :)
то что в начальном тексте у меня ошибка это ясно, глупо клонировать функцию вот так

when "[object Function]" then some.bind({})

а потом пытаться сравнивать вот так

when "[object Function]" then a.toString() == b.toString()

Но вот я поковырялся с интерпретатором, и в итоге прикрепляю скриншот того что получилось. Я вижу что функции тут — клонируемые по значению абстракции, и это парадоксально но похоже что сравниваются они тоже по значению. Прикрепляю скриншот чтобы ты не подумал что я жульничаю и набираю это всё в текстовом редакторе :)

Похоже всё работает как надо, но конечно если придерживаться определённых правил.

В принципе да :) Такой подход имеет ряд плюсов

1) Однородность данных: сервер кидает клиенту через вебсокет сообщения которые содержат какие-то данные. Сервер написан на эрланге. Там нет никаких объектов — есть binaries, integers, floats, lists, maps. Именно в таком виде данные приходят клиенту. Если мы продолжим работать с этими данными именно как с данными а не как с объектами — это здорово снизит накладные расходы на написание всяческого рода классов, конструкторов, и прочих адаптеров erlang_data <=> js_data.

То же самое правило я кстати использую и по отношению в взаимодействию сервер <=> бд. То есть называю поля в эрланговских структурах в точности именами столбцов бд. Это реально здорово снижает накладные расходы, количество кода, увеличивает читаемость и прозрачность.

2) Мне гораздо проще читать / писать код, если он написан в парадигме моего основного языка.
смотря в каких языках :)
в эрланге например можно

насчёт js — нет, в лоб это не работает

coffee> f1 = () -> 123
[Function]
coffee> f2 = () -> 123
[Function]
coffee> f1 == f2
false
coffee> f1.toString() == f2.toString()
true

можно конечно использовать toString, но как было верно подмечено это костыль :)
скорее всего глобальный state + react будет быстрее, но конечно чистота тут уже нарушится :)
Кстати насчёт == || === и прочего — в coffeescript многие подобные скользкие моменты решены, например == всегда разворачивается в ===, слова return нет — всегда возвращается результат последнего выражения в функции итп

Насчёт работы с реальным продакшном у меня сложилась поределённая схема, вот пример:

1) Вот html-страничка, нас интересует вот этот блок который собственно будет отрисовываться в jreact, там будет происходить весь экшн

github.com/timCF/megaweb/blob/c90ede0e0c48373712695fb5a3e3b77247c6f6a7/app/index.jade#L12

2) Вот сам виджет который будет рисоваться пользователю в зависимости от состояния state

github.com/timCF/megaweb/blob/c90ede0e0c48373712695fb5a3e3b77247c6f6a7/app/widget.jreact

3) Когда DOM первый раз построился — мы врубаем jreact через актор

github.com/timCF/megaweb/blob/c90ede0e0c48373712695fb5a3e3b77247c6f6a7/app/scripts/app.coffee#L88-91

4) А дальше уже всё в абсолютно свободном плавании — коллбэки висящие на кнопках, что-то летящее с сервера в вебсокет — всё это отправляет сообщения актору

github.com/timCF/megaweb/blob/c90ede0e0c48373712695fb5a3e3b77247c6f6a7/app/scripts/app.coffee#L51

который строго в порядке очереди их вызывает, обновляя свой внутренний state

5) Периодически опрашиваем актор — получаем копию его текущего state и передаём в react который рисует пользователю страничку

github.com/timCF/megaweb/blob/c90ede0e0c48373712695fb5a3e3b77247c6f6a7/app/scripts/app.coffee#L68
Дело в том что я в своём коде не использую какие-то сложные, неоднозначные и уж тем более ООП стороны js.

а вы точно хотите на +0 == -0 получать true?
да :)

В моём понимании [head, tail...] — это просто список, а не объект и я никогда не переопределю для него поле length, в моём понимании length тут вообще не поле а метод (хотя судя по тому как он «вызывается» — это не так)

{key: value} — для меня не объект а просто map, хэш-таблица с парами key — value где key и value — любые js-данные, и поэтому я никогда не буду что-то там делать с прототипами

Насчёт when "[object Function]" then a.toString() == b.toString() — реально очень скользкий момент, но я увы так и не смог придумать как ещё можно сравнить две функции по значению. Разыменовывания указателя в js я так и не нашёл, это решило бы все подобные проблемы :(

a == b для примитивов у меня написано просто для красоты и однородности :) Да и мало ли что, просто изучать детально и глубоко реализацию всех типов данных в js не было ни времени ни сил ни желания
Не знаю)
Название я позаимствовал у одноимённого аналогичного макроса из библиотеки для ЯП Elixir которой пользуюсь. А вообще, возможно такое понятие как «монада» близко pipe_matching. «Возможно» — потому что Haskell я почти не знаю, так что за этот факт не могу ручаться.
При разработке на erlang / otp всегда есть 3 уровня абстракции — application, supervisor, gen_server. Application собственно — это дерево с корневым supervisor к которому привязаны другие supervisors, а gen_server в дереве — соответственно листья. И всё это динамическое — то есть может порождаться, прикрепляясь к какому-либо supervisor или умирать. В одном реальном приложении естественно может работать несколько otp-applications

www.erlang.org/doc/man/application.html
www.erlang.org/doc/design_principles/sup_princ.html
www.erlang.org/doc/man/gen_server.html
Огромное спасибо за ценное замечание насчёт # — я реально проглядел так как ещё пока newbie в таких вещах, в репозитории исправлю обязательно перед использованием в продакшне)

Насчёт «читать внутреннее устройство макросов» — а зачем в этом случае это делать? Просто задаются некоторые правила ( в данном случае требуется паттерн первым аргументом и n-ное количество выражений ) и макрос гарантированно предоставляет определённую управляющую логику для этих выражений — в данном случае pipe matching с заданным pattern-ом (ну если конечно убрать этот баг с «res»))).

Какую логику тут использовать в качестве управляющей — сугубо дело вкуса. Для меня как для erlang-девелопера p.m. — это как глоток свежего воздуха в странноватом пока что для меня языке, вот я и использую его. Ну и строго говоря — предложенный вами вариант это просто частный случай p.m.
Было бы круто)
На самом деле возможности эликсировских макросов имхо плохо документированы, по крайней мере на официальном сайте
Использовал Idea для Erlang. Классная штука. Понравилось что слева наглядно показываются места где функции входят в рекурсию, ну и автодополнение очень крутое, для Elixir конечно пока такого нет
Тоже обожаю mix. Он может то что ребару и не снилось)
В статье не стал расписывать mix, OTP и макросы, дабы не перегружать. Хотя мне кажется надо бы про них написать подробнее, ведь в них самый сок
Я не знаю что такое «поиск в глубину и ширину», хотя это конечно не характеризует меня с хорошей стороны. Но я хотел показать что если язык лаконичен и красив, то писать нормальные программы сможет любой, даже с большими пробелами в фундаментальных знаниях. Конечно когда набираешься некоторого опыта — понимаешь что сам язык не так уж и важен. Я просто заметил что Elixir учит меня думать более красиво. А дальше с этим умением можно будет писать нормально «хоть на php».

Information

Rating
Does not participate
Location
Таллин, Эстония, Эстония
Registered
Activity