VD> Иначе зачем бы делали эти эксперементальные проекты на которыет тут ссылки давали рядом?
Да просто потому что любой язык/платформа развиваются, елси не умерли.
Зайдем на MS Research и увидим там кучу экспериментальных языков для .NET
Не будем же говорить теперь, что C# отстой раз MS как убдто лихорадочно и массово опробует ему на замену все те языки ? Ведь нет?
Серьезно будет сказать по другому: есть места, где у C# (и тесно связанной с ним .NET) недостатки, и чтобы покрыть эти места Майкрософту нужны другие свои языки под .NET, что она и пытается сделать.
Идет нормальное развитие проекта. Посмотрели где в .NET могут образоваться узкие места — делают попытки их расшить. Будет удачно — в следующей версчии VisualStudio штатно будет какой-нибудь F# или Haskell.
Точно так же идет развитие Питона или Руби. Точно так же — Эрланга.
Здравствуйте, VladD2, Вы писали:
VD>Это от "рельных" задач зависит. Если задача укладывается в область действия высокоуровневых библиотечкных функций, то да. А если нет, и нужно именно что на самом языке написать, то приплыли. Иначе зачем бы делали эти эксперементальные проекты на которыет тут ссылки давали рядом?
Если что, HiPE — это не экспериментальный проект. С 2001 года это часть Erlang/OTP.
Здравствуйте, VladD2, Вы писали:
VD>Это от "рельных" задач зависит. Если задача укладывается в область действия высокоуровневых библиотечкных функций, то да. А если нет, и нужно именно что на самом языке написать, то приплыли. Иначе зачем бы делали эти эксперементальные проекты на которыет тут ссылки давали рядом?
Собственно, почему ? Библиотеки написаны на том же Ерланге. Согласен, хорошо написаны, и что-то соптимизировать в них сложно. Но ежели их не хватает, написать свое — проблем не представляет
G>> Кроме того, HIPE сейчас является частью стандартной библиотеки. К сожалению, код под Виндозу пока не генерит — только под Линукс и Соляру VD>Вот. Вот. И таких "к сожалению" море.
Если взять не бинарный дистрибутив, а сорцы, и собрать под Виндозу с включенным HIPE, то все заработает...Но меня это не сильно жмет , потому и не напрягаюсь
По поводу моря сожалений — это, мягко говоря, преувеличение. Меня не устраивает 3 вещи ( не говоря о мелочах ) : медленные float операции, недоделанная генерация нативного кода, отсутствие standalone бинарника для полученного приложения
VD>А вообще, я не очень понимаю как без хоть какой-то аннотации типов получить быстрый код. А если они будут, то это уже другой язык.
запросто ! в форте и намека на типы нет, а работает ! я уж не говорю про ассемблер, где вся типизация представляет собой обман зрения 8))
VD>Ни о чем. Вот если они алогоритмически эквивалентны, и оба оптимизированны, то о чем-то говорит. Вот только чудес на свете не бывает.
Алгоритмически эквивалентны на столь разных языках ? Воистину, чудес не бывает
Здравствуйте, gandalfgrey, Вы писали:
VD>>А вообще, я не очень понимаю как без хоть какой-то аннотации типов получить быстрый код. А если они будут, то это уже другой язык. G>запросто ! в форте и намека на типы нет, а работает ! я уж не говорю про ассемблер, где вся типизация представляет собой обман зрения 8))
Да, но они не типобезапосны, в отличие от Erlang-а.
Здравствуйте, WFrag, Вы писали:
G>>запросто ! в форте и намека на типы нет, а работает ! я уж не говорю про ассемблер, где вся типизация представляет собой обман зрения 8)) WF>Да, но они не типобезапосны, в отличие от Erlang-а.
Ерланг тоже не безопасен в этом отношении. Самая частая причина глюков при работе в изменяющейся среде — mismatch. Например, сменился протокол работы некоей внешней системы :
func1({packet1,X})->X;
func1({packet2,X})->X+1.
если я вызову func1 с аргументом, отличающимся от этих двух видов, то что произойдет ? падение процесса !
конечно, это можно обработать. И более того, можно предотвратить :
func1(X)->io:fwrite("ERROR: ~p",[X]).
но все же это не та безопасность типов, как в Clean, например
хотя вопрос о том, что лучше — сложен и туманен
Здравствуйте, gandalfgrey, Вы писали:
G>func1({packet1,X})->X; G>func1({packet2,X})->X+1. G>если я вызову func1 с аргументом, отличающимся от этих двух видов, то что произойдет ? падение процесса ! G>конечно, это можно обработать. И более того, можно предотвратить : G>func1(X)->io:fwrite("ERROR: ~p",[X]).
Да, но это как раз и показывает, что Erlang типобезопасен, просто типы проверяются в рантайме (в процессе паттерн-матчинга). Если функция принимает тупл, то список или число ты туда не впихнешь. Соответственно, должны быть накладные расходы на эти проверки.
В том же Clean-е наверняка часть подобных проверок делается еще при компиляции и, соответственно, в рантайме проверки уже будут и не нужны.
В FORTH такого нет — там что число, что адрес памяти (где лежит тупл, например) — разницы нет. Все проверки — только вручную. То ли тебе число передали, то ли адрес некоторого тупла, то ли адрес какой-нибудь другой структуры (P.S. возможно, мои знания о FORTH-е немного устарели ).
Здравствуйте, WFrag, Вы писали:
WF>Да, но это как раз и показывает, что Erlang типобезопасен, просто типы проверяются в рантайме (в процессе паттерн-матчинга). Если функция принимает тупл, то список или число ты туда не впихнешь. Соответственно, должны быть накладные расходы на эти проверки.
Ну, если так подходить — то да. Просто обычно несколько другое под типобезопасностью подразумевается
WF>В том же Clean-е наверняка часть подобных проверок делается еще при компиляции и, соответственно, в рантайме проверки уже будут и не нужны.
Это верно. Система типов там еще более мощная, чем в Окамле. Развивался бы он еще...
WF>В FORTH такого нет — там что число, что адрес памяти (где лежит тупл, например) — разницы нет. Все проверки — только вручную. То ли тебе число передали, то ли адрес некоторого тупла, то ли адрес какой-нибудь другой структуры (P.S. возможно, мои знания о FORTH-е немного устарели ).
Я тоже не слышал о типизированном Форте 8)
Приветствую All
Изначальный вопрос был не о реализациях, а о сфере применимости и достоинствах/недостатках Ерланга
Про плюсы/минусы вроде бы понаписали уже достаточно, а вот теперь и о том, где его выгодно применять :
1. Сложная логика обработки. Вместо 1000 строк с if/switch получится 50 строк case
2. параллельность. Тут конкурентов вообще нет
3. обработка потоков данных, сложных бинарных структур
4. системы повышенной надежности, для непрерывной работы на протяжении месяцев и лет. У меня есть несколько приложений, в которых сдохшие по какой-то причине системы перезапускаются себе и работают дальше, никому не вредя.
5. когда нужна портабельность — полностью переносим, без каких-либо заморочек. У меня один и тот же код работает под Linux/FreeBSD/Windows
6. распределенные системы — опять-таки не с чем сравнивать
Если хоть что-то из этого используется в разрабатываемом приложении — Ерланг в руки !
Здравствуйте, gandalfgrey, Вы писали:
G>Здравствуйте, Gaperton, Вы писали:
G>>> Это по памяти...А по быстродействию — очень даже хорошо получается !
G>>Возможно. Но в конфе пришли к выводу, что для строк рулят binaries. G> Странно...Сколько использую, для типично строчных операций — строки и быстрее. Для типично байтовых — понятно, быстрее бинарисы. как пример : G> getb(Out,<<L,D:L/binary,R/binary>>)->getb([proceed(D)|Out],R).
Строки не могут быть быстрее при представлении в виде списка 4-х байтовых чисел. И они не быстрее.
При потребности активно манипулировать строками переходят к представлениям binaries и atom.
Посмотри исходники XML-парсеров, почитай мэйл-лист на эту тему. Например, что по этому поводу думает Армстронг.
G>>Надо! Попробуй заведи тупл размером в 100 тыщ элементов (это аналог массива). И сделай ему несколько setelement-ов. G> Гм. А зачем такое ? Я дикт заведу, или в етс положу. Это уже архитектурные проблемы
Затем. Потому, что чтение их тупла по индексу — это O(1) с очень низкой константой. Асимптотика dict на чтении — O(N), а ets — это O(1) c копированием элемента при чтении и большой константой (это хэштаблица), плюс отсутствие сборки мусора и побочные эффекты. Их используют именно из-за убогости (вернее, отсутствия) массивов, это workaround, а не достоинство. Отсутствие массивов — неудобно, хоть и обходится.
G>>Строки. Строки. И еще раз строки. А также сериализация. Плюс — binaries не копируются при передаче от процесса к процессу в качестве мессаги — оч. полезное свойство. G> При shared куче — вообще ничего не копируется
shared heap, который есть в стабильной версии сейчас, применяется только для binaries. Тот shared heap, о котором говоришь ты — исследовательский проект. Мало ли что можно сделать. Я тебе говорю, как есть.
Здравствуйте, Gaperton, Вы писали:
G>Строки не могут быть быстрее при представлении в виде списка 4-х байтовых чисел. И они не быстрее.
Зато ими гораздо проще манипулировать в большинстве случаев
G>При потребности активно манипулировать строками переходят к представлениям binaries и atom. G>Посмотри исходники XML-парсеров, почитай мэйл-лист на эту тему. Например, что по этому поводу думает Армстронг.
я избегаю порождать атомы динамически по вполне понятным причинам
G>Затем. Потому, что чтение их тупла по индексу — это O(1) с очень низкой константой. Асимптотика dict на чтении — O(N), а ets — это O(1) c копированием элемента при чтении и большой константой (это хэштаблица), плюс отсутствие сборки мусора и побочные эффекты. Их используют именно из-за убогости (вернее, отсутствия) массивов, это workaround, а не достоинство. Отсутствие массивов — неудобно, хоть и обходится.
Не совсем так. Dict = O(log(N)). Но я не об этом, а о том, зачем может понадобиться огромный массив с произволным доступом.
G>shared heap, который есть в стабильной версии сейчас, применяется только для binaries. Тот shared heap, о котором говоришь ты — исследовательский проект. Мало ли что можно сделать. Я тебе говорю, как есть.
Странно, а по времени и размеру кучки мне показалось, что для всех видов
Здравствуйте, gandalfgrey, Вы писали:
G>Здравствуйте, Gaperton, Вы писали:
G>>Строки не могут быть быстрее при представлении в виде списка 4-х байтовых чисел. И они не быстрее. G>Зато ими гораздо проще манипулировать в большинстве случаев
Конечно.
G>>При потребности активно манипулировать строками переходят к представлениям binaries и atom. G>>Посмотри исходники XML-парсеров, почитай мэйл-лист на эту тему. Например, что по этому поводу думает Армстронг. G>я избегаю порождать атомы динамически по вполне понятным причинам
Естественно (ведь имеется в виду отсутствие GC для таблицы атомов?) . Поэтому в мэйллисте и сошлись на binaries
G>>Затем. Потому, что чтение их тупла по индексу — это O(1) с очень низкой константой. Асимптотика dict на чтении — O(N), а ets — это O(1) c копированием элемента при чтении и большой константой (это хэштаблица), плюс отсутствие сборки мусора и побочные эффекты. Их используют именно из-за убогости (вернее, отсутствия) массивов, это workaround, а не достоинство. Отсутствие массивов — неудобно, хоть и обходится. G>Не совсем так. Dict = O(log(N)). Но я не об этом, а о том, зачем может понадобиться огромный массив с произволным доступом.
Точно? А разве простой dict не на сортированном списке сделан? Впрочем, неважно — доступен и dict на базе gb_trees.
G>>shared heap, который есть в стабильной версии сейчас, применяется только для binaries. Тот shared heap, о котором говоришь ты — исследовательский проект. Мало ли что можно сделать. Я тебе говорю, как есть. G>Странно, а по времени и размеру кучки мне показалось, что для всех видов
Дело в реализации куч — там одна куча на каждый процесс для термов со stop-and-copy GC, и отдельная общая на все процессы куча для binaries с подсчетом ссылок. В этом и причина разницы.
Здравствуйте, gandalfgrey, Вы писали:
G>>Затем. Потому, что чтение их тупла по индексу — это O(1) с очень низкой константой. Асимптотика dict на чтении — O(N), а ets — это O(1) c копированием элемента при чтении и большой константой (это хэштаблица), плюс отсутствие сборки мусора и побочные эффекты. Их используют именно из-за убогости (вернее, отсутствия) массивов, это workaround, а не достоинство. Отсутствие массивов — неудобно, хоть и обходится. G>Не совсем так. Dict = O(log(N)). Но я не об этом, а о том, зачем может понадобиться огромный массив с произволным доступом.
Да много зачем. Затем же, зачем и в любом другом языке. Не хочешь же ты сказать, что никто никогда не заводит длинных массивов — за ненадобностью? Например, какой у нас самый естественный и эффективный способ представления двумерных матриц (допустим, мне марковский автомат нужен — да мало ли что)? Неужели хэштаблицы?
Здравствуйте, Gaperton, Вы писали:
G>Точно? А разве простой dict не на сортированном списке сделан? Впрочем, неважно — доступен и dict на базе gb_trees.
Вроде бы да. Но это как раз и дает логарифмическую зависимость ( метод половинного деления 8)) ). Разумеется, для сильно больших обьемов простой dict неприменим.Но dict процесса почему-то работает существенно быстрее, и кривая зависимости скорости от размеров у него другая
G>Дело в реализации куч — там одна куча на каждый процесс для термов со stop-and-copy GC, и отдельная общая на все процессы куча для binaries с подсчетом ссылок. В этом и причина разницы.
Возможно, время на конвертацию терм-бинарис и обратно компенсировало время на пересылку терма для моих задач...Для больших бинарисов и термов это, возможно, будет не так
Здравствуйте, Gaperton, Вы писали:
G>Да много зачем. Затем же, зачем и в любом другом языке. Не хочешь же ты сказать, что никто никогда не заводит длинных массивов — за ненадобностью? Например, какой у нас самый естественный и эффективный способ представления двумерных матриц (допустим, мне марковский автомат нужен — да мало ли что)? Неужели хэштаблицы?
Тут я согласен...Хотя, какие тут размеры, если подумать ? В компиляторе, который я делал, всего 390 правил и несколько больше состояний. Это и тупль потянет без проблем
Здравствуйте, gandalfgrey, Вы писали:
G>Здравствуйте, Gaperton, Вы писали:
G>>Точно? А разве простой dict не на сортированном списке сделан? Впрочем, неважно — доступен и dict на базе gb_trees. G>Вроде бы да. Но это как раз и дает логарифмическую зависимость ( метод половинного деления 8)) ). Разумеется, для сильно больших обьемов простой dict неприменим.Но dict процесса почему-то работает существенно быстрее, и кривая зависимости скорости от размеров у него другая
Не, это дает только О(N). К сожалению. По причине отсутствия произвольного доступа к элементам списков, половинное деление невозможно — только линейный поиск.
G>Не, это дает только О(N). К сожалению. По причине отсутствия произвольного доступа к элементам списков, половинное деление невозможно — только линейный поиск.
Тогда нафиг список сортированный ?
Вообще жаль, что Жрланг не может попытаться предсказать модель использования и добавить обратные ссылки
G>4. системы повышенной надежности, для непрерывной работы на протяжении месяцев и лет. У меня есть несколько приложений, в которых сдохшие по какой-то причине системы перезапускаются себе и работают дальше, никому не вредя.
А можно поинтересоваться, какие системы? Ну хотя бы приблизительно
Здравствуйте, Arioch2, Вы писали:
A>Тогда нафиг список сортированный ? A>Вообще жаль, что Жрланг не может попытаться предсказать модель использования и добавить обратные ссылки
Завтра померяю еще раз зависимости. Мне казалось, что уж никак не линейная, но могу ошибаться
Здравствуйте, Arioch2, Вы писали:
G>>Не, это дает только О(N). К сожалению. По причине отсутствия произвольного доступа к элементам списков, половинное деление невозможно — только линейный поиск.
A>Тогда нафиг список сортированный ?
Их сливать можно за O(N), например.
A>Вообще жаль, что Жрланг не может попытаться предсказать модель использования и добавить обратные ссылки
Этого не умеет делать ни один из известных мне языков. И вообще — я не понимаю как это можно сделать, и главное — как тебе помогут обратные ссылки получить произвольный доступ.
Здравствуйте, Mamut, Вы писали:
M>А можно поинтересоваться, какие системы? Ну хотя бы приблизительно
Распределенный сбор данных с промышленных датчиков. В основном потребление энергии, напряжение и ток, хотя иногда заводят данные и с других агрегатов, например, от контактов.
На одном из рудников эта система ( являющаяся частью большей ) покрывает почти сотню кв. километров поверхности, не говоря уж о шахтных горизонтах. На нее заведена аварийная сигнализация, диспетчерское отображение и расчеты. Первая ступень больше 2-х лет работает. Последний рестарт системы был полгода назад ( это не везде, кое-где часто перезапускают по сврим причинам )
На одном из крупнейших заводов страны собираются и обрабатываются данные со всех подстанций, а потом выгоняются в SQL, чтоб можно было стандартными средствами извне заходить. Последний раз перезапуск был ранней весной
Это к примеру...