Хм. Это не ДСЛ-и. Это ты реализовывал вполне себе стандарный и универсальный скриптовый язык.
CS>Да ты понимаешь... для нового человека в команде много чего учить приходится. Библиотеки , термины, предметную область... CS>И очень сильно сомневаюсь что самодельный language extension содержит при том достаточно документации для освоения.
Дык, а в чем разница с библиотеками? Учить прийдется так же. Но зато потом будет проще ичить код. И ошибок будет меньше.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[24]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, VladD2, Вы писали:
VD>Говоря о Парске мы обнаружили проблемы в синтаксисе которые было предложено решать левыми средствами присутствующими только в одном компиляторе,
Ты запутался, одно дело синтаксис, EBNF, другое дело ByteString, который включается через Rewrite Rules только в GHC и Hugs кажется.
VD>а так же усомнились в производительности данного решения.
Эх!
VD>В прочем я еще сильно сомневаюсь в том, что Парсер обеспечивает внятную диагностику грамматических ошибок (выявление неоднозначностей, например).
Пример неоднозначности дай -- я проверю. А то я не понимаю, что это. Бэктрекинг? Если да, то есть try.
-- попытка раз
someKeyword = string "someKeyword"
identifier = many1 letter
someExpr = someKeyword <|> identifier -- сломается на "someIdentifier"
-- попытка два
someKeyword = string "someKeyword"
identifier = many1 letter
someExpr = try someKeyword <|> identifier -- на "someIdentifier" пройдёт identifier.
Что касается диагностики, то есть <?>:
spaces = skipMany space <?> "white space"
Оно?
VD>На предложение создать реальный (простенький) пример мне было заявлено, что на это нет времени, так как иначе будет некогда отвечать на мои сообщения. Почему-то мне кажется, что время на создание теста должно было бы уйти куда меньше.
Для меня — больше. Мне надо переписать Parsec на ByteString, поглядеть на синтаксис языка С# и написать для него лексер. Причём то, для чего всё это делается — мне совершенно не интересно.
Чувствую придётся всё таки мне переписать Parsec на ByteString и написать какой нибудь простой лексер.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[18]: Являются ли макросы свидетельством недостаточной выр
конкретно это и производится.
K>Правильно ли я понял, что предлагается писать вручную реализации для всех возможных выражений?
Нет. Не правильно. Но вы, я вижу, больше математик, чем программист. Может быть, что-то и не допоняли.
Поскольку из показанного мной решения можно сделать, например, вот такое:
#include <cmath>
#include <iostream>
#include <vector>
typedef std::vector< float > vector_t;
class vector_element_extractor_t
{
public :
virtual float
operator[]( unsigned int index ) const = 0;
virtual unsigned int
size() const = 0;
};
class delayed_scalar_by_vector_multiply_t
: public vector_element_extractor_t
{
public :
delayed_scalar_by_vector_multiply_t(
float a,
const vector_t & b )
: a_( a )
, b_( b )
{}
virtual float
operator[]( unsigned int index ) const
{
return b_[ index ] * a_;
}
virtual unsigned int
size() const
{
return b_.size();
}
private :
float a_;
const vector_t & b_;
};
delayed_scalar_by_vector_multiply_t
operator*(
float a,
const vector_t & b )
{
return delayed_scalar_by_vector_multiply_t( a, b );
}
class delayed_vector_by_scalar_div_t
: public vector_element_extractor_t
{
public :
delayed_vector_by_scalar_div_t(
const vector_t & a,
float b )
: a_( a )
, b_( b )
{
if( fabs( b ) < 0.00000000001 )
throw std::invalid_argument( "devider is 0" );
}
virtual float
operator[]( unsigned int index ) const
{
return a_[ index ] / b_;
}
virtual unsigned int
size() const
{
return a_.size();
}
private :
const vector_t & a_;
float b_;
};
delayed_vector_by_scalar_div_t
operator/(
const vector_t & a,
float b )
{
return delayed_vector_by_scalar_div_t( a, b );
}
class delayed_sum_of_vectors_t
: public vector_element_extractor_t
{
public :
delayed_sum_of_vectors_t(
const vector_element_extractor_t & a,
const vector_element_extractor_t & b )
: a_( a )
, b_( b )
{
if( a.size() != b.size() )
throw std::invalid_argument(
"vectors sizes must be the same" );
}
virtual float
operator[]( unsigned int index ) const
{
return a_[ index ] + b_[ index ];
}
virtual unsigned int
size() const
{
return a_.size();
}
private :
const vector_element_extractor_t & a_;
const vector_element_extractor_t & b_;
};
delayed_sum_of_vectors_t
operator+(
const vector_element_extractor_t & a,
const vector_element_extractor_t & b )
{
return delayed_sum_of_vectors_t( a, b );
}
class delayed_sub_of_vectors_t
: public vector_element_extractor_t
{
public :
delayed_sub_of_vectors_t(
const vector_element_extractor_t & a,
const vector_element_extractor_t & b )
: a_( a )
, b_( b )
{
if( a.size() != b.size() )
throw std::invalid_argument(
"vectors sizes must be the same" );
}
virtual float
operator[]( unsigned int index ) const
{
return a_[ index ] - b_[ index ];
}
virtual unsigned int
size() const
{
return a_.size();
}
private :
const vector_element_extractor_t & a_;
const vector_element_extractor_t & b_;
};
delayed_sub_of_vectors_t
operator-(
const vector_element_extractor_t & a,
const vector_element_extractor_t & b )
{
return delayed_sub_of_vectors_t( a, b );
}
vector_t &
operator<<(
vector_t & receiver,
const vector_element_extractor_t & extractor )
{
receiver.clear();
receiver.reserve( extractor.size() );
for( unsigned int i = 0, i_max = extractor.size();
i != i_max;
++i )
receiver.push_back( extractor[ i ] );
return receiver;
}
std::ostream &
operator<<(
std::ostream & to,
const vector_t & v )
{
for( unsigned int i = 0, i_max = v.size(); i != i_max; ++i )
{
if( i )
to << " ";
to << v[ i ];
}
return to;
}
void
main()
{
const int vector_size = 5;
float a_src[ vector_size ] = { 1, 2, 3, 4, 5 };
float b_src[ vector_size ] = { 0.5, 1.5, 2.5, 3.5, 4.5 };
vector_t a( a_src, a_src + vector_size );
vector_t b( b_src, b_src + vector_size );
vector_t d( b_src, b_src + vector_size );
vector_t c;
c << 0.0 * a + 2.0 * b - 1 * d + b / 0.2;
std::cout << c << std::endl;
}
А если потратить еще некоторое количество времени, то можно сделать еще и поддержку некоторых других сочетаний. Но здесь, вероятно, придется задействовать динамическую память, чтобы классы, производные от vector_element_extractor_t могли сохранять свои операнды по указателю. Чтобы можно было обрабатывать выражения типа:
Но такие операции будут эффективны только на больших размерностях. В противном случае расходы на new/delete окажутся значительно дороже, чем сами вычисления.
K>Это шутка? Если это шутка, то ее можно было бы выразить и короче: K>Зачем макросы, если есть прилежание и усидчивость?
E>>Это демонстрация принципиальной схемы реализации отложенных вычислений в C++, полученная за 15 минут. Более сложные схемы могут быть получены при приложении несколько больших усилий.
K>И, по всей видимости, всего навсего за N * 15 минут, где N — количество всех возможных в линейной алгебре выражений со скалярами, векторами и матрицами? Так ведь можно до конца геологической эпохи не поспеть.
А с макросами, надо полагать, поспели уже.
Видимо, с макросами не нужно все возможные комбинации предусматривать.
E>>Только Nolite mittere margaeritas ante porcas!
K>Да уж, про метание бисера перед свиньями, это к месту, после такого выступления.
Абсолютно.
K>Боюсь, что у меня и в самом деле недостаточно широкие взгляды, для того чтобы оценить такое решение моей задачи по достоинству. Или, может быть, я вовсе не свинья, может быть это бисер у Вас какой-то сомнительный, а?
Все проще. Если вы решаете свои вычислительные задачи в рамках своей работы, то можете сами оценить, во что обходится качественный, надежный, универсальный и расширяемый библиотечный код. Соответственно, можете предположить, что я не могу пренебречь своей собственной работой для того, чтобы потратить несколько дней на проектирование достаточно хорошей библиотеки отложенных векторно-матричных вычислений. Тем не менее, данный код показывает, что в C++ можно значительно к этому делу приблизится.
Сначала я дал точную ссылку на Страуструпа, где показан принцип отложенных вычислений. Розовый слон косвенно обвинил меня в трепачестве. Я потратил 15 минут на воспроизводство примера Страуструпа и еще 15 минут своего времени на оформление сообщения с этим кодом. Это практически все, что я мог себе позволить. Вам этого недостаточно? Отлично, я потратил еще 45 минут на это сообщение и новый пример. Что дальше?
Вы считаете, что я над вами решил поиздеваться? Или вы думаете, что я настолько недалек, что не понимаю, насколько демонстрация принципиальной схемы будет далека от промышленного решения? Или вы думаете, что я такой гений, который может за пару часов повторить что-то вроде Blitz++?
Мне кажется, вы забываете где находитесь и что вам здесь никто ничего не должен.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[18]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, lomeo, Вы писали:
L>2. "Что такое выкрутасы с системой типов Хаскеля? Вот мы тут с konsoletyper про Parsec говорили. Это выкрутасы?" (до сих пор не знаю о чём идёт речь)
Откровенно говоря, для более детального обсуждения было бы неплохо:
1. Иметь реализации одинаковых грамматик на обсуждаемых системах парсинга (ведь мы уже говорим не совсем о Хаскеле или Немерле, а об ДСЛ-ях созданных на их базе).
2. Краткое описание принципов реализации и других деталей.
Без этого, учитывая теоритические знания предмета с обоих сторон, нам вообще тяжело будет разговаривать.
Так что может все же лучше взять более менее законченный пример (может по проще, но все же реальный) и реализовать его двумя способами. Далее описать, что и где нужно установить чтобы можно было поиграться с ним и тогда уже обсудить конкретику. А?
L>3. "Где монады при использовании Парсека?" Это к вопросу о простоте.
Про монады не знаю. Думаю, речь шла "в общем". Уж больно много выкртасов в Хаскеле через них протаскивается.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, lomeo, Вы писали:
L>Здравствуйте, VladD2, Вы писали:
L>>>1. Почему большую сложность реализации? VD>>Потому что окольными путями ходить приходится. Может и не всегда, но частенько.
L>Нуу, это надо конкретные случаи рассматривать.
Согласен. В данном случае это впечатление создавшееся при просмотре того на что давали ссылки в "Деларативном программировании".
VD>>Незачем. Но тут то (в этой теме) высказывается абсолютиская теория о том, что макросы вообще вселенское зло не нужное как класс. В твоей интерпретации все звучит логично. Если вспомнить, что Хаскель единственный гибкий язык, то вообще все ОК. На Немерле я тоже не сую всуду макросы. Если есть прямые и удобные средства языка (а они есть в большинстве случаев), то конечно лучше предпочесть их. Но если задача более эффективно может быть решена путем манипуляции кодом как данными, то на кой черт заниматься пуританством и искать неуклюжие обходные пути?
L>Ну да, чего мы опять эту тему обсасываем?
Дык мы же тему обсуждаем. Сабж то глянь...
L>>>3. Проблема производительности решается не только макросами, честное пионерское. VD>>Вот только макросы позволяют решать ее без шаманства.
L>Сильно сомневаюсь, что только.
Опять же бессмысленный разговор.
VD>>Задача ведь формулируется как? Имеем желательный синтаксис и имеем код который хотим из него получить. Ну, или вроде того. Так зачем же нужно подвергать мозг изнасилованию переводя эту задачу в нечто шаманопдобные и шибко интеллектуальное? Не проще ли ее решить в терминах переписывания кода?
L>Вроде тут говорили не о синтаксисе, а о DSL.
А чем определяется ДСЛ в первую очередь? Ну, можно семантику добавить. Один фиг, в общем-то.
VD>>Нет. Не знаю. У них только два недостатка: VD>>1. Их нужно писать и отлаживать (как любой код). VD>>2. Они меняют семантику языка.
VD>>Оба недостатка будут у любого средства ДСЛ-естроения.
L>Штатные конструкции меняют семантику? Или ты что то другое хотел сказать?
А язык Парсека оказывается рассматривается как штатный синтиаксис? Ты действительно смотришь на грамматику как на набор комбинаторов?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, lomeo, Вы писали:
VD>>Мне совершенно все равно как там работает bytestring. Но мне очень интересно сравнить Хаскель с его подходом к ДСЛ-естроению с Немерле на реальной (боевой, можнос сказать) задаче. А вот наши беседы мне становятся менее и менее интересны, и не потому, что я тебя не уважаю или стопроцентно уверен в своем мнении, а потому, что не несут рационального зерна. Это не более чем наши мнения.
L>ОК. Понимаю, тебе интересно. Мне не очень -- просто в силу того, что знание это никакой пользы для меня иметь не будет. Может быть очень маленькую. А вот сил я затрачу массу на написание лексера языка, с которым я не работаю.
Как минимум ты (мы, точнее) сможешь в своих утверждениях ссылаться на четкие эксперементальные данные. Это уже немало. Что до времени, то на пустую болтавню мы тут его больше убили. А так глядишь еще статейку забацали бы совместными усилиями — "Сравнительный анализ разных подходов к ДСЛ-естроению" — звучить, однако!
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[25]: Являются ли макросы свидетельством недостаточной выр
Вряд ли. Речь идет о сообщениях при компиляции о том, что в грамматике есть неоднозначность или другая ошибка. Плюс интересно что за сообщения выдает конечный парсер когда ему дают текст с ошибками (не соответствующий грамматике).
L>Для меня — больше. Мне надо переписать Parsec на ByteString, поглядеть на синтаксис языка С# и написать для него лексер. Причём то, для чего всё это делается — мне совершенно не интересно.
Стало быть рассказы о лекости и крутости сильно преувеличены? Иначе чем объяснить, что при наличии готовой грамматики нужно тратить столько сил? Ведь казалось бы замени по контексту синтаксические нюансы и вуаля...
L>Чувствую придётся всё таки мне переписать Parsec на ByteString и написать какой нибудь простой лексер.
Да фиг с ним с байтсрингом для начала бы можно и попроще. Неоптимальности потом можно подправить. Хотя бы будет на что смотреть.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, VladD2, Вы писали:
VD>А чем определяется ДСЛ в первую очередь? Ну, можно семантику добавить. Один фиг, в общем-то.
Приближенностью к предметной области. Это вовсе не обязательно синтаксис.
VD>А язык Парсека оказывается рассматривается как штатный синтиаксис? Ты действительно смотришь на грамматику как на набор комбинаторов?
Знаешь, не задумывался об этом. Когда как, наверное. Но я имел в виду именно "изменение семантики". Это всё таки Хаскель, так что на грамматику, выраженную на Parsec, иногда смотрю как на комбинаторы. Т.е. как на сущности первого порядка. Это позволяет, например, использовать их в выражениях:
вместо
variable = do
x <- identifier
return (Var x)
пишу
variable = liftM Var identifier
и это читается (мне) естественно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, VladD2, Вы писали:
VD>Так что может все же лучше взять более менее законченный пример (может по проще, но все же реальный) и реализовать его двумя способами. Далее описать, что и где нужно установить чтобы можно было поиграться с ним и тогда уже обсудить конкретику. А?
Эх, ну, давай У вас ещё был JSON. Там писать совсем ничего, да и у вас он уже, насколько я помню, написан.
Кстати, спросить хотел. konsoletyper'а парсер пишется в отдельном файле? Это не встроенный в Немерле язык или что? Можно о его организации чуть чуть — это что то вроде изменения лиспового ридера?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[26]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, VladD2, Вы писали:
VD>Ну, не знаю. Парсер то какого типа получается? LL(k) или там еще что?
Да, для lookahead (например, твои примеры) используется try.
VD>Вряд ли. Речь идет о сообщениях при компиляции о том, что в грамматике есть неоднозначность или другая ошибка. Плюс интересно что за сообщения выдает конечный парсер когда ему дают текст с ошибками (не соответствующий грамматике).
Нет, компилятор неоднозначности не найдёт. Ты же о компиляторе Хаскеля? Не думаю, что он умеет определять, что в строках "public", "private" и "protected" все слова начинаются на одну букву
Сам же парсер выдаёт либо сообщение о несработавшем комбинаторе (если поставить явный <?>). Либо говорит о том, что ожидается то-то, а найдено то-то.
VD>Стало быть рассказы о лекости и крутости сильно преувеличены? Иначе чем объяснить, что при наличии готовой грамматики нужно тратить столько сил? Ведь казалось бы замени по контексту синтаксические нюансы и вуаля...
Так у С# грамматика должна быть не маленькая верно?
VD>Да фиг с ним с байтсрингом для начала бы можно и попроще. Неоптимальности потом можно подправить. Хотя бы будет на что смотреть.
Ясно. Я думал, тебя производительность интересовала в первую очередь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[16]: Являются ли макросы свидетельством недостаточной выр
L>Ты запутался, одно дело синтаксис, EBNF, другое дело ByteString, который включается через Rewrite Rules только в GHC и Hugs кажется.
в hugs нет rewrite rules — нахрена они там?
VD>>В прочем я еще сильно сомневаюсь в том, что Парсер обеспечивает внятную диагностику грамматических ошибок (выявление неоднозначностей, например).
неоднозначностей — скорее нет, это надо делать вручную. дело в том, что он ориентирован на практическое применение и хранить все возможные варианты разбора — это нереально. другие монадические парсеры, в частности используемый в реализации read (аналог atoi, парсящий любой определённый пользователем тип данных), могут это делать
а вообще диагностика там есть и очень удобно подцепляется комбинатором <?>
L>Чувствую придётся всё таки мне переписать Parsec на ByteString и написать какой нибудь простой лексер.
если не ошибаюсь, это один из GSOC проектов этого года
и разумеется, ты прав, что всё это делается с помощью монад. монады — это просто универсальный способ написания "фабрик кода", что-то типа поддержки создания паттернов в самом языке. монады, создаваемые для парсинга, весьма напоминают Прологовский механизм унификации с бэктрекингом. просто здесь он реализован в виде библиотеки, а монады обеспечивают необходимый сахар в лице 'do' плюс high-order functions
Люди, я люблю вас! Будьте бдительны!!!
Re[26]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, BulatZiganshin, Вы писали:
L>>Ты запутался, одно дело синтаксис, EBNF, другое дело ByteString, который включается через Rewrite Rules только в GHC и Hugs кажется.
BZ>в hugs нет rewrite rules — нахрена они там?
Ух, это я прогнал.
L>>Чувствую придётся всё таки мне переписать Parsec на ByteString и написать какой нибудь простой лексер.
BZ>если не ошибаюсь, это один из GSOC проектов этого года
Э-э-э, а там какие-то сложности?
Вместо CharParser написать свой (+ все комбинаторы над ним, разумеется), для этого State для GenParser сделать либо независимым от списка токенов, т.е. с возможностью использования любой коллекции, ну или сам State сделать классом, а не типом.
Кстати, уже что нибудь есть в этом проекте? Есть где почитать?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Являются ли макросы свидетельством недостаточной выра
VD>В общем, не спорю, что сувать всюду макросы не нужно. Работая над интеграцией я применил макросы всего пару раз (хотя кода там не так мало было в проекте). Но за то даже один из этих раз дал мне такой прорывной эффект, что никакие хаскели (без метапрограммирования) и рядом не волялись. Например, я с помощь макросов накенерировал код инкрементального изменения (relocation) положений строк (Location-ов). При редактировании кода во многих случаях можно не перепарсивать файл, а просто поправить Location-ы. Получается куча шаблонного кода отличающегося разными нюансами плюс еще сами поля Location-ов нужно отследить. Вручную это было бы нереально. А с макросом вполне реально. Перебрал все типы, выявил те что содержат Location-ы, добавил в них код пересчета, вызвал их рекурсивно и вуаля. И таких примеров масса. А ведь это еще не ДСЛ-ли даже, а так мелкая втоматизация.
а достаточно ли ты хорошо знаешь хаскел, чтобы это утверждать? это как раз типичная задача на generic programming, которое в хаскеле цветёт бурным цветом (даже я смог насчитать десяток различных средств для него, а ведь я так, мелкий пользователь)
у одного из спецов, работающих в этой сфере, любимый пример — есть развесистая структура данных, представляющая собой структуру некоей организации. нужно увеличить зарплату всем сотрудникам организации на 10% если для представления зарплат выделен специальный тип данных:
data Salary = Salary Double
то это делается одной строчкой:
gmap (\Salary x -> Salary (x*1.1))
в общем и целом, generic программирование обеспечивает автоматическую навигацию по любым контейнерам с организацией обработки только интересующих нас частей информации. основные алгоритмы — gmap, отображающий структуру данных в изоморфную ей, gfold, собирающий информацию (скажем, сумму всех зарплат или список номеров кабинетов), gunfold, конструирующий структуру данных (скажем, при десериализации), gzip, обрабатывающий параллельно два объекта с одинаковой структурой
а наиболее известная статья в этой области — "Scrap your boilerpate!", т.е. "выкиньте ваш шаблонный код!" — как будто написана специально для тебя
по теме: ответ да. другое дело, что абсолютно выразительных языков не бывает, в хаселе тоже без макросов не всегда обойдёшься. так что вопрос не в наличии их в языке (запас карман не тянет), а в том, когда их приходится применять. скаждем, хорошо известно, что многие фичи, которые в раннем С реализовывались с помощьтю макросов (от определеняи констант до полиморфного кода), в C++ стали частью языка. и наверно, никто не будет спорить с тем, что это упростило разработку программ
то же самое относится и к немерле или хаскелю — случаи, когда приходится применять макросы, высвечивают недостатки языка. хорошо, что эти проблемы можно решить хотя бы так, но ещё лучше, если бы макросы совсем не были нужны. особенно кстати это относится к хаскелю, где TH реализован только в одном компиляторе и крайне неудобен в использовании — имо это главным образом инструмент защиты диссертаций, а не реального порграммирования
на Немерле, насколько я понял, макросы писать проще, но ситуации, когда их приходится использовать, точно так же высвечивают недостатки языка (и вообще всех языков этой группы). например, в хаскеле можно определять управляющие стурктуры — это всего лишь high-order функции, и они пишутся, используются, типо-порверяются, и передаются куда угодно как самые обычные функции. в немерле, С или лиспе это макросы, имеющие иной способ описания и не проверяющие типы своих аргументов
Люди, я люблю вас! Будьте бдительны!!!
Re[12]: Являются ли макросы свидетельством недостаточной выр
VD>Нет. Не знаю. У них только два недостатка: VD>1. Их нужно писать и отлаживать (как любой код). VD>2. Они меняют семантику языка.
VD>Оба недостатка будут у любого средства ДСЛ-естроения.
похоже, ты путаешь DSL и eDSL. DSL — это просто любой язык, интерепретатор/компилятор которого ты реализуешь. embedded DSL — это DSL, реализованный как расширение твоего ЯП. через доп. функции, классы, макросы и т.д. т.е. библиотека матричных операций — это уже eDSL. а скажем, любой язык, реализуемый с помощью ParseC — это DSL, но при этом сам ParseC реализует eDSL для описания грамматик
ещё примеры: всякие boost::lambda — это eDSL функционального программирования внутри C++, а byson или regexps — это средства создания DSL
Люди, я люблю вас! Будьте бдительны!!!
Re[18]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, eao197, Вы писали:
VD>Пояснил бы суть решения...
просто операции +, * и т.д. создают в памяти структуру, описывающую вычисляемое выражание, а собственно вычисление происходит по спец. команде. в точности то же, что делают lazy языки на уровне самой реализации
Люди, я люблю вас! Будьте бдительны!!!
Re[18]: Являются ли макросы свидетельством недостаточной выр
L>Нет. По сути — разное. На макросах можно вообще целую кучу всего написать, сам говоришь, что они "могут делать все что им угодно с кодом проекта". Рулезы более специфичное решение, возможно, его можно повторить на макросах, возможно, удастся создать удобную форму для записи этих рулезов, но это не значит, что рулезы и макросы по сути одно и то же.
а по-моему, RULES — это частный случай макросов, нацеленный на решение одной конкретной задачи. кстати, TH для оптимизации кода тоже использовали. при этом с одной стороны возможности RULES очень ограничены, с другой — их писать гораздо-гораздо проще, чем аналогичное решение с помощью TH. универсальность против удобства использования. и исхо RULES составляют существенную часть механизма оптимизации GHC — в них вынесены многие вещи которые иначе пришлось бы делать внутри компилятора. без них -O2 просто не взлетит и их нужно рассматривать как успещно вынесенную наружу часть компилятора
кстати, также можно смотреть и на макросы Немерле. в этом отношении понятно, что макросы лучше жёстко зашитого в компилятор кода (хотя в средствах диагностики они и проигрывают), но хуже возможности, доступной на уровне языка
Люди, я люблю вас! Будьте бдительны!!!
Re[20]: Являются ли макросы свидетельством недостаточной выр
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, lomeo, Вы писали:
L>>Ой сорри. Я имел в виду ByteString (Duncan Coutts, Don Stewart)
L>>Начать можно отсюда: Data.ByteString L>>Основная статья: Rewriting Haskell Strings
VD>"Byte" означает то о чем я подумал, и Юникод Хаскелю незнаком?
не хаскелю, а байтовым строкам. интересно, ты вообще хоть что-нибудь читаешь из всех ссылок, что тебе приводят?