Почему поставил -1? Ну так просто моё мнение считает твоё мнение неправильным
[]
К>И? К>Сравним:
[]
К>В первом случае тебе нужно знать и хранить в голове структуру класса, какие там поля и т.п.
Зачем? Есть же определение. Это вот в эрланге нужно хранить, тк эти определения могут отличаться от использования к использованию. Это нечеткая типизация со всеми вытекающими
К>В эрланге ты можешь сделать то же самое, если поставить Tuple = func(), но если ты "запаттернматчишь", то дальше по коду тебе не нужны подробности структуры тупла, ты работаешь с конкретными данными, которые тебя интересуют в конкретный момент.
а как с ними работать, если мне не нужна структура тупла? Тупл, поправь меня, если я говорю что-то нето, динамическая структура данных, без строгой структурированности (сорри за каламбур).
К>Т.е. таким образом ты локализуешь объём сложности данных, участвующих в логике приложения. К>Всё, конечно, есть только лишь сугубо моё мнение
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, Курилка, Вы писали:
К>>В первом случае тебе нужно знать и хранить в голове структуру класса, какие там поля и т.п.
КЛ>Зачем? Есть же определение. Это вот в эрланге нужно хранить, тк эти определения могут отличаться от использования к использованию. Это нечеткая
типизация со всеми вытекающими
Давай не надо придумывать интересных новых оригинальных терминов.
Типизация есть, строгая, но динамическая, если ты против неё — так и скажи, но тут уже "просто вы не умеете их готовить"
Хотя статика мне тоже очень даже нравится.
А по поводу сказанного мной поясню: если функция у тебя возвращает класс, то у тебя будет использоваться этот самый класс, со всеми его внутренностями, тогда как если я "паттернматчу" результат функции в тупл, то в результате получаю (возможно) атомарные значения, которые нужны мне в текущей функции, причём я могу на подробности, не интересные мне в данном месте (но нужные в другом случае), просто "забить", поставив там _
Например функция возвращает точку как тупл 2 координат, а мне нужна только X, я сделаю {X, _} = func(), и дальше по тексту у меня есть только переменная X, и нет объекта point с лишними подробностями.
Не ахти важный пункт, но всёж...
К>>В эрланге ты можешь сделать то же самое, если поставить Tuple = func(), но если ты "запаттернматчишь", то дальше по коду тебе не нужны подробности структуры тупла, ты работаешь с конкретными данными, которые тебя интересуют в конкретный момент.
КЛ>а как с ними работать, если мне не нужна структура тупла? Тупл, поправь меня, если я говорю что-то нето, динамическая структура данных, без строгой структурированности (сорри за каламбур).
эээ, что значит "не нужна структура тупла"? В голове только рисуется вариант диспетчерезации сообщений, когда процесс их посылает нужным получателям, тогда, что там в каких туплах — пофиг, что получили, то и переслали (если, конечно, адрес не содержится в теле сообщения).
Ни разу тупл не динамическая структура, она может быть как в динамических так и в статических языках, не надо, пожалуйста, путать. Другое дело, что поля там неименованные и адресуются порядковым номером в тупле, а для именованного доступа в эрланге есть рекорды.
[]
К>Давай не надо придумывать интересных новых оригинальных терминов.
давай
К>Типизация есть, строгая, но динамическая, если ты против неё — так и скажи, но тут уже "просто вы не умеете их готовить"
ну ты с этого начал. Вообще, из этого спора вряд-ли кто-то вйдет победителями, на то и имхо.
К>Хотя статика мне тоже очень даже нравится.
[]
К>Не ахти важный пункт, но всёж...
Ты отклонился от темы. Ну да ладно.
К>>>В эрланге ты можешь сделать то же самое, если поставить Tuple = func(), но если ты "запаттернматчишь", то дальше по коду тебе не нужны подробности структуры тупла, ты работаешь с конкретными данными, которые тебя интересуют в конкретный момент.
КЛ>>а как с ними работать, если мне не нужна структура тупла? Тупл, поправь меня, если я говорю что-то нето, динамическая структура данных, без строгой структурированности (сорри за каламбур).
К>эээ, что значит "не нужна структура тупла"? В голове только рисуется вариант диспетчерезации сообщений (1), когда процесс их посылает нужным получателям, тогда, что там в каких туплах — пофиг, что получили, то и переслали (если, конечно, адрес не содержится в теле сообщения). К>Ни разу тупл не динамическая структура, она может быть как в динамических так и в статических языках, не надо, пожалуйста, путать.(2) Другое дело, что поля там неименованные и адресуются порядковым номером в тупле, а для именованного доступа в эрланге есть рекорды.
(1) Стоп, до этого вроде рисовался вариант разбора? В том то и пробелма, что только в голове.
(2) Что ты путаешь где она может быть и кем она является? В том то и дело, что типа у тупла нет, имени нет, имен полей нет. Так что что и сколько ты туда положил, то там и будет.
В вообще, думаю проще ту мою оценку удалить, чтобы тебя не раздражать. Тема флеймовая.
Здравствуйте, Константин Л., Вы писали:
E>>>Вот что мне не нравится в подобных декларативных вещах, что при наличии большого количества полей в PDU нужно писать большие туплы прямо в коде для того, чтобы принять результат работы parse. Можешь показать, как от этого дублирования описаний избавиться в Erlang-е
G>>Принять можно без тупла. Можно просто — Result = parse( Stream ), а разобрать его потом. Далее — не обязательно большой разбирать тупо сразу целиком.
КЛ>Ну так какая разница, сейчас или потом.
Офигенная разница, сейчас или потом. Это "потом" я могу в функцию завернуть, так, что ты его не увидишь.
КЛ>Тебе говорят о том, что, фактически, при каждом разборе ты снова будешь писать "декларацию" тупла.
У туплов нет никакой декларации, это не рекорд, поэтому я ее писать не буду вообще ни разу — ни при первом разборе, ни при последнем. Надо называть вещи своими именами. Вообще — эта претензия настолько же абсурдна и дика, как придирка к функции с несколькими аргументами — что же это их много а не один — их же блин при каждом вызове снова все 12 штук писать придется, да еще помнить, в каком порядке что идет, да еще (боже упаси) какие из них input а какие — output! Ужас то какой! Это же считай заново декларацию функции писать. Как от того избавиться — скажите же мне? А если часть аргументов функции я передавать не хочу?! Что тогда? А?! Все, в помойку ваш С++ за это — на простом вызове функции шею можно свернуть .
Во-вторых — тебе говорят о том, что вовсе не при каждом вызове надо разбирать тупл на составляющие. Фактически, при каждом разборе ты можешь делать так:
Result = parse( Stream ),
DoSomethingWithResult( Result ).
И в третьих, с чего то ты взял, что у меня один и тот же пакет будет в нескольких местах разбираться? Это уж как я программу свою организую, так и будет. И уверяю тебя, я постараюсь такой код из разных мест не вызывать. Я его аккуратно в функции запакую, а потом вызову.
И в четвертых, у меня в Эрланге есть полноценные рекорды (структуры с именованными полями), для тех случаев, когда они действительно нужны. Вы не переживайте за Эрланг, (сразу вспоминается, как английские лорды рекомендовали сделать колеса паравоза зубчатыми — чтоб не проскальзывали) — на нем уже достаточно много телеком-софта написано (эффективность разработки по метрикам реальных проектов Эриксона — вчетверо быстрее С++ при большей отказоустойчивости — т.е. паровоз давно уже ездит, и сцепление у колес офигенное, спокойно, уважаемые лорды), и ничего, туплы как-то не помешали.
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, Курилка, Вы писали:
[cut]
К>>Не ахти важный пункт, но всёж...
КЛ>Ты отклонился от темы. Ну да ладно.
Ни разу, я просто подробнее расписал свою мысль, или тебе видней, что я имел в виду?
К>>>>В эрланге ты можешь сделать то же самое, если поставить Tuple = func(), но если ты "запаттернматчишь", то дальше по коду тебе не нужны подробности структуры тупла, ты работаешь с конкретными данными, которые тебя интересуют в конкретный момент.
КЛ>>>а как с ними работать, если мне не нужна структура тупла? Тупл, поправь меня, если я говорю что-то нето, динамическая структура данных, без строгой структурированности (сорри за каламбур).
К>>эээ, что значит "не нужна структура тупла"? В голове только рисуется вариант диспетчерезации сообщений (1), когда процесс их посылает нужным получателям, тогда, что там в каких туплах — пофиг, что получили, то и переслали (если, конечно, адрес не содержится в теле сообщения). К>>Ни разу тупл не динамическая структура, она может быть как в динамических так и в статических языках, не надо, пожалуйста, путать.(2) Другое дело, что поля там неименованные и адресуются порядковым номером в тупле, а для именованного доступа в эрланге есть рекорды.
КЛ>(1) Стоп, до этого вроде рисовался вариант разбора? В том то и пробелма, что только в голове.
Да почему, совсем нет, сейчас пишу одну штуку, там как раз есть подобная схемка, т.е. не только в голове, но и в коде КЛ>(2) Что ты путаешь где она может быть и кем она является? В том то и дело, что типа у тупла нет, имени нет, имен полей нет. Так что что и сколько ты туда положил, то там и будет.
Вот тут скорей путаешь ты — по поводу того "что" положили, есть туплы статически-типизированные, так что строку туда, где число должно быть ты не положишь, ну и там же с длиной тупла ты тож не поиграешься. В динамических же языках то же самое, только вот проверка будет в рантайме и в том же Эрланге вылезет ошибка времени исполения, какой нибудь бад_матч или функцшн_клоз (в зависимости от того где у нас паттерн-матчинг).
Я же утверждал, что туплы не есть прерогатива динамических языков.
Туплы есть лишь одна из возможных структур данных со своими плюсами и минусами, а что удобней использовать — на вкус и цвет...
КЛ>В вообще, думаю проще ту мою оценку удалить, чтобы тебя не раздражать. Тема флеймовая.
Да я не раздражаюсь — нервы вещь ценная
Просто хотелось понять другую точку зрения.
Здравствуйте, Курилка, Вы писали:
E>>Ага, а после этого говорят, что обеспечение целостности данных в C++ при исключениях -- сложное дело!
E>>Шутка
К>А если чуть серьёзней? Моделирование на процессах тебе кажется сильно сложным?
По моему субъективному мнению программирование на обмене сообщений не проще, чем программирование на непосредственных вызовах. Везде есть свои заморочки. В каких-то случаях на сообщении проще, в каких-то сложнее. Все зависит от конкретной задачи.
К>И ещё мысль — в случае такого моделирования ты разделяешь именно участки алгоритма, которые могут "отвалиться", т.е. уделяешь внимание участкам кода. К>Тогда как для обеспечения целостности на плюсах, тебе надо рассуждать уже не только об участках кода, но и о самих, данных, как там что клинится и т.п.
Если я еще хоть что-то понимаю, заботится о данных нужно всегда. Имхо, сформировать ошибочный тупл в Erlang-е при организации очередного вызова в хвостовой рекурсии не сложнее, чем напортачить в каком-нибудь императивном языке, будь то C++, D, Java или C#.
Но, в чем Erlang существенно выигрывает у более сложных и универсальных императивных конкурентов, так это в том, что возникшее исключение не оставляет локальных данных процесса в разсогласованном состоянии. В тех же плюсах этого достичь гораздо сложнее (хотя, имхо, и проще, чем в Java или Ruby). Например, в C++ если у объекта есть два атрибута-списка в которые нужно засунуть значения в некотором методе и после изменения первого списка вылетает исключение, то нужно использовать дополнительные механизмы по восстановлению объекта в первоначальном состоянии. Чего не нужно делать в Erlang-е. В этом смысле чистая функциональность рулит, адназначна.
Однако, если речь идет о взаимодействии параллельных сущностей (нитей в C++/D/Java и процессов в Erlang), то пока не буду распространяться на эту тему. Ибо Erlang еще не в курил, а в C++ с этим у меня проблем не было.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
[]
К>Я же утверждал, что туплы не есть прерогатива динамических языков.
так это понятно, мы первоначально начали спорить о том, что удобнее
К>Туплы есть лишь одна из возможных структур данных со своими плюсами и минусами, а что удобней использовать — на вкус и цвет...
КЛ>>В вообще, думаю проще ту мою оценку удалить, чтобы тебя не раздражать. Тема флеймовая. К>Да я не раздражаюсь — нервы вещь ценная К>Просто хотелось понять другую точку зрения.
точка зрения -> не известно что удобнее, туплы или рекорды
[]
G>Офигенная разница, сейчас или потом. Это "потом" я могу в функцию завернуть, так, что ты его не увидишь.
Когда-то все-таки придется
КЛ>>Тебе говорят о том, что, фактически, при каждом разборе ты снова будешь писать "декларацию" тупла.
G>У туплов нет никакой декларации, это не рекорд, поэтому я ее писать не буду вообще ни разу — ни при первом разборе, ни при последнем. Надо называть вещи своими именами.
ну че ты какой придирчивый, под декларацией понималось la-la-la(field1,field2,field3) = func(...)
G>Вообще — эта претензия настолько же абсурдна и дика, как придирка к функции с несколькими аргументами — что же это их много а не один — их же блин при каждом вызове снова все 12 штук писать придется, да еще помнить, в каком порядке что идет, да еще (боже упаси) какие из них input а какие — output!
для тебя дика, для меня нет. Ты кое-что путаешь. Сигнатура функции сама все подскажет.
G>Ужас то какой! Это же считай заново декларацию функции писать. Как от того избавиться — скажите же мне? А если часть аргументов функции я передавать не хочу?! Что тогда? А?! Все, в помойку ваш С++ за это — на простом вызове функции шею можно свернуть .
G>Во-вторых — тебе говорят о том, что вовсе не при каждом вызове надо разбирать тупл на составляющие. Фактически, при каждом разборе ты можешь делать так:
ладно, не доходит, так не доходит.
[]
G>И в четвертых, у меня в Эрланге есть полноценные рекорды (структуры с именованными полями), для тех случаев, когда они действительно нужны. Вы не переживайте за Эрланг,
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, Gaperton, Вы писали:
G>>Вообще — эта претензия настолько же абсурдна и дика, как придирка к функции с несколькими аргументами — что же это их много а не один — их же блин при каждом вызове снова все 12 штук писать придется, да еще помнить, в каком порядке что идет, да еще (боже упаси) какие из них input а какие — output!
КЛ>для тебя дика, для меня нет. Ты кое-что путаешь. Сигнатура функции сама все подскажет.
Да ничего не подскажет, скажем у меня есть класс, туда передаются, скажем 1 целый аргумент и 3 строковых, не посмотрев в сигнатуру ты сходу скажешь какой параметр под каким номером идёт?
Скажем, вот местами в вебсферовских либах есть сигнатуры а-ля (string1, sring2, string3) — без жавадоков очень забавно было бы програмить
Здравствуйте, Константин Л., Вы писали:
КЛ>а как же имена параметров?
Ну так вот string1, sring2 и string3 и есть имена параметров, которые эклипс выдаёт.
Или имена параметров уже стали обязательной частью сигнатуры?
Есть ощущение, что нет
Пример:
interface X{
void log(String className, String methodName);
}
static class A implements X{
public void log(String methodName, String className){
}
}
Здравствуйте, Константин Л., Вы писали:
G>>У туплов нет никакой декларации, это не рекорд, поэтому я ее писать не буду вообще ни разу — ни при первом разборе, ни при последнем. Надо называть вещи своими именами.
КЛ>ну че ты какой придирчивый, под декларацией понималось la-la-la(field1,field2,field3) = func(...)
Не "ну че". Потрудись свои мысли формулировать по человечески, без ну че и ла-ла-ла. Смотрим:
Здравствуйте, Константин Л., Вы писали:
G>>Не "ну че". Потрудись свои мысли формулировать по человечески, без ну че и ла-ла-ла. Смотрим:
КЛ>может мне самому можно разобраться, как выражать свои мысли?
Если ты их выражаешь сам для себя, "тихо сам с собой ведешь беседу", то можешь разобраться и сам. Когда ведешь беседу с другим человеком — здесь надо заботится о том, чтобы ему, а не тебе, было понятно, что ты говоришь. И твоя манера беседу вести мне тоже не нравится. Общий тон напоминает гопоту подъездную.
G>>{ out_parm1, out_parm2, out_parm3 } = func( in_parm1, in_parm2, in_parm3 ).
КЛ>Под декларацией тупла подразумевалось выделенное. Пардон, месье, если оскорбил твои чувства оп поводу этого.
Я думал, под ней подразумевалось "ла-ла-ла", но теперь все встало на свои места. Ура, мне все понятно! Только вопрос — а нужда писать декларацию функции тебя не пугает? Под ней, очевидно, подразумевается выделенное:
G>>{ out_parm1, out_parm2, out_parm3 } = func( in_parm1, in_parm2, in_parm3 ).
E>>или бы вообще сделал генератор, который бы парсинг подобных пакетов G> генерировал по DSL-описаниям. Это не фокус в любом языке. DSL на G> каждый писк — не выход. Кстати, можно просто воспользоваться G> генератором ASN.1.
Для приведенных случаев как раз только DSL и подойдёт реально. Потому как
нужно и парсить, и генерировать пакеты. И типы этих пакетов могуть быть
схожими между собой (разные PDU, или различные протоколы над IP),
т.е. общего у них много может быть.
И в таком случае одним паттерном матчить целый пакет конечно эффектно, но
не эффективно с точки зрения продуктивности программиста.
В том же oserl'е (SMPP для Erlang) самый длинный бинарный паттерн — 4
значения по 4 байта — извлекается всего один раз. Остальные места — это
откусывание от начала пакета, довольно часто — даже по одному байту, так
как — null terminated strings.
А написание DSL займёт я думаю примерно одинаковое время на любом языке
высокого уровня. Да, код на Erlang'е для работы с бинарными данными, я
думаю будет покороче и разработан быстрее. Но это не будет отличие на
порядок.
Здравствуйте, binarin, Вы писали:
B>А написание DSL займёт я думаю примерно одинаковое время на любом языке B>высокого уровня. Да, код на Erlang'е для работы с бинарными данными, я B>думаю будет покороче и разработан быстрее. Но это не будет отличие на B>порядок.
Мы проводили эксперименты с бит-синтаксисом (одному сотруднику нашего отдела надо было защищать кандидатскую, решили сделать что-то полезное). Суть эксперимента — в язык С добавляется бит-синтаксис, скопированный из Эрланга, а также множественный оператор switch, в котором можно применять соспоставление с образцом для бит-синтаксиса. Цель исследования — понять, насколько этот модифицированный С будет удобнее для программирования встраиваемых систем, в которых большая часть кода — обработка и преобразование различых бинарных протоколов.
В рамках этих работ было проведено сравнение фрагментов реализаций на С и на "С с бинарисами" для нескольких разных протоколов, в частности, был взят стек протокола ZiBee. Так вот, предварительные результаты следующие (парень будет защищаться осенью, можно будет дисер выложить наверное). Реализация протокола с бинарисами на порядок выигрывает в читабельности. Применение бинарисов предполагает другое структурирование кода, и при правильном программировании (техника другая совершенно — надо привыкнуть) код получается в разы компактнее и неизмеримо проще в понимании и поддержке (я говорю о фрагменте системы — реализации протокола, а не о всей системе, конечно). И это тот же самый язык — С. Эрланг будет еще компактнее и выразительнее — там помимо бинарисов много чего есть.
Отличия на порядок (это в десять раз, так, про между прочим) — мало какой язык даст вообще, разве что K или J — но это экзотика. Рассчитывать надо на сокращение кода с коэффициентом 2-4, что вобще-то очень даже ничего. Представьте — вы делаете проект год, или полгода. Разница есть?
Что касательно бинарисов в Эрланге — они появились не так давно. Значительная часть OTP разаботана раньше, до того, как стали доступны бинарисы. Например, AXD301 был сделан без бинарисов вообще. Поэтому не так много и примеров их использования в стандартной либе.
Что касательно DSL — его не нужно разрабатывать, есть стандартные языки для описания протоколов — ASN.1 и TTCN, и есть компиляторы из них во все популярые языки.
Здравствуйте, binarin, Вы писали:
B>В том же oserl'е (SMPP для Erlang) самый длинный бинарный паттерн — 4 B>значения по 4 байта — извлекается всего один раз. Остальные места — это B>откусывание от начала пакета, довольно часто — даже по одному байту, так B>как — null terminated strings.
null-terminated string, кстати, проблемой не является. Еще раз.
{ RestOfStream, [
String1,
<< Number:7, Num2:9 >>, здесь разбирается бинарис длиной в два байта
String2,
CompoundType ] } = parse( Stream, [ string, 2, string, my_module:my_parse_fun/1 ] ),
И все. В предыдущем посте я объяснил в двух словах, как это рабтает.
Здравствуйте, Gaperton, Вы писали:
g> Суть эксперимента — в язык С добавляется бит-синтаксис, скопированный из Эрланга, а также множественный оператор switch, в котором можно применять соспоставление с образцом для бит-синтаксиса.
А можно поглядеть на пример такого кода? Похоже на паттерн-матчинг списков в Хаскелле?