Способно ли метапрограммирование заменить отдельные языки?
От: Chrome  
Дата: 01.02.11 09:00
Оценка:
Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.
Позволяет самим реализовать фичи, которые нужны вам сейчас.
Позволяет отказаться от ненужного наследства.
Эти два фактора, как мне кажется, являются двужущей силой для изобретения новых языков программирования и смерти существующих.
Наличие платформы метапрограммирования резко снижает расходы на создание собственного языка или диалекта существующего.
У вас уже есть back end компилятора, который умеет создавать все примитивы runtime платформы — остается придумать грамматику и транслировать ее в эти примитивы.
Это, конечно, само по себе крупная задача, не не такая неподьемная, как целый компилятор.
Кроме того, можно ограничиться расширением существующего языка.

Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.
Можно ли за аналогичное време реализовать эрланг? F#?
Если сроки реально такого порядка — стоит ли ожидать в будущем отдельный диалект языка программирования на каждую программерскую контору или крупный проект?
Re: Способно ли метапрограммирование заменить отдельные язык
От: Sinix  
Дата: 01.02.11 09:20
Оценка: +2
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

И создаёт кучу проблем с совместимостью/неоднозначностью грамматик/защитой от очередных религиозных фанатиков/поддержкой инструментария. Для мейнстрима дизайном языка должны заниматься специалисты, а метапрограммирование лучше ограничить AOP.

C>Позволяет самим реализовать фичи, которые нужны вам сейчас.

Фич, которые не могут быть реализованы внутри библиотек-хелперов, очень мало.

C>Позволяет отказаться от ненужного наследства.

Как?


C>Наличие платформы метапрограммирования резко снижает расходы на создание собственного языка или диалекта существующего.

Зачем? Для DSL нужна очень большая инфраструктура аля M. Последний, кстати, не взлетел.

Для полноценных языков (если мы не собираемся гнать погонными метрами клоны существующих) толку от метапрограммирования как такового тоже очень мало. Выигрыш от кучи диалектов можно наблюдать на примере SQL.

C>У вас уже есть back end компилятора, который умеет создавать все примитивы runtime платформы — остается придумать грамматику и транслировать ее в эти примитивы.

Язык не ограничивается одним синтаксисом. Большинство интересных плюшек идёт в виде довеска к рантайму или в виде генерации дополнительных типов данных.

C>Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.

Нет, 2 месяца — это на немерль с синтаксисом шарпа. Полноценный компилятор, со всеми прелестями и нюансами — на порядок больше работы.

C>Можно ли за аналогичное време реализовать эрланг? F#?

Да, только по поведению это будет всё тот же nemerle.

C>Если сроки реально такого порядка — стоит ли ожидать в будущем отдельный диалект языка программирования на каждую программерскую контору или крупный проект?

Конечно. Это самый лучший способ протратить ресурсы.
Re: Способно ли метапрограммирование заменить отдельные язык
От: Fancy  
Дата: 01.02.11 09:25
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

C>Позволяет самим реализовать фичи, которые нужны вам сейчас.
C>Позволяет отказаться от ненужного наследства.
C>Эти два фактора, как мне кажется, являются двужущей силой для изобретения новых языков программирования и смерти существующих.
C>Наличие платформы метапрограммирования резко снижает расходы на создание собственного языка или диалекта существующего.
C>У вас уже есть back end компилятора, который умеет создавать все примитивы runtime платформы — остается придумать грамматику и транслировать ее в эти примитивы.
C>Это, конечно, само по себе крупная задача, не не такая неподьемная, как целый компилятор.
C>Кроме того, можно ограничиться расширением существующего языка.

C>Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.

C>Можно ли за аналогичное време реализовать эрланг? F#?
C>Если сроки реально такого порядка — стоит ли ожидать в будущем отдельный диалект языка программирования на каждую программерскую контору или крупный проект?
Re: Способно ли метапрограммирование заменить отдельные язык
От: Fancy  
Дата: 01.02.11 09:29
Оценка:
Думается мне что это привлекательное решение смогут оценить только её сторонники. Чтобы это оценил кто-то ещё, нужно, во-первых, чтобы кто-то с помощью этой технологии реализовал что-то прибыльное, и во-вторых, заявил об этом на весь мир. Даже если энтузиастам удастся решить первую задачу, вторая может не принести никаких плодов, если конечно не брать в расчёт минутную славу и шум вокруг чего-то "принципиально нового".
Re: Способно ли метапрограммирование заменить отдельные язык
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 01.02.11 09:36
Оценка: +1 -1

Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку. Позволяет самим реализовать фичи, которые нужны вам сейчас. Позволяет отказаться от ненужного наследства.


Частично реализовано в LISP, полностью реализовано в Tcl.

Наличие платформы метапрограммирования резко снижает расходы на создание собственного языка или диалекта существующего


Кроме плюсов возникают минусы. Посмотрите на практику применения DSL: чем более сложный DSL мы применяем, тем поще и быстрее нам код писать, но тем сложнее и дольше его поддерживать другим людям. Соответственно, это не так популярно потому как компании хотят защититься от эффекта падающего кирпича. Если архитектор DSL покинет компанию или даже заболеет — будут большие проблемы. ОЧЕНЬ большие проблемы.

Эти два фактора, как мне кажется, являются двужущей силой для изобретения новых языков программирования и смерти существующих.


Там, ИМХО, намного больше факторов — инфраструктура, простота реализации тех или иных вещей (зачастую диаметрально противоположных), развертывание, поддержка и прочее.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: 0x7be СССР  
Дата: 01.02.11 09:44
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Кроме плюсов возникают минусы. Посмотрите на практику применения DSL: чем более сложный DSL мы применяем, тем поще и быстрее нам код писать, но тем сложнее и дольше его поддерживать другим людям. Соответственно, это не так популярно потому как компании хотят защититься от эффекта падающего кирпича. Если архитектор DSL покинет компанию или даже заболеет — будут большие проблемы. ОЧЕНЬ большие проблемы.

Тут ключевое слово не "DSL", а "сложный".
Когда мы создаем систему абстракций (классов, интерфейсов, функций и т.п.), то мы тоже создаем свой язык, и если эта система будет сложной, то эффект кирпича тут будет такой же, как и у DSL.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 10:18
Оценка:
Здравствуйте, Sinix, Вы писали:

C>>Позволяет самим реализовать фичи, которые нужны вам сейчас.

S>Фич, которые не могут быть реализованы внутри библиотек-хелперов, очень мало.
Как вы обьясняете для себя существование множества языков программирования?
для чего то люди их выдумывают?
На мой взгляд — именно от невозможности реализовать что либо в библиотеке.

C>>Позволяет отказаться от ненужного наследства.

S>Как?
написать грамматику, в которой не будет устаревших конструкций — например указателей, если они вам не нужны.


C>>Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.

S>Нет, 2 месяца — это на немерль с синтаксисом шарпа. Полноценный компилятор, со всеми прелестями и нюансами — на порядок больше работы.

Не понял этого замечания — этот "немерль с синтаксисом шарпа" умеет компилить программы на шарпе?
на мой вкус это и есть компилятор шарпа, и затраты на это — 2 месяца...

C>>Можно ли за аналогичное време реализовать эрланг? F#?

S>Да, только по поведению это будет всё тот же nemerle.
что имеется в виду под поведением? в чем отличие от оригинального F#?
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: alpha21264 СССР  
Дата: 01.02.11 10:21
Оценка: 6 (1) +1
Здравствуйте, Chrome, Вы писали:

C>Здравствуйте, Sinix, Вы писали:


C>>>Позволяет самим реализовать фичи, которые нужны вам сейчас.

S>>Фич, которые не могут быть реализованы внутри библиотек-хелперов, очень мало.
C>Как вы обьясняете для себя существование множества языков программирования?
C>для чего то люди их выдумывают?
C>На мой взгляд — именно от невозможности реализовать что либо в библиотеке.

Не переоценивай разумность человечества.
Чаще всего это делается потому что у кого-то "творческий зуд".
Изобретение вечного двигателя из той же оперы.

Течёт вода Кубань-реки куда велят большевики.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 10:48
Оценка:
C>>Если сроки реально такого порядка — стоит ли ожидать в будущем отдельный диалект языка программирования на каждую программерскую контору или крупный проект?
S>Конечно. Это самый лучший способ протратить ресурсы.

2 человеко месяца — не выглядит сколь нибудь серьезным ресурсом.
меня собственно и заинтересовало — неужели реально с такой скоростью клепать языки?
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Mamut Швеция http://dmitriid.com
Дата: 01.02.11 11:08
Оценка: 1 (1) +1
C>>>Можно ли за аналогичное време реализовать эрланг? F#?
S>>Да, только по поведению это будет всё тот же nemerle.
C>что имеется в виду под поведением? в чем отличие от оригинального F#?

На примере Erlang'а. Erlang — это не только синтаксис. Это и легковесные потоки, и асинхронные сообщения, и архитектура shared-nothing и т.д. и т.п. Для того, чтобы реализовать этона Немерле, ндо писать рантайм (грубо говоря) эрланга на Нмерле


dmitriid.comGitHubLinkedIn
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 01.02.11 11:11
Оценка:

Тут ключевое слово не "DSL", а "сложный".


Вы правы — именно это я и ответил автору . Своя грамматика = сложный DSL.

Когда мы создаем систему абстракций (классов, интерфейсов, функций и т.п.), то мы тоже создаем свой язык, и если эта система будет сложной, то эффект кирпича тут будет такой же, как и у DSL.


Не-е-е-е, тут, ИМХО, мы не создаем свой язык — мы создаем абстракции на базе известного программистам языка/технологии. Если у меня архитектура actor model на Qt, то знающий C++ и Qt человек ее поймет, потому что все примитивы и приемы кодирования ему известны. А вот если я под эту actor model наваяю собственный синтаксис, который уменьшит количество моего кода в пару-тройку раз, то с этим синтаксисом новому человеку будет разобраться намного сложнее. А уж поменять что-нибудь — большой проблемой.
Re: Способно ли метапрограммирование заменить отдельные язык
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 11:15
Оценка: +2 -2
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

C>Позволяет самим реализовать фичи, которые нужны вам сейчас.
C>Позволяет отказаться от ненужного наследства.
C>Эти два фактора, как мне кажется, являются двужущей силой для изобретения новых языков программирования и смерти существующих.
C>Наличие платформы метапрограммирования резко снижает расходы на создание собственного языка или диалекта существующего.
Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.
Вот изменяемая грамматика этому крайне не способствует.

C>У вас уже есть back end компилятора, который умеет создавать все примитивы runtime платформы — остается придумать грамматику и транслировать ее в эти примитивы.

C>Это, конечно, само по себе крупная задача, не не такая неподьемная, как целый компилятор.
C>Кроме того, можно ограничиться расширением существующего языка.
А теперь вопрос: если одни и те же задачи можно решать библиотекой или расширением\изменением\созданием нового языка, то что ты выберешь?

Может все таки стремиться не столько к изменяемым языкам, сколько к возможности выразить максимум средствами языка?
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 11:28
Оценка:
Здравствуйте, Mamut, Вы писали:

C>>>>Можно ли за аналогичное време реализовать эрланг? F#?

S>>>Да, только по поведению это будет всё тот же nemerle.
C>>что имеется в виду под поведением? в чем отличие от оригинального F#?

M>На примере Erlang'а. Erlang — это не только синтаксис. Это и легковесные потоки, и асинхронные сообщения, и архитектура shared-nothing и т.д. и т.п. Для того, чтобы реализовать этона Немерле, ндо писать рантайм (грубо говоря) эрланга на Нмерле


суть моего оригинального вопроса состояла в следующем
— предположим, эрланга в природе еще нет,
и его идеи только что родились в моей гениальной голове.
Что мне выбрать — написать рантайм, и компилятор, и прикрутить это к какой нибудь среде программирования
или взять платформу метапрограммирования вроде немерле, реализовать на ней синтаксис,
допилить таки недостающие части рантайма — те самые легковесные потоки и сообщения.
(заметьте, мне не нужно писать весь рантайм, 90% уже есть).

второй путь кажется более быстрым
и не является чем то громоздким — по сложности — как обычная библиотека.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.02.11 11:34
Оценка:
Здравствуйте, Chrome, Вы писали:

C>суть моего оригинального вопроса состояла в следующем

C>- предположим, эрланга в природе еще нет,
C>и его идеи только что родились в моей гениальной голове.
C>Что мне выбрать — написать рантайм, и компилятор, и прикрутить это к какой нибудь среде программирования
C>или взять платформу метапрограммирования вроде немерле, реализовать на ней синтаксис,
C>допилить таки недостающие части рантайма — те самые легковесные потоки и сообщения.
C>(заметьте, мне не нужно писать весь рантайм, 90% уже есть).

90% — это ты про дотнет?
Если да, то есть некоторые проблемы, скажем ГЦ сильно другой и др. (подробнее — в архиве
Автор: Lazy Cjow Rhrr
Дата: 12.12.06
)
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 11:45
Оценка:
EOH>Не-е-е-е, тут, ИМХО, мы не создаем свой язык — мы создаем абстракции на базе известного программистам языка/технологии. Если у меня архитектура actor model на Qt, то знающий C++ и Qt человек ее поймет, потому что все примитивы и приемы кодирования ему известны. А вот если я под эту actor model наваяю собственный синтаксис, который уменьшит количество моего кода в пару-тройку раз, то с этим синтаксисом новому человеку будет разобраться намного сложнее. А уж поменять что-нибудь — большой проблемой.

Неужели перспектива сократить код в 2-3 раза
не сподвигнет вас на изучение небольшого расширения синтаксиса?
я так полагаю, введение вашей actor model (не знаю, что это такое по сути)
не повлиеяет на такие понятия в вашей программе, как namespace, class, fields, methods, foreach и куча всего другого — они останутся неизменны, добавится небольшое расширение — которое увеличит производительность вашего труда.
перешли же люди на с with classes.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: hardcase Пират http://nemerle.org
Дата: 01.02.11 11:48
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>если я под эту actor model наваяю собственный синтаксис, который уменьшит количество моего кода в пару-тройку раз, то с этим синтаксисом новому человеку будет разобраться намного сложнее.


Если синтаксис действительно настолько крут, что настолько уменьшает количество кода, то затраты на обучение ему (совсем не такие большие как кажутся) окупаются скоростью разработки и качеством результата.

EOH>А уж поменять что-нибудь — большой проблемой.


А от это уже зависит от качества реализации "собственного синтаксиса".


Разве никто не здесь не допускает возможности того, что сложность реализации "синтаксиса" эквивалентна написанию библиотеки, а удобство использования в определенных случаях может быть значительно выше?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 12:09
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>Вот изменяемая грамматика этому крайне не способствует.
думаю, раз существуют разные языки — есть потребность в разных грамматиках.


G>А теперь вопрос: если одни и те же задачи можно решать библиотекой или расширением\изменением\созданием нового языка, то что ты выберешь?


G>Может все таки стремиться не столько к изменяемым языкам, сколько к возможности выразить максимум средствами языка?


я не против, поэтому говорю в основном про расширение синтаксиса, в тех случаях, когда нельзя лаконично выразить свою мысль существующими средствами языка.
да и само раширение синтаксиса(в свете метапрограммирования) является ничем иным, как библиотекой
так что ваш вопрос можно рассматривать
как выбор между библиотекой и библиотекой.
разница будет в местах вызова элементов этих библиотек.
в стандартном синтаксисе вызовы будут раздуты
в измененном синтаксисе — лаконичны
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 12:23
Оценка:
Здравствуйте, Курилка, Вы писали:

C>>(заметьте, мне не нужно писать весь рантайм, 90% уже есть).


К>90% — это ты про дотнет?

К>Если да, то есть некоторые проблемы, скажем ГЦ сильно другой и др. (подробнее — в архиве
Автор: Lazy Cjow Rhrr
Дата: 12.12.06
)


про дотнет — это частность.
я про простоту реализации нового синтаксиса языков на базе метапрограммирования.

замечание про гц никак не влияет на нашу способность реализовать эрланг под дот нет.
он будет работать. но потеряет свойства realtime
но это свойство не присуще именно .net runtime.
и никак не связано с синтаксисом и семантикой эрланга.
нам просто нужен бек энд компилятора для realtime runtime

в общем, языки и рантаймы — это разные вещи.
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 12:26
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Здравствуйте, gandjustas, Вы писали:


G>>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>>Вот изменяемая грамматика этому крайне не способствует.
C>думаю, раз существуют разные языки — есть потребность в разных грамматиках.
Сомневаюсь. Ты хоть раз ощущал потребность в новой грамматике?
У меня такое было только с паскалем, когда задалбывало begin\end писать, но это мелочи.

G>>А теперь вопрос: если одни и те же задачи можно решать библиотекой или расширением\изменением\созданием нового языка, то что ты выберешь?


G>>Может все таки стремиться не столько к изменяемым языкам, сколько к возможности выразить максимум средствами языка?

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

C>разница будет в местах вызова элементов этих библиотек.

C>в стандартном синтаксисе вызовы будут раздуты
C>в измененном синтаксисе — лаконичны
А что мешает сделать вызовы лаконичными без изменения синтаксиса?
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.02.11 12:30
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Здравствуйте, Курилка, Вы писали:


C>>>(заметьте, мне не нужно писать весь рантайм, 90% уже есть).


К>>90% — это ты про дотнет?

К>>Если да, то есть некоторые проблемы, скажем ГЦ сильно другой и др. (подробнее — в архиве
Автор: Lazy Cjow Rhrr
Дата: 12.12.06
)


C>про дотнет — это частность.

C>я про простоту реализации нового синтаксиса языков на базе метапрограммирования.

C>в общем, языки и рантаймы — это разные вещи.


Ну тогда не пиши про рантайм, если речь не о нём
Re: Способно ли метапрограммирование заменить отдельные язык
От: FR  
Дата: 01.02.11 12:33
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.


Все это не раз проходили, не прижилось.
Один из первых языков на котором я профессионально начал программировать это Форт, ожидания от него были практически такие же как от
Немерла, еще раньше тоже самое было с Лиспом, и совсем печально с Dylan,
не помогла даже поддержка Apple, притом Dylan по возможностям очень близок к Немерле http://www.opendylan.org/books/drm/Language_Overview.html
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 12:37
Оценка:
Здравствуйте, Chrome, Вы писали:

C>в общем, языки и рантаймы — это разные вещи.


Угу и многие языки без соответствующего рантайма никому не нужны.
Даже те же питон и руби в конце концов потребовали изменения рантайма NET.
OCaml превратившись в F# тоже много чего растерял.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 13:10
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Chrome, Вы писали:


C>>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.


FR>Все это не раз проходили, не прижилось.

FR>Один из первых языков на котором я профессионально начал программировать это Форт, ожидания от него были практически такие же как от
FR>Немерла, еще раньше тоже самое было с Лиспом, и совсем печально с Dylan,
FR>не помогла даже поддержка Apple, притом Dylan по возможностям очень близок к Немерле http://www.opendylan.org/books/drm/Language_Overview.html

я пытаюсь понять, есть ли причины, которые заставят вас писать собственный компилятор изобретенного вами языка программирования, вместо того, что бы воспользоаватся метапрограммированием немерла, например(когда он позволит компилировать любой пользовательский синтаксис и позволит отключить собственный)
учитывая, что озвучены временные затраты порядка 2 месяцев на имплементацию с#
если причины есть — назовите их
Re: Способно ли метапрограммирование заменить отдельные язык
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 01.02.11 13:20
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

C>Позволяет самим реализовать фичи, которые нужны вам сейчас.

А много ли таких фичей? Лично я метапрограммирование больше применял для описания некоторых данных, которые потом переводились в разные таблицы.
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Sinix  
Дата: 01.02.11 13:23
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Как вы обьясняете для себя существование множества языков программирования?

C>для чего то люди их выдумывают?
C>На мой взгляд — именно от невозможности реализовать что либо в библиотеке.

2 основных причины:
1. Критический объём фишек, которые нельзя реализовать силами существующих языков/рантаймов. Сюда же относятся узкопрофильные ЯП, желание попробовать скомбинировать идеи из различных типов ЯП и попытка изобрести принципиально новый ЯП.
2. Обострённый синдром NIH+избыток лишней энергии+нежелание изучать готовые решения. Забавная закономерность: окружающие очень скоро объявляются полными идиотами, а похожие языки, как один, страдают от фатальных недостатков.

C>>>Позволяет отказаться от ненужного наследства.

S>>Как?
C>написать грамматику, в которой не будет устаревших конструкций — например указателей, если они вам не нужны.
А почему бы просто не использовать устаревшие конструкции и не мучать окружающих?



C>>>Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.
S>>Нет, 2 месяца — это на немерль с синтаксисом шарпа. Полноценный компилятор, со всеми прелестями и нюансами — на порядок больше работы.
C>Не понял этого замечания — этот "немерль с синтаксисом шарпа" умеет компилить программы на шарпе?
Нет — поведение скомпилированного кода не будет совпадать с поведением оригинальной программы. Фактически, там транслятор c# в AST немерла. Немерлисты! Если ошибаюсь — поправьте, ок?

C>>>Можно ли за аналогичное време реализовать эрланг? F#?

S>>Да, только по поведению это будет всё тот же nemerle.
C>что имеется в виду под поведением? в чем отличие от оригинального F#?
См выше.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 01.02.11 13:44
Оценка: +2
Здравствуйте, Sinix, Вы писали:

C>>написать грамматику, в которой не будет устаревших конструкций — например указателей, если они вам не нужны.

S>А почему бы просто не использовать устаревшие конструкции и не мучать окружающих?

Чтобы не использовать устаревшие конструкции, надо чтобы остальные вещи можно было бы использовать без этих устаревших конструкций.
Пример с указателями это очень хорошо показывает.
Вселенная бесконечна как вширь, так и вглубь.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 01.02.11 13:56
Оценка:
Здравствуйте, Sinix, Вы писали:

S>А почему бы просто не использовать устаревшие конструкции и не мучать окружающих?

одна причина — элегантных синтаксических конструкций не так много,
и они оказываются нагружены устаревшими понятиями
например &x *x x->y занимаются ненужной нам адресной арифметикой
а мы могли бы приспособить их, например, для ленивых вычислений
или x|y x&y по традиции заняты возней с битами, что тоже не очень востребовано в нашем проекте
учитывая весь этот багаж, для наших целей остаются такие монстры, как x^^, a&&&b, x==>y, что уродливо.

во вторых, я, как руководитель проекта, могу захотеть запретить адресную арифметику в своем проекте
и ограничения синтаксиса пришлись бы кстати.
Вообще хороший фреймворк оставляет доступными только проверенные и предписанные тропинки для хождения по граблям. То же относится и к языку программирования.


C>>>>Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.

S>>>Нет, 2 месяца — это на немерль с синтаксисом шарпа. Полноценный компилятор, со всеми прелестями и нюансами — на порядок больше работы.
C>>Не понял этого замечания — этот "немерль с синтаксисом шарпа" умеет компилить программы на шарпе?
S>Нет — поведение скомпилированного кода не будет совпадать с поведением оригинальной программы. Фактически, там транслятор c# в AST немерла. Немерлисты! Если ошибаюсь — поправьте, ок?

ну приведите пример программы на с#, когда поведение будет отличаться.
даже если такой пример найдется, останется только занести его в баг лист и зафиксить.
понятно что генерируемый код будет несколько разный.
Такое бывает, например, в компиляторах C++ разных фирм или версий
— но никто не говорит, что у них "разное поведение"
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 01.02.11 14:02
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>Вот изменяемая грамматика этому крайне не способствует.
Необходимость заниматься реверсинжинерингом задумки разработчика этому еще меньше способствует.
var file = File.Open(...);
try
{
}
finally
{
    if (file != null)
        file.Dispose();
}

против
using (file = File.Open(...))
{
}

И это очень простой пример.

G>А теперь вопрос: если одни и те же задачи можно решать библиотекой или расширением\изменением\созданием нового языка, то что ты выберешь?

Если кода будет примерно одинакого то библиотеку.
А если синтаксисом код можно ужать хотябы в пару раз то синтаксис.

G>Может все таки стремиться не столько к изменяемым языкам, сколько к возможности выразить максимум средствами языка?

Ну иди попробуй выразить Nemerle.Peg средствами языка.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 01.02.11 14:12
Оценка: 8 (1) +1
Здравствуйте, Sinix, Вы писали:

S>1. Критический объём фишек, которые нельзя реализовать силами существующих языков/рантаймов. Сюда же относятся узкопрофильные ЯП, желание попробовать скомбинировать идеи из различных типов ЯП и попытка изобрести принципиально новый ЯП.

Подавляющее колличество таких фишек можно сделать макросами.

S>Нет — поведение скомпилированного кода не будет совпадать с поведением оригинальной программы. Фактически, там транслятор c# в AST немерла. Немерлисты! Если ошибаюсь — поправьте, ок?

Там не компилируются некоторые фичи типа unsafe и иногда перегрузка работает не так как в C#. Но найти отличия в перегрузке может разве что nikov.
Также вывод типов заметно мощьнее. Но это не влияет на поведение.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 14:31
Оценка: :)
Здравствуйте, Chrome, Вы писали:

C>я пытаюсь понять, есть ли причины, которые заставят вас писать собственный компилятор изобретенного вами языка программирования, вместо того, что бы воспользоаватся метапрограммированием немерла, например(когда он позволит компилировать любой пользовательский синтаксис и позволит отключить собственный)

C>учитывая, что озвучены временные затраты порядка 2 месяцев на имплементацию с#
C>если причины есть — назовите их

Угу "вы можете купить автомобиль любого цвета при условии сто это будет черный форд".
Тут же выше уже называли причины рантайм. Другая причина просто язык далекий от мейнстрима.
Третья написание небольшого языка используя например OCaml/Хаскель будет ненамного сложнее
чем чем на макросах Немерле или Лиспа.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 14:33
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Там не компилируются некоторые фичи типа unsafe и иногда перегрузка работает не так как в C#. Но найти отличия в перегрузке может разве что nikov.

WH>Также вывод типов заметно мощьнее. Но это не влияет на поведение.

А хоть какой-то нетривиальный C# проект на нем уже пробовали компилировать?
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 14:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, gandjustas, Вы писали:


G>>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>>Вот изменяемая грамматика этому крайне не способствует.
WH>Необходимость заниматься реверсинжинерингом задумки разработчика этому еще меньше способствует.
WH>
WH>var file = File.Open(...);
WH>try
WH>{
WH>}
WH>finally
WH>{
WH>    if (file != null)
WH>        file.Dispose();
WH>}
WH>

WH>против
WH>
WH>using (file = File.Open(...))
WH>{
WH>}
WH>

WH>И это очень простой пример.
G>>А теперь вопрос: если одни и те же задачи можно решать библиотекой или расширением\изменением\созданием нового языка, то что ты выберешь?
WH>Если кода будет примерно одинакого то библиотеку.
WH>А если синтаксисом код можно ужать хотябы в пару раз то синтаксис.

Вместо оператора using можно сделать функцию using, что гораздо проще. В ленивом языке вообще любую конструкцию можно функцией выразить.


G>>Может все таки стремиться не столько к изменяемым языкам, сколько к возможности выразить максимум средствами языка?

WH>Ну иди попробуй выразить Nemerle.Peg средствами языка.
Какого языка?
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: IT Россия linq2db.com
Дата: 01.02.11 14:59
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>Вот изменяемая грамматика этому крайне не способствует.

Откуда такие сведения? Есть конкретный опыт или это всего-лишь измышлизмы?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: hardcase Пират http://nemerle.org
Дата: 01.02.11 15:09
Оценка: :)
Здравствуйте, gandjustas, Вы писали:

G>Вместо оператора using можно сделать функцию using, что гораздо проще. В ленивом языке вообще любую конструкцию можно функцией выразить.


Вырази конструкцию создания экземпляра анонимного типа ленивой функцией.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 01.02.11 15:13
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>Тут же выше уже называли причины рантайм.

Это хорошая причина.

FR>Другая причина просто язык далекий от мейнстрима.

Это вообще не рпричина.

FR>Третья написание небольшого языка используя например OCaml/Хаскель будет ненамного сложнее чем чем на макросах Немерле или Лиспа.


А IDE ты тоже собрался писать?
А если тебя все устраивает но не хватает какойто фичи будешь весь язык переделывать?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 01.02.11 15:13
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Вместо оператора using можно сделать функцию using, что гораздо проще. В ленивом языке вообще любую конструкцию можно функцией выразить.

ComputationExpressions иди функцией вырази...

WH>>Ну иди попробуй выразить Nemerle.Peg средствами языка.

G>Какого языка?
Любого. Только макросы не используй.
Только давай без халтуры. Чтобы производительность была на уровне.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Способно ли метапрограммирование заменить отдельные язык
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 15:30
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Некоторые товарищи утверждают, что на имплементацию C# на немерле у них ушло 2 месяца.


Не утверждают, а так оно почти и есть.

C>Можно ли за аналогичное време реализовать эрланг? F#?


F# — можно. Эрланг намного сложнее, так как в нем основная фишка это не язык, а рантайм. Сам язык там очень простой и его парсер и интерпретатор пишутся легко и быстро. А вот рантайм — это совсем другое дело. На это нужно не мало времени.

C>Если сроки реально такого порядка — стоит ли ожидать в будущем отдельный диалект языка программирования на каждую программерскую контору или крупный проект?


Не стоит. На самом деле опыт Лиспа и Немерла показал, что в 99% случаев используется базовый язык или стандартные макросы. Хорошие идеи воплощенные в макросах быстро попадают в стандартную библиотеку и становятся практически частью языка.

В прикладных же проектах обычно используются специализированные расширения которые позволяют упростить решение именно этих задач. Это опять же не создает новый язык. Обычно все ограничиваенся созданием DSL-я который позволяет описать задачу близко к ее декларации.

Так что в будущем стоит ожидать введения в обиход большинства программистов механизмов расширения языков и основанную на этом целую парадигму языко-ориентированного (или DSL-ориентированного) программирования. Но вот сколько времени займет процесс перехода к нему не ясно. На сегодня конкурентов немерлу не много. Народ латентен, привычки сильны, а пиар (со стороны монополий вроде MS и IBM) старых подходов только осложняет обстановку. Но, лично у меня, нет сомнений, что за этим подходом будущее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 15:53
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


G>>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>>Вот изменяемая грамматика этому крайне не способствует.

IT>Откуда такие сведения? Есть конкретный опыт или это всего-лишь измышлизмы?


Отлично можно наблюдать при переходе C#2 -> C#3.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 15:56
Оценка:
Здравствуйте, WolfHound, Вы писали:

FR>>Другая причина просто язык далекий от мейнстрима.

WH>Это вообще не рпричина.

Причина, но скажем даже не от мейнстрима а от типичного NET языка.
А если еще и рантайм при этом не подойдет может оказаться проще писать с нуля чем втискивать макросами.

FR>>Третья написание небольшого языка используя например OCaml/Хаскель будет ненамного сложнее чем чем на макросах Немерле или Лиспа.

WH>
WH>А IDE ты тоже собрался писать?

Нет, меня IDE мало волнует

WH>А если тебя все устраивает но не хватает какойто фичи будешь весь язык переделывать?


А вот этот случай как раз самое то для макропрограммирования.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Mamut Швеция http://dmitriid.com
Дата: 01.02.11 16:01
Оценка:
C>>>>>Можно ли за аналогичное време реализовать эрланг? F#?
S>>>>Да, только по поведению это будет всё тот же nemerle.
C>>>что имеется в виду под поведением? в чем отличие от оригинального F#?

M>>На примере Erlang'а. Erlang — это не только синтаксис. Это и легковесные потоки, и асинхронные сообщения, и архитектура shared-nothing и т.д. и т.п. Для того, чтобы реализовать этона Немерле, ндо писать рантайм (грубо говоря) эрланга на Нмерле


C>суть моего оригинального вопроса состояла в следующем

C>- предположим, эрланга в природе еще нет,
C>и его идеи только что родились в моей гениальной голове.
C>Что мне выбрать — написать рантайм, и компилятор, и прикрутить это к какой нибудь среде программирования
C>или взять платформу метапрограммирования вроде немерле, реализовать на ней синтаксис,
C>допилить таки недостающие части рантайма — те самые легковесные потоки и сообщения.
C>(заметьте, мне не нужно писать весь рантайм, 90% уже есть).

C>второй путь кажется более быстрым

C>и не является чем то громоздким — по сложности — как обычная библиотека.

Ну, можно и так. Только на практике все упирается в «насколько это нужно» и «насколько это соответствует требованиям». Как бы допиливание рантайма не вылилось в написание рантайма с нуля


dmitriid.comGitHubLinkedIn
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 16:03
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, gandjustas, Вы писали:


G>>Вместо оператора using можно сделать функцию using, что гораздо проще. В ленивом языке вообще любую конструкцию можно функцией выразить.

WH>ComputationExpressions иди функцией вырази...

Не знаю как у вас, а в F# coputational expressions рассахариваются именно в вызовы функций.

WH>>>Ну иди попробуй выразить Nemerle.Peg средствами языка.

G>>Какого языка?
WH>Любого. Только макросы не используй.
WH>Только давай без халтуры. Чтобы производительность была на уровне.
Ашо это за еврейские замашки сразу на производительность съезжать?
Или ты хочешь сказать что аналогичная производительность доступна только на Nemerle?
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 16:05
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, gandjustas, Вы писали:


G>>Вместо оператора using можно сделать функцию using, что гораздо проще. В ленивом языке вообще любую конструкцию можно функцией выразить.


H>Вырази конструкцию создания экземпляра анонимного типа ленивой функцией.


А что сразу определение функции не спросил?
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 01.02.11 16:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Не знаю как у вас, а в F# coputational expressions рассахариваются именно в вызовы функций.

Ну так ты тот ужос в который оно переписывается видел?
Проблема ведь не в том что бы что-то во что-то переписать, а в том что бы это было красиво.

G>Ашо это за еврейские замашки сразу на производительность съезжать?

G>Или ты хочешь сказать что аналогичная производительность доступна только на Nemerle?
Она доступна только макросам. Ибо там идет очень жестокое переписывание кода для того чтобы это все работало быстро.
Ну и без статической типизации никуда.
И как следствее остается один немерле.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 16:56
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>но тем сложнее и дольше его поддерживать другим людям.


Это заблуждение обычно муссируют те, кто "знаком" с проблемой теоретически. На практике же как раз поддерживать ДСЛ-и куда проще. Обычно ДСЛ-и весьма просты и очень легко осваиваются (намного проще нежели код решающий ту же задачу).

EOH> Соответственно, это не так популярно потому как компании хотят защититься от эффекта падающего кирпича.


Можно описание этого эффекта?

Что до компаний, то они многие из них латентны. Они занимаются престраховкой. Ну, а те что по смелее давно извлекают из этого подхода выгоду.

Пол Грэм описывал историю успеха своих проектов на Лиспе еще 10 лет назад.
В Руби и Питоне МП используется по полной программе. И только "корпоративные разработчики" идут одним дружным стадом боясь взять хоть что-то на чем нет клейма MS, Oracle или IBM.

EOH>Если архитектор DSL покинет компанию или даже заболеет — будут большие проблемы. ОЧЕНЬ большие проблемы.


Чушь полнейшая. Как минимум есть множество примеров ДСЛ-ей широко используемых на практике (BNF, ASP/JSP, Regex). Никаких отличий у доморощенных ДСЛ-ей нет и быть не может.

EOH>

Эти два фактора, как мне кажется, являются двужущей силой для изобретения новых языков программирования и смерти существующих.


Движущей силой для изобретения новых языков программирования является недовольство старыми. А факторы эти не больше чем пугалки придуманные теми кто сами в вопросе не разбирался.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:02
Оценка:
Здравствуйте, FR, Вы писали:

FR>Все это не раз проходили, не прижилось.


Да? А как же на счет Питона, Руби и Лиспа? В них МП — это норма.

FR>Один из первых языков на котором я профессионально начал программировать это Форт, ожидания от него были практически такие же как от

FR>Немерла, еще раньше тоже самое было с Лиспом, и совсем печально с Dylan,
FR>не помогла даже поддержка Apple, притом Dylan по возможностям очень близок к Немерле http://www.opendylan.org/books/drm/Language_Overview.html

Просто всему свое время. Лисп опередил свое время на 50 лет и имел фатальный недостаток — не имел синтаксиса.
Но времена меняются. Задачи становятся все объемнее. Изобретение ООП и ФП отодвинуло востребованность МП на какое-то время. но рано или поздно МП вернется.

Все развивается по спирали. Первые витки сделаны. Люди с головой оценили преимущества МП. Другие тоже оценят... рано или поздно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Sinix  
Дата: 01.02.11 17:09
Оценка:
Здравствуйте, WolfHound, Вы писали:


S>>Нет — поведение скомпилированного кода не будет совпадать с поведением оригинальной программы. Фактически, там транслятор c# в AST немерла. Немерлисты! Если ошибаюсь — поправьте, ок?

WH>Там не компилируются некоторые фичи типа unsafe и иногда перегрузка работает не так как в C#. Но найти отличия в перегрузке может разве что nikov.
WH>Также вывод типов заметно мощьнее. Но это не влияет на поведение.

Не холивара ради. Я ведь правильно помню, что парсер шарпа делался главным образом для обкатки PEG-а, и в целях соблюдение спецификаций шарпа не значилось?

Потому что если озадачиться 100% совместимостью (в том числе и обратной), там работы явно не на 2 человекомесяца. Навскидку:
— dynamic (если будет использоваться родной биндер шарпа — придётся всё-таки полноценно имитировать вывод перегрузок), иначе поведение в рантайме начнёт отличаться от compile-time.
— expression trees.
— куча "фич" аля 0 как допустимое значение enum-а, возможность использования запятой после последнего элемента enum-а/инициализатора, неоднозначность со скобками в object initializer.
— и даже вот такие баги компилятора.

Всё это очень хорошо ест время, а практической пользы — 0.
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:12
Оценка:
Здравствуйте, Chrome, Вы писали:

C>я пытаюсь понять, есть ли причины, которые заставят вас писать собственный компилятор изобретенного вами языка программирования, вместо того, что бы воспользоаватся метапрограммированием немерла, например(когда он позволит компилировать любой пользовательский синтаксис и позволит отключить собственный)


На самом деле до сегодняшнего дня не было ни одного действительно полностью расширяемого (и легко!) ЯП. Даже немерл 1 имеет ряд существенных ограничений. Лисп вообще не мог менять синтаксис. Просто его исходный синтаксис весьма гибок (потому как это просто список). В Nemerle 2.0 мы подойдем к действительно почти не ограниченной расширяемости. Вот тогда твои идеи будут воплощены в жизнь. Создавать языки или модифицировать их будет не просто, а очень просто.

В прочем, Nemerle.Peg + Nemerle 1.0 уже дает делать это. Но пока что это дает только возможность создать полный язык, а не изменить существующий. В Nemerle можно будет так же легко развивать базовый язык (и все его изменения).

C>учитывая, что озвучены временные затраты порядка 2 месяцев на имплементацию с#

C>если причины есть — назовите их

Ну, 2 месяца это не совсем честная цифра. 2 месяца ушло на создание парсера и на прикрутку его к компилятору Nemerle 1. После было потрачено еще какое-то время на то чтобы найти и исправить ошибки. Плюс в результате получился не C#, а язык очень похожий на C#. В нашей реализации нет поддержки unsafe, нинамиков и некоторой другой мелочи. Более того наш C# имеет семантику немерла. Она она очень близка к C#, но все же отличается. Например, в нашем C# доступен вывод типов немела, что позволяет вообще не указать типы внутри кода методов .

Но в целом создание платформы для конструирования и модификации языков более чем возможна. И она будет реализована в Nemerle 2.0. Кто хочет может присоединиться к его разработке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 17:14
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Да? А как же на счет Питона, Руби и Лиспа? В них МП — это норма.


Ну в них (кроме лиспа) как и в Smalltalk или в D легкий вариант
Не мейнстримные есть и более тяжелые, тот же макропроцессор OCaml'а или темплате Хаскель.

VD>Просто всему свое время. Лисп опередил свое время на 50 лет и имел фатальный недостаток — не имел синтаксиса.


Тот же Dylan этого недостатка не имел.

VD>Но времена меняются. Задачи становятся все объемнее. Изобретение ООП и ФП отодвинуло востребованность МП на какое-то время. но рано или поздно МП вернется.


VD>Все развивается по спирали. Первые витки сделаны. Люди с головой оценили преимущества МП. Другие тоже оценят... рано или поздно.


По моему скорее придумают что-то жесткое но более выразительное чем современные языки
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:18
Оценка:
Здравствуйте, FR, Вы писали:

FR>Угу "вы можете купить автомобиль любого цвета при условии сто это будет черный форд".


Точная цитата — "Автомобиль может быть любого цвета при условии, что это черный цвет" (с) Генри Форд.

FR>Тут же выше уже называли причины рантайм. Другая причина просто язык далекий от мейнстрима.


Но тем не менее более чем возможен конструктор позволяющий собирать языки. Потом есть всего 4 больших группы действительно различных языков (ленивые/энергичные * статика/динамика). Так что учесть их особенности в одном фрэймворке можно.

FR>Третья написание небольшого языка используя например OCaml/Хаскель будет ненамного сложнее

FR>чем чем на макросах Немерле или Лиспа.

ОКам имеет ту же основу что и тот же немерл. Лисп — динамика. Проблемы есть только с хаскелем, так как он требует сложной машины вычислителя из-за своей ленивости. Так же проблему может вызвать рантам вроде Эрлангового. Но это как раз скорее исключения. В Эрланговом рантайме основная проблема — это дешевые "зеленые" потоки. В принципе тоже реализуемо (но несколько сложновато в рамках дотнета или явы, что потребует нэйтив-реализации).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

FR>>Третья написание небольшого языка используя например OCaml/Хаскель будет ненамного сложнее чем чем на макросах Немерле или Лиспа.

WH>
WH>А IDE ты тоже собрался писать?
WH>А если тебя все устраивает но не хватает какойто фичи будешь весь язык переделывать?

Они (ОКамлисты) таким дерьмом пользуются, что для них IDE скорее всего не аргумент .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:21
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>Причина, но скажем даже не от мейнстрима а от типичного NET языка.

FR>А если еще и рантайм при этом не подойдет может оказаться проще писать с нуля чем втискивать макросами.

Я бы сказал так. Проблема есть, но она решаемая. Да и проблема в основном в том, то рантайм дотнета только декларирован как многоязычный, а на самом деле был заточен под одни язык — Яву (с событиями ).

WH>>А IDE ты тоже собрался писать?


FR>Нет, меня IDE мало волнует


Что я говорил?

WH>>А если тебя все устраивает но не хватает какойто фичи будешь весь язык переделывать?


FR>А вот этот случай как раз самое то для макропрограммирования.


+1

Но идея фрэймворка для создания языков тоже в принципе интересна, согласись.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:22
Оценка:
Здравствуйте, Mystic, Вы писали:

M>А много ли таких фичей? Лично я метапрограммирование больше применял для описания некоторых данных, которые потом переводились в разные таблицы.


Какие проблемы, такие и решения. Но есть и общие для разных предметных областей фишки. Скажем автоматизация паттернов ООП.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 17:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Но тем не менее более чем возможен конструктор позволяющий собирать языки. Потом есть всего 4 больших группы действительно различных языков (ленивые/энергичные * статика/динамика). Так что учесть их особенности в одном фрэймворке можно.


Ну есть еще term rewriting, если элементарный пролог совсем не сложно, то его же эффективно работающий или например тот же Pure очень сложно и на этом фоне разбор синтаксиса и т. п. исчезающе малая величина.
Я не спорю конструктор возможен, но скорее всего он будет конструктором языков близких к C# и Немерле.

FR>>Третья написание небольшого языка используя например OCaml/Хаскель будет ненамного сложнее

FR>>чем чем на макросах Немерле или Лиспа.

VD>ОКам имеет ту же основу что и тот же немерл. Лисп — динамика. Проблемы есть только с хаскелем, так как он требует сложной машины вычислителя из-за своей ленивости. Так же проблему может вызвать рантам вроде Эрлангового. Но это как раз скорее исключения. В Эрланговом рантайме основная проблема — это дешевые "зеленые" потоки. В принципе тоже реализуемо (но несколько сложновато в рамках дотнета или явы, что потребует нэйтив-реализации).


В принципе все реализуемо даже на языке шаблонов C++
Но я же не про это, а про то что трудозатраты на написание небольшого язычка или внешнего DSL используя ФЯ типа Хаскель/OCaml (или если больше нравится и Немерле) будет сопоставима с написанием его же как макрорасширения для Немерле.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.02.11 17:33
Оценка:
Здравствуйте, FR, Вы писали:

FR>Даже те же питон и руби в конце концов потребовали изменения рантайма NET.


Можно поподробнее, что в CLR поменяли для руби и питона?
... << RSDN@Home 1.2.0 alpha 4 rev. 1490 on Windows 7 6.1.7600.0>>
AVK Blog
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 17:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Они (ОКамлисты) таким дерьмом пользуются, что для них IDE скорее всего не аргумент .


Ничего и не дерьмо, лучше чем C++ Builder
Правда я IDE для OCaml'а на самом деле не использую, надобности нет, но блин подсел на тот же Eclipse(PyDev) с питоном.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 17:43
Оценка:
Здравствуйте, AndrewVK, Вы писали:

FR>>Даже те же питон и руби в конце концов потребовали изменения рантайма NET.


AVK>Можно поподробнее, что в CLR поменяли для руби и питона?


Не поменяли а добавили Dynamic Language Runtime, возможно и не специально для этих языков, но трудности
их реализации тоже сыграли свою роль, вот например http://msdn.microsoft.com/en-us/magazine/cc163344.aspx
один из разработчиков IronPython весьма хвалит. Насколько помню в IronPython 1.0 были большие проблемы с вызовом
питоньих функций из внешнего NET кода.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:46
Оценка:
Здравствуйте, FR, Вы писали:

VD>>Да? А как же на счет Питона, Руби и Лиспа? В них МП — это норма.

FR>Ну в них (кроме лиспа) как и в Smalltalk или в D легкий вариант

Легкий? Этого легкого варианта хватило на Рельсы и еще осталось! Он не легкий, он тормозной. А это не одно и тоже .

FR>Не мейнстримные есть и более тяжелые, тот же макропроцессор OCaml'а или темплате Хаскель.


Ну, камловский препроцессор штука весьма огнаниченная. Плюс и ОКамл и Хаскель распространены чуть больше чем немерле, то есть чуть больше чем никак. А их расширения еще меньше. Может по этому и не востребованы?

VD>>Просто всему свое время. Лисп опередил свое время на 50 лет и имел фатальный недостаток — не имел синтаксиса.


FR>Тот же Dylan этого недостатка не имел.


Я не знаком с Dylan. Думаю, что у него своих тараканов хватало. Это интерпретатор?

FR>По моему скорее придумают что-то жесткое но более выразительное чем современные языки


Например? Мат?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: Lloyd Россия  
Дата: 01.02.11 17:49
Оценка:
Здравствуйте, FR, Вы писали:

AVK>>Можно поподробнее, что в CLR поменяли для руби и питона?


FR>Не поменяли а добавили Dynamic Language Runtime,


Это просто библиотека. Вас смутило слово Runtime?
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:55
Оценка:
Здравствуйте, FR, Вы писали:

FR>Ну есть еще term rewriting,


Это как раз плевая задача. Видимо ты все же имеешь в виду что-то другое.

FR>если элементарный пролог совсем не сложно, то его же эффективно работающий или например тот же Pure очень сложно и на этом фоне разбор синтаксиса и т. п. исчезающе малая величина.


А причем тут Пролог? В прологе основная сложность — это унификация и рекурсивный поиск с бэктрекингом. Этот механизм так же можно предоставить в виде библиотеки. И только от ее авторов будет зависеть качество ее реализации.

FR>Я не спорю конструктор возможен, но скорее всего он будет конструктором языков близких к C# и Немерле.


Я как раз прикидывал. В принципе можно сделать и очень универсальное решение. Потуги уже в общем-то были даже. Тут кто-то на лиспе подобное дело делал.

Ну, да даже фрэймворк позволяющий создавать и развивать статически-типизированные гибридные языки с энергичной семантикой дал бы уже не малый просто для фантазии. Ведь в этот класс языков входят не только C# и Немерле, а еще F#, OKaml, Дельфи, Васик и многие другие. Это по сути все языки дотнета. Почему не пойти дальше и не сделать не толко бэкэнд (дотнет) общими, но и мидл-энд, и фронт-энд?

FR>В принципе все реализуемо даже на языке шаблонов C++


Не. Слишком сложно.

FR>Но я же не про это, а про то что трудозатраты на написание небольшого язычка или внешнего DSL используя ФЯ типа Хаскель/OCaml (или если больше нравится и Немерле) будет сопоставима с написанием его же как макрорасширения для Немерле.


Ты просто не писал настоящих компиляторов. Затраты на разработку языка очень высоки! Чем качественнее хочется получить результат, тем сложнее задача.

Языки с паттерн-матчингом и ФВП немного упрощают задачу, но не существенно.

А сложных уж и подавно. Попробуй ради хохмы создать компилятор C#-а хотя бы за в десять раз большее время, а я посмеюсь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 17:57
Оценка:
Здравствуйте, FR, Вы писали:

FR>Ничего и не дерьмо, лучше чем C++ Builder


C++ Builder, конечно, тоже дерьмо еще то. Но уж позволь не поверить.

FR>Правда я IDE для OCaml'а на самом деле не использую, надобности нет,


Потому и не используешь, что качество такое у нее.

FR>но блин подсел на тот же Eclipse(PyDev) с питоном.


Что подтверждает мои слова.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: hardcase Пират http://nemerle.org
Дата: 01.02.11 17:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, hardcase, Вы писали:


H>>Здравствуйте, gandjustas, Вы писали:


G>>>Вместо оператора using можно сделать функцию using, что гораздо проще. В ленивом языке вообще любую конструкцию можно функцией выразить.


H>>Вырази конструкцию создания экземпляра анонимного типа ленивой функцией.


G>А что сразу определение функции не спросил?


Если функцию для using или lock я понимаю, то ответ на вопрос про определение типов в функциях в условиях статической типизации для меня не очевиден. Пример в студию!
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 01.02.11 17:59
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Mystic, Вы писали:


M>>А много ли таких фичей? Лично я метапрограммирование больше применял для описания некоторых данных, которые потом переводились в разные таблицы.


VD>Какие проблемы, такие и решения. Но есть и общие для разных предметных областей фишки. Скажем автоматизация паттернов ООП.


Смотря каких паттернов. В общем случае, мне кажется, игра не стоит свеч: на изучение более абстрактной настройки понадобится время, а используется раз в год, два раза на пасху.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 17:59
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>Ну в них (кроме лиспа) как и в Smalltalk или в D легкий вариант


VD>Легкий? Этого легкого варианта хватило на Рельсы и еще осталось! Он не легкий, он тормозной. А это не одно и тоже .


По сравнению с полноценными макросами конечно легкий.
Ну и для меня его такого и хватает вполне.

VD>Ну, камловский препроцессор штука весьма огнаниченная. Плюс и ОКамл и Хаскель распространены чуть больше чем немерле, то есть чуть больше чем никак. А их расширения еще меньше. Может по этому и не востребованы?


Ну все-таки распространены они все-таки намного шире, да и поверхностное знакомство с ними есть у гораздо большего числа программистов из-за ВУЗов.
Но я имел в виду что в мейнстрим так и не прошли даже такие.


FR>>Тот же Dylan этого недостатка не имел.


VD>Я не знаком с Dylan. Думаю, что у него своих тараканов хватало. Это интерпретатор?


По сути Common Lisp с паскалевым синтаксисом, компилятор, язык динамический с опциональной поддержкой типизации:

define function absolute-value(x :: <integer>)
 => (result :: <integer>)
  if (x >= 0)
    x;
  else
    -x;
  end;
end;


Там вообще много чего наворочено вплоть до минимальной поддержки зависимых типов http://www.opendylan.org/fragments/limited-types.phtml


FR>>По моему скорее придумают что-то жесткое но более выразительное чем современные языки


VD>Например? Мат?


Re[6]: Способно ли метапрограммирование заменить отдельные я
От: hardcase Пират http://nemerle.org
Дата: 01.02.11 18:02
Оценка: +2
Здравствуйте, Sinix, Вы писали:

S>Потому что если озадачиться 100% совместимостью (в том числе и обратной), там работы явно не на 2 человекомесяца. Навскидку:


Это верно

S>- dynamic (если будет использоваться родной биндер шарпа — придётся всё-таки полноценно имитировать вывод перегрузок), иначе поведение в рантайме начнёт отличаться от compile-time.


Сделать можно, даже аналог в языке есть (ага, макрос), но пока не нужно.

S>- expression trees.


Они есть, догадайся на чем реализованы

S>возможность использования запятой после последнего элемента enum-а/инициализатора, неоднозначность со скобками в object initializer.


Это фичи парсера, так что мимо.

S>- и даже вот такие баги компилятора.


Такая хреновина действительно бесполезна. Какому бишь проценту пользователей она нужна?
/* иЗвиНите зА неРовнЫй поЧерК */
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 18:07
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>C++ Builder, конечно, тоже дерьмо еще то. Но уж позволь не поверить.


Это ты просто с билдером не работал

FR>>Правда я IDE для OCaml'а на самом деле не использую, надобности нет,


VD>Потому и не используешь, что качество такое у нее.


Нет не из-за этого, просто и проекты маленькие и сам язык железобетонный, отладки не требует

FR>>но блин подсел на тот же Eclipse(PyDev) с питоном.


VD>Что подтверждает мои слова.


Даже если бы OCaIDE был бы по возможностям близок к PyDev больших преимуществ это не принесло бы.
Re: Способно ли метапрограммирование заменить отдельные язык
От: jazzer Россия Skype: enerjazzer
Дата: 01.02.11 18:07
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.


Почему ты все метапрограммирование сводишь к подключаемой грамматике? Это более широкое понятие, охватывающее гораздо больший спектр техник, чем одни только подключаемые грамматики. Те же шаблоны в С++, перегрузка операторов в куче языков, текстовые макросы в Си — это все не подключаемые грамматики, но это вполне себе метапрограммирование.

Метапрограммирование — это, фактически, кодогенерация, в том или ином виде. В случае сишных макросов это прямая текстовая кодогенерация, в более продвинутых случаях — кодогенерация прямо в представлении компилятора, но все равно это она и есть.

Насчет заменить отдельные языки — смотря какие языки ты имеешь в виду. Если языки, которые используются для внешней кодогенерации — то да, способно, до определенного предела. Но, опять же, оно заменить эти языки только в этой крайне узкой нише. Если универсальные языки, особенно нативные — так они обычно подразумевают бэкэнд, обычно несовместимый. Т.е. распарсить-то ты может и распарсишь сишный код на немерле, только вот что это тебе даст, когда нет указателей и прочего...
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 18:22
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>Ну есть еще term rewriting,


VD>Это как раз плевая задача. Видимо ты все же имеешь в виду что-то другое.


Так я же ниже прямо написал (выделил), элементарный очень легко чуть сложнее все, тем более Pure гораздо сложнее пролога.

FR>>если элементарный пролог совсем не сложно, то его же эффективно работающий или например тот же Pure очень сложно и на этом фоне разбор синтаксиса и т. п. исчезающе малая величина.


VD>А причем тут Пролог? В прологе основная сложность — это унификация и рекурсивный поиск с бэктрекингом. Этот механизм так же можно предоставить в виде библиотеки. И только от ее авторов будет зависеть качество ее реализации.


Вот качественная и потребует столько трудозатрат что хоть ты ее макросом оформи хоть как отдельный язык с написанным на си парсером на этом фоне одинаково

VD>Я как раз прикидывал. В принципе можно сделать и очень универсальное решение. Потуги уже в общем-то были даже. Тут кто-то на лиспе подобное дело делал.


VD>Ну, да даже фрэймворк позволяющий создавать и развивать статически-типизированные гибридные языки с энергичной семантикой дал бы уже не малый просто для фантазии. Ведь в этот класс языков входят не только C# и Немерле, а еще F#, OKaml, Дельфи, Васик и многие другие. Это по сути все языки дотнета. Почему не пойти дальше и не сделать не толко бэкэнд (дотнет) общими, но и мидл-энд, и фронт-энд?


Вот и все, а появится завтра суперрефал?
Эх вспоминаю как писал надцать лет назад еще студентом на Форте универсальный баскенд для всех языков, даже успел минимальный паскаль реализовать до того как забросил

FR>>В принципе все реализуемо даже на языке шаблонов C++


VD>Не. Слишком сложно.


Ну я же в шутку.

VD>Ты просто не писал настоящих компиляторов. Затраты на разработку языка очень высоки! Чем качественнее хочется получить результат, тем сложнее задача.


VD>Языки с паттерн-матчингом и ФВП немного упрощают задачу, но не существенно.


Ну тот же dmz показал что не очень и высоки для простого языка. Тем более если back end LLVM или NEТ.

VD>А сложных уж и подавно. Попробуй ради хохмы создать компилятор C#-а хотя бы за в десять раз большее время, а я посмеюсь.


Ну это не спортивно, напиши на немерле компилятор C++
Ну и я речь веду про простые языки, так как сложные на макросах тоже запросто не реализуешь.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 18:28
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А что мешает сделать вызовы лаконичными без изменения синтаксиса?


С C#-ом или ВБ знаком? Покажи как сделать объявление и использование зависимых свойств из WPF "лаконичными без изменения синтаксиса".

Вот как это делается на Nemerle:
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.WPF/Test/Main.n
using Nemerle.Collections;
using Nemerle.Utility;
using Nemerle.Text;
using Nemerle.WPF;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Controls;

using System.Windows;
using System.Console;

public class MyStateControl : Button
{
  public this() { base() }

  [DependencyProperty(Metadata = FrameworkPropertyMetadata("a", (_, _) => { }, (_, b) => b))]
  public DependencyProperty1 : string { get { } set { } }

  [DependencyProperty(IsReadOnly)]
  internal DependencyProperty2 : string { get { } set { } }

  [DependencyProperty(IsReadOnly, ValidateCallback = value => value > 0, Metadata = PropertyMetadata((_, _) => { }))]
  public static GetDependencyProperty3(_ : DependencyObject) : int;

  [DependencyProperty]
  public static GetDependencyProperty4(item : DependencyObject) : int;
}

module Program
{
  [STAThread]
  Main() : void
  {
    try
    {
      def control = MyStateControl();
      control.DependencyProperty1 = control.DependencyProperty1 + control.DependencyProperty2;
      def x = MyStateControl.GetDependencyProperty3(control);
      def y = MyStateControl.GetDependencyProperty4(control);
      MyStateControl.SetDependencyProperty4(control, x + y);
    }
    catch
    {
      | e => WriteLine(e.ToString());
    }
  }
}

А вот реализация:
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.WPF/Nemerle.WPF/DependencyProperty.n
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 18:28
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, gandjustas, Вы писали:


G>>Не знаю как у вас, а в F# coputational expressions рассахариваются именно в вызовы функций.

WH>Ну так ты тот ужос в который оно переписывается видел?
WH>Проблема ведь не в том что бы что-то во что-то переписать, а в том что бы это было красиво.
Это уже ты придумал про "красиво".

G>>Ашо это за еврейские замашки сразу на производительность съезжать?

G>>Или ты хочешь сказать что аналогичная производительность доступна только на Nemerle?
WH>Она доступна только макросам. Ибо там идет очень жестокое переписывание кода для того чтобы это все работало быстро.
WH>Ну и без статической типизации никуда.
WH>И как следствее остается один немерле.
А кто мешает в рантайме переписывать?

Чето у немерелистов уже настолько взгляд затуманен, что они вообзе плохо видят возможности за пределми того что есть в nemerle.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 01.02.11 18:35
Оценка: 2 (1)
Здравствуйте, VladD2, Вы писали:

VD>Ты просто не писал настоящих компиляторов. Затраты на разработку языка очень высоки! Чем качественнее хочется получить результат, тем сложнее задача.


VD>Языки с паттерн-матчингом и ФВП немного упрощают задачу, но не существенно.


Те кто писали говорят, например тот же Дмитрий, что очень существенно (http://fprog.ru/2009/issue2/dmitry-zuikov-one-compiler-story/):

Можно привести такой пример: существуют довольно интересные языки программирования Haxe и Boo. Они во многом похожи, например, строгой статической типизацией и выводом типов. Первый язык реализован преимущественно на OCaml, второй — на C#.

Реализация системы типов в Boo, написанном на C#, занимает более семнадцати тысяч строк кода (более половины мегабайта кода на высокоуровневом языке), размещающихся в ста двадцати двух файлах. При этом представлявший наибольший интерес алгоритм вывода типов надежно декомпозирован на слои и «шаблоны проектирования» и код, который его реализует является вполне идиоматичным для этого класса языков. Задача идентифицировать основной код алгоритма и понять его не выглядела решаемой за разумное время и была оставлена.

Ни одной понятной реализации системы типов и алгоритма выведения на императивных языках найдено не было (были рассмотрены варианты на C#, С++ и даже Perl).

Реализация системы типов в языке Haxe, занимает 4088 строк (127624 байт кода) на OCaml и размещается в трех файлах, при этом интересующий алгоритм идентифицируется сразу же и представляет собой, в основном, свертку списков с применением сопоставления с образцом. Прочитать и понять его было достаточно легко, несмотря на то, что на тот момент опыт разработки и чтения кода, написанного на императивных языках, сильно превосходил аналогичный опыт для функциональных.

Даже со всеми возможными оговорками разница в функциональности систем типов Boo и Haxe гораздо меньше, чем разница в количестве кода, эту функциональность реализующего: 100072 строки (2955595 байт) кода текущей реализации Boo убивали всякую надежду, что подобный проект может вообще быть реализован самостоятельно.

Для сравнения, текущие значения для Бипа: 2592 строки (109780 байт) кода, а время, затраченное на реализацию вместе с рантаймом, не превышает трех человеко-месяцев. Это маленький проект, и сделать его маленьким помог именно выбор OCaml в качестве языка разработки.

Re[3]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 18:39
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Необходимость заниматься реверсинжинерингом задумки разработчика этому еще меньше способствует.

WH>
WH>var file = File.Open(...);
WH>try
WH>{
WH>}
WH>finally
WH>{
WH>    if (file != null)
WH>        file.Dispose();
WH>}
WH>

WH>против
WH>
WH>using (file = File.Open(...))
WH>{
WH>}
WH>

WH>И это очень простой пример.

Вот, кстати, недавний пример.
ReadWriteHashtable.n до применения макроса и после ReadWriteHashtable.n.
Пусть тот кто читает, что код:
          locker.EnterWriteLock();
          try
          {
            foreach(kv in range)
              hashtable.Add(kv.Key, kv.Value);
          }
          finally
          {
            locker.ExitWriteLock();
          }

более понятен нежели:
          surroundwith (write_lock)
            foreach(kv in range)
              hashtable.Add(kv.Key, kv.Value);

первым кинет в меня камень!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 18:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

H>>Вырази конструкцию создания экземпляра анонимного типа ленивой функцией.


G>А что сразу определение функции не спросил?


Ны ты крут! Я еще не видел, чтобы люди сами намеренно участвовали в дискредитации своих же утверждений.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 18:44
Оценка: -1
Здравствуйте, gandjustas, Вы писали:

G>Не знаю как у вас, а в F# coputational expressions рассахариваются именно в вызовы функций.


Ну, дык за чем дело стало? Напиши аналог на C#. Ты же крут!

WH>>>>Ну иди попробуй выразить Nemerle.Peg средствами языка.

G>>>Какого языка?
WH>>Любого. Только макросы не используй.
WH>>Только давай без халтуры. Чтобы производительность была на уровне.
G>Ашо это за еврейские замашки сразу на производительность съезжать?

Что опять слил?

G>Или ты хочешь сказать что аналогичная производительность доступна только на Nemerle?


Он хотел сказать, что на макросах можно реализовать как хочешь, в том числе и очень эффективно. А вот когда у тебя нет таких средств, то делают как получится. И обычно получается некрасиво и медленно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 18:46
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Вот только ты не учел что язык — не только способ передачи информации от программиста компьютеру, но и способ передачи информации между программистами.

G>>>Вот изменяемая грамматика этому крайне не способствует.

IT>>Откуда такие сведения? Есть конкретный опыт или это всего-лишь измышлизмы?


G>Отлично можно наблюдать при переходе C#2 -> C#3.


А в котором из них изменяемая грамматика?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: hardcase Пират http://nemerle.org
Дата: 01.02.11 18:49
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А что сразу определение функции не спросил?


Покажи мне построение Expression Tree на ленивых функциях.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 01.02.11 19:08
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Это уже ты придумал про "красиво".

Ну так мы тут не про полноту по Тьюрингу говорим.

G>А кто мешает в рантайме переписывать?

И машинный код сгенерировать,... и получишь ты макросы немерла вид в профиль.

G>Чето у немерелистов уже настолько взгляд затуманен, что они вообзе плохо видят возможности за пределми того что есть в nemerle.

Я вижу все лучше чем ты.
Я прекрасно знаю что можно сделать и что нельзя.
Но в отличии от тебя я прекрасно понимаю что как ни крутись, а для того чтобы получить аналогичное по краткости и производительности решения понадобится механизм похожий на макросы немерла.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:09
Оценка:
Здравствуйте, FR, Вы писали:

FR>Это ты просто с билдером не работал


Довелось на его заре. Функционально на тот момент он был ничего. Но глючил страшно. В прочем, все IDE для С++ тогда работали кое-как. В итоге, правда, перешли на VS 6. Там интелисенса почти не было, но редакторо хороший, компилятор приличный... посталиви Томату и забыли про билдер.

VD>>Потому и не используешь, что качество такое у нее.


FR>Нет не из-за этого, просто и проекты маленькие и сам язык железобетонный, отладки не требует


Первое — возможно. Второе — сказки. В IDE отладка не главное. В ней главное возможность контролировать код (типы, ошибки). Для явзыка с выводом типов это очень важно.

FR>Даже если бы OCaIDE был бы по возможностям близок к PyDev больших преимуществ это не принесло бы.


Какая разница как называется IDE? Главное, что она ускоряет работу.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:13
Оценка:
Здравствуйте, FR, Вы писали:

FR>По сравнению с полноценными макросами конечно легкий.


Полноценные макросы могут быть очень легкими в применении.

FR>Ну и для меня его такого и хватает вполне.


Тем более!

VD>>Ну, камловский препроцессор штука весьма огнаниченная. Плюс и ОКамл и Хаскель распространены чуть больше чем немерле, то есть чуть больше чем никак. А их расширения еще меньше. Может по этому и не востребованы?


FR>Ну все-таки распространены они все-таки намного шире, да и поверхностное знакомство с ними есть у гораздо большего числа программистов из-за ВУЗов.


Программисты из ВУЗ-ов звучит очень смешно. Не находишь?

FR>Но я имел в виду что в мейнстрим так и не прошли даже такие.


Дык, а как они пройдут то когда сами базовые языки (без мета-расширений) в мэйстрим попасть не могут.

FR>По сути Common Lisp с паскалевым синтаксисом, компилятор, язык динамический с опциональной поддержкой типизации:


Ну, а что ты хочешь? Динамика да еще и лиспоподобная. Хотя выглдяит все же по проще чем Лисп.

FR>Там вообще много чего наворочено вплоть до минимальной поддержки зависимых типов http://www.opendylan.org/fragments/limited-types.phtml


Интересно...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:15
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Смотря каких паттернов. В общем случае, мне кажется, игра не стоит свеч: на изучение более абстрактной настройки понадобится время, а используется раз в год, два раза на пасху.


Ключевое слово здесь — "кажется".

Паттерны заполоняют код обычных ОО-проектов. Инкапсуляция их в языковые конструкции позволяет сделать код во много раз чище и проще. Одно это упрощает разработку сложных проектов. А мы еще и не заикались о ДСЛ-ях...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:31
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Почему ты все метапрограммирование сводишь к подключаемой грамматике? Это более широкое понятие, охватывающее гораздо больший спектр техник, чем одни только подключаемые грамматики. Те же шаблоны в С++, перегрузка операторов в куче языков, текстовые макросы в Си — это все не подключаемые грамматики, но это вполне себе метапрограммирование.


J>Метапрограммирование — это, фактически, кодогенерация, в том или ином виде. В случае сишных макросов это прямая текстовая кодогенерация, в более продвинутых случаях — кодогенерация прямо в представлении компилятора, но все равно это она и есть.


+1

J>Насчет заменить отдельные языки — смотря какие языки ты имеешь в виду. Если языки, которые используются для внешней кодогенерации — то да, способно, до определенного предела. Но, опять же, оно заменить эти языки только в этой крайне узкой нише.


Это очень узкий взгляд на проблему. На самом деле при наличии качественного и прсотого в использовании МП, да еще и с легко изменяемым синтаксисом становится доступна новая парадигма — языко-ориентированное программирование. Когда прикладаная задача описывается на ДСЛ-е, а макросы (или что-то их заменяющее) обеспечивают реализацию этого ДСЛ-я (создание компилятора или интерпретатора).

J>Если универсальные языки, особенно нативные — так они обычно подразумевают бэкэнд, обычно несовместимый. Т.е. распарсить-то ты может и распарсишь сишный код на немерле, только вот что это тебе даст, когда нет указателей и прочего...


Дык если говорить о эдаком языковом фрэймворке, то под копотом у него могут быть и указатели и все что угодно. Скажем в Н1 (немерле 1.0) нет операторов goto. Но тем не менее при реализации C#-а поверх немерла мы таки реализовали этот самый goto. И в Nemerle.Peg goto для оптимизации (в релизе) используется. Это возможно потому, что goto как примитив присутствует в типизированном АСТ. И макросы могут его использовать. Точно так же может быть с указателями. Так что воспроизвести С++ на немерле очень даже можно. Вопрос только в объеме работы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.02.11 19:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, gandjustas, Вы писали:


G>>А что мешает сделать вызовы лаконичными без изменения синтаксиса?


VD>С C#-ом или ВБ знаком? Покажи как сделать объявление и использование зависимых свойств из WPF "лаконичными без изменения синтаксиса".


Я не про C# говорю.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:39
Оценка:
Здравствуйте, Mamut, Вы писали:

M>На примере Erlang'а. Erlang — это не только синтаксис. Это и легковесные потоки


Вот их реализация средствами дотнета будет не простым занятием. Точнее простым, но не факт, что получится так же эффективно.

M>, и асинхронные сообщения,


Это ни разу не проблема.

M>и архитектура shared-nothing и т.д.


Тоже самое. Запрещаем статические переменные и получаем shared-nothing. Хотя это как раз уже сказка, так как процессы эрланга таки могут содержать глобальные данные. А сам процесс эрланга удивительно похож на классы в ООП (так как инкапсулирует логику).

M> и т.п.


Нет никаких "и т.п.". Не выдумывай. Есть только те самые зеленые потоки.

M> Для того, чтобы реализовать этона Немерле, ндо писать рантайм (грубо говоря) эрланга на Нмерле


Рантайм ограничивается теми самыми потоками. Остальное выражается имеющимися средствами.

Другой вопрос — зачем вообще воспроизводить Эрланг на Немерле? Ведь можно воспроизвести только главное — зеленые потоки и изолированные "ссылочные пространства" общение между которыми ведется по средствам сообщений. При этом оставить язык типизированным. Мне видится — это куда более логичным и востребованным. Главные фичи эрланга в статически-типизированном виде и со скоростью близкой к С — это и правда очень приятная фишка.

Еще интересным расширением была бы — реализация логического (аля Пролог) ядра. Это тоже очень даже возможно, но требует не мало усилий.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:41
Оценка:
Здравствуйте, Chrome, Вы писали:

C>он будет работать. но потеряет свойства realtime


А их, кстати, никогда и не было. "Софт реалтайм" — это как почти беременная.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.02.11 19:55
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Mamut, Вы писали:


M>>и архитектура shared-nothing и т.д.


VD>Тоже самое. Запрещаем статические переменные и получаем shared-nothing. Хотя это как раз уже сказка, так как процессы эрланга таки могут содержать глобальные данные. А сам процесс эрланга удивительно похож на классы в ООП (так как инкапсулирует логику).


Расскажи, что за глобальные данные?
Re[11]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 19:58
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Это просто библиотека. Вас смутило слово Runtime?


Дык при наличии вот таких "просто библиотек" реализация подобных языков становится тривиальным. А без оных очень не простой.

Я тебе больше скажу. Главная проблема макросов заключается в том, что их реализация не тривиальна. Причем проблемы не в сложности реализации самих макросов, а в сложности прикладной. Это ведь тоже код! И код, не простой. Наличие библиотек или даже понимания того как задачу нужно решать уже дает огромное преимущество.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.02.11 20:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Другой вопрос — зачем вообще воспроизводить Эрланг на Немерле? Ведь можно воспроизвести только главное — зеленые потоки и изолированные "ссылочные пространства" общение между которыми ведется по средствам сообщений. При этом оставить язык типизированным. Мне видится — это куда более логичным и востребованным. Главные фичи эрланга в статически-типизированном виде и со скоростью близкой к С — это и правда очень приятная фишка.


Сорри, выше ответил, не дочитав, по поводу фич эрланга и статической типизации — для JVM (Java/Scala) есть по идее akka, если вдруг кому-то интересна тема.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: Lloyd Россия  
Дата: 01.02.11 20:14
Оценка: +1
Здравствуйте, VladD2, Вы писали:

L>>Это просто библиотека. Вас смутило слово Runtime?


VD>Дык при наличии вот таких "просто библиотек" реализация подобных языков становится тривиальным. А без оных очень не простой.


Но это ни в коем случае не означает, что в CLR было что-то поменяно.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 20:54
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Нет — поведение скомпилированного кода не будет совпадать с поведением оригинальной программы. Фактически, там транслятор c# в AST немерла. Немерлисты! Если ошибаюсь — поправьте, ок?


Ты не ошибаешься, но таки в 99% случаев семантика шарпа выдержана. Компилируется почти весь код который мы пробовали.

Потом поведение скомпилированного то кода как раз почти всегда совпадает. Вот поведение компилятора может отличаться. Например, могут быть ворнинги которых не было в шарпе, например.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.02.11 20:54
Оценка:
Здравствуйте, FR, Вы писали:

FR>Не поменяли а добавили Dynamic Language Runtime


Это просто библиотека. Точнее даже стандарт для интероперабельности разных динамических языков. Никакого отношения к CLR он не имеет.
С натяжкой можно отнести к изменениям рантайма связанные с DLR доработки маршаллера. Но эти доработки, в свою очередь, не имеют никакого отношения к питону или руби.
... << RSDN@Home 1.2.0 alpha 4 rev. 1490 on Windows 7 6.1.7600.0>>
AVK Blog
Re[12]: Способно ли метапрограммирование заменить отдельные
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 01.02.11 20:54
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Дык при наличии вот таких "просто библиотек" реализация подобных языков становится тривиальным. А без оных очень не простой.


Сам по себе DLR ничего особо не упрошает, он лишь обеспечивает интероперабельность динамики. Вот стандартные биндеры, те могут кое что упростить. Но это все не имеет никакого отношения к возможности CLR хостить разные языки.
... << RSDN@Home 1.2.0 alpha 4 rev. 1490 on Windows 7 6.1.7600.0>>
AVK Blog
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 21:00
Оценка:
Здравствуйте, Chrome, Вы писали:

C>ну приведите пример программы на с#, когда поведение будет отличаться.

C>даже если такой пример найдется, останется только занести его в баг лист и зафиксить.

Будут различаться:
1. Разрешение перегрузок. Многие Никовские этюды на Немерле будут вести себя так как предполагает человек, а не каким-то странным образом описанном в стандарте шарпа.
2. Несколько иначе ведет себя переопределение виртуальных методов.
3. Кое где появятся ворнинги которых не должно быть с точки зрения шапра.
4. Кое где компилятор будет дозволять вольности (вывод типов сильно круче).

Но в целом все это проявляется только в пограничных случаях. На реальном C#-коде все работает не плохо.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Предлагаю обсудить в таком ключе
От: Wolverrum Ниоткуда  
Дата: 01.02.11 21:07
Оценка:
Здравствуйте, Chrome, Вы писали:

Давайте условимся,
что из нижеперечисленных продуктов:
— Lisp
— JetBrains MPS
— Template Haskell
— Nemerle
(добавь свой вариант)

"вздетело" — "не взлетело" на текущий момент,
и на основании полученного соглашения продолжим обсуждать тему?
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 21:26
Оценка: 2 (1)
Здравствуйте, FR, Вы писали:

FR>Те кто писали говорят, например тот же Дмитрий, что очень существенно (http://fprog.ru/2009/issue2/dmitry-zuikov-one-compiler-story/):


Я это читал. Там сравнивается только вывод типов.
Но я еще и писал сам. Это дает возможность говорить о проблеме более компетентно. Так вот уверяю тебя, что использование макро-системы (в купе с ПМ и ФВП) дает значительно (в разы) бльший выигряшь. Компилятор немерла меньше Бушного во много раз. А ты ведь знаешь насколько больше он делает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 21:35
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>А что мешает сделать вызовы лаконичными без изменения синтаксиса?


VD>>С C#-ом или ВБ знаком? Покажи как сделать объявление и использование зависимых свойств из WPF "лаконичными без изменения синтаксиса".


G>Я не про C# говорю.


А ты не уходи от ответа. Ответь на вопрос и получишь ответ на свой вопрос.

ЗЫ

Ответ то очевиден. Язык не позволяет. Но ты честно на этот вопрос никогда не ответишь. Потому и от вопроса уходишь.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 21:36
Оценка:
Здравствуйте, Курилка, Вы писали:

VD>>Тоже самое. Запрещаем статические переменные и получаем shared-nothing. Хотя это как раз уже сказка, так как процессы эрланга таки могут содержать глобальные данные. А сам процесс эрланга удивительно похож на классы в ООП (так как инкапсулирует логику).


К>Расскажи, что за глобальные данные?


У процессов есть свои словари. Данные в них помещаются и удерживаеются точно так же как в статических переменных. Таким образом в Эрнанке процессы могут капсулировать состояние.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 21:38
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Но это ни в коем случае не означает, что в CLR было что-то поменяно.


"Плменяно" тоже было. Но раньше. Насколько мне известно для повышения эффективности использовалась динамическая компиляция деревьев выражений. А это уже не просто библиотека. Хотя по сути весь дотнет — просто библиотека.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.02.11 21:47
Оценка: 8 (1)
Здравствуйте, AndrewVK, Вы писали:

AVK>Сам по себе DLR ничего особо не упрошает, он лишь обеспечивает интероперабельность динамики. Вот стандартные биндеры, те могут кое что упростить. Но это все не имеет никакого отношения к возможности CLR хостить разные языки.


Да, наверное. Но у CLR и других проблем хватает. Классы в IL загнали, а замыкания нужно эмулировать. Для ленивого выполнения никакой поддержки нет. Гарантировать неизменяемость данных CLR тоже не может. Есть делегаты, но нет более общего функционального типа. Объеденений тоже нет. И сделать кроме как через ООП нельзя, так как это связано с реализацией GC. В общем, проблем хватает.

Но объем работ — это не меньшая проблема. Рантайм вроде CLR снимает море работы с компиляторщиков. Но если бы он был спроектирован более правильно, то снимал бы еще больше работы и не создавал бы при это проблем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.02.11 21:49
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Курилка, Вы писали:


VD>>>Тоже самое. Запрещаем статические переменные и получаем shared-nothing. Хотя это как раз уже сказка, так как процессы эрланга таки могут содержать глобальные данные. А сам процесс эрланга удивительно похож на классы в ООП (так как инкапсулирует логику).


К>>Расскажи, что за глобальные данные?


VD>У процессов есть свои словари. Данные в них помещаются и удерживаеются точно так же как в статических переменных. Таким образом в Эрнанке процессы могут капсулировать состояние.


Чот, Влад, путаешься местами в последнее время. Поясни мне, как mutable словари процессов (которые, насколько я понимаю, используются реже чем unsafe на платформе, под которую ты пишешь) стали вдруг глобальными? Ну не надо так-то уж явно
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: night beast СССР  
Дата: 02.02.11 04:55
Оценка:
Здравствуйте, VladD2, Вы писали:

C>>Если сроки реально такого порядка — стоит ли ожидать в будущем отдельный диалект языка программирования на каждую программерскую контору или крупный проект?


VD>Не стоит. На самом деле опыт Лиспа и Немерла показал, что в 99% случаев используется базовый язык или стандартные макросы. Хорошие идеи воплощенные в макросах быстро попадают в стандартную библиотеку и становятся практически частью языка.


VD>В прикладных же проектах обычно используются специализированные расширения которые позволяют упростить решение именно этих задач. Это опять же не создает новый язык. Обычно все ограничиваенся созданием DSL-я который позволяет описать задачу близко к ее декларации.


VD>Так что в будущем стоит ожидать введения в обиход большинства программистов механизмов расширения языков и основанную на этом целую парадигму языко-ориентированного (или DSL-ориентированного) программирования. Но вот сколько времени займет процесс перехода к нему не ясно. На сегодня конкурентов немерлу не много. Народ латентен, привычки сильны, а пиар (со стороны монополий вроде MS и IBM) старых подходов только осложняет обстановку. Но, лично у меня, нет сомнений, что за этим подходом будущее.


ты все таки найди время на tex посмотреть.
думаю, не малую роль в его популярности сыграло наличие в свободном доступе Texbook'a, на пальцах описывающего весь язык.
Сможете подобное для немерла сделать?
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 02.02.11 09:48
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Mystic, Вы писали:


M>>Смотря каких паттернов. В общем случае, мне кажется, игра не стоит свеч: на изучение более абстрактной настройки понадобится время, а используется раз в год, два раза на пасху.


VD>Ключевое слово здесь — "кажется".


"Кажется" потому что я этого никогда не видел. И вообще разговор ведется чисто гипотетически, потому что сейчас метапрограммирование мало используется в сложных проектах

VD>Паттерны заполоняют код обычных ОО-проектов. Инкапсуляция их в языковые конструкции позволяет сделать код во много раз чище и проще. Одно это упрощает разработку сложных проектов. А мы еще и не заикались о ДСЛ-ях...


Чище не значит проще для понимания. Это значит, что под тем, что я вижу, находится еще некоторая скрытая логика, которую надо хорошо понимать. Это увеличивает порог вхождения, требуемую квалификацию и т. д. и т. п.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 02.02.11 10:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Программисты из ВУЗ-ов звучит очень смешно. Не находишь?


Нет я имел в виду, что этим языкам (ML и потомки, Хаскель) обучают в вузах, лиспу кстати тоже, и хоть какие-то поверхностные знания да
и остаются, даже по себе могу судить.

FR>>Но я имел в виду что в мейнстрим так и не прошли даже такие.


VD>Дык, а как они пройдут то когда сами базовые языки (без мета-расширений) в мэйстрим попасть не могут.


А зачем базовые, ладно к C++ прикрутить синтаксический макропроцессор очень сложно, но к той же Ява или Шарпу
вполне реально (для производителей языка) вместо выдумывания гораздо более слабых T4.

VD>Ну, а что ты хочешь? Динамика да еще и лиспоподобная. Хотя выглдяит все же по проще чем Лисп.


Все-таки гибрид, изначально можно задавать типы.
От липсоподобности (синтаксической) там как раз и старались избавится, по моему вполне получилось.

FR>>Там вообще много чего наворочено вплоть до минимальной поддержки зависимых типов http://www.opendylan.org/fragments/limited-types.phtml


VD>Интересно...


Угу, я уже давно поковырял и бросил, язык практически заброшен
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: IT Россия linq2db.com
Дата: 02.02.11 17:11
Оценка:
Здравствуйте, gandjustas, Вы писали:

IT>>Откуда такие сведения? Есть конкретный опыт или это всего-лишь измышлизмы?

G>Отлично можно наблюдать при переходе C#2 -> C#3.

Если ты про Linq Comprehension, то там переход не столько на новый синтаксис, сколько на новую парадигму. А синтаксис как раз всё сильно упрощает. Без него вообще была бы оппа.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.02.11 20:51
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, gandjustas, Вы писали:


G>>>>А что мешает сделать вызовы лаконичными без изменения синтаксиса?


VD>>>С C#-ом или ВБ знаком? Покажи как сделать объявление и использование зависимых свойств из WPF "лаконичными без изменения синтаксиса".


G>>Я не про C# говорю.


VD>А ты не уходи от ответа.


Я не ухожу от ответа, это ты пытаешься сузить тему обсуждения до удобной тебе.

Кстати своим примером ты не показал изменение синтаксиса.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.02.11 20:58
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


IT>>>Откуда такие сведения? Есть конкретный опыт или это всего-лишь измышлизмы?

G>>Отлично можно наблюдать при переходе C#2 -> C#3.

IT>Если ты про Linq Comprehension, то там переход не столько на новый синтаксис, сколько на новую парадигму. А синтаксис как раз всё сильно упрощает. Без него вообще была бы оппа.

Посмотри сколько до сих пор холиваров:
1)Linq Comprehension vs Method Calls
2)Extensions vs Instance methods
3)var vs explicit type declarations

Это все чисто синтаксические примочки, которые на семантику никак не влияют.

К изменению синтаксиса надо подходить очень осторожно.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.02.11 20:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Кстати своим примером ты не показал изменение синтаксиса.


Ну, дык хорошему языку это не всегда нужно. Иногда можно и в рамках имеющегося синтаксиса проблемы решить. А вот как их решать с помощью языка который не поддерживает никакого расширения?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.02.11 20:59
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

G>>А кто мешает в рантайме переписывать?

WH>И машинный код сгенерировать,... и получишь ты макросы немерла вид в профиль.
Когда в руках молоток — все вокруг кажется гвоздями.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: IT Россия linq2db.com
Дата: 02.02.11 21:08
Оценка: +2 :)
Здравствуйте, gandjustas, Вы писали:

IT>>Если ты про Linq Comprehension, то там переход не столько на новый синтаксис, сколько на новую парадигму. А синтаксис как раз всё сильно упрощает. Без него вообще была бы оппа.

G>Посмотри сколько до сих пор холиваров:
G>1)Linq Comprehension vs Method Calls
G>2)Extensions vs Instance methods
G>3)var vs explicit type declarations

Все эти холивары инициируются как раз людьми, которые пока ещё не в теме и не совсем понимают смысл новых возможностей. После того как они всё осваивают, холиварить уже нет смысла.

G>Это все чисто синтаксические примочки, которые на семантику никак не влияют.

G>К изменению синтаксиса надо подходить очень осторожно.

Но подходить нужно. Иначе бы мы все до сих пор на ассемблере писали. Да и осторожность здесь нужна только по причине того, что обратной дороги нет всем пользователям языка. Если же мне дадут возможность расширять язык в моём собственном огороде, то чего мне осторожничать? Но в результате, во-первых, мне не нужно никого ждать годами, а, во-вторых, из таких огородов может произрости и выкристализоваться что-то ценное и полезное для всех.
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.02.11 21:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, gandjustas, Вы писали:


G>>Кстати своим примером ты не показал изменение синтаксиса.


VD>Ну, дык хорошему языку это не всегда нужно.

Именно

VD>А вот как их решать с помощью языка который не поддерживает никакого расширения?

А необязательно это делать на уровне языка.

Например в .NET Code Contracts реализованы на уровне IL и к языку не привязаны.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.02.11 21:22
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


IT>>>Если ты про Linq Comprehension, то там переход не столько на новый синтаксис, сколько на новую парадигму. А синтаксис как раз всё сильно упрощает. Без него вообще была бы оппа.

G>>Посмотри сколько до сих пор холиваров:
G>>1)Linq Comprehension vs Method Calls
G>>2)Extensions vs Instance methods
G>>3)var vs explicit type declarations

IT>Все эти холивары инициируются как раз людьми, которые пока ещё не в теме и не совсем понимают смысл новых возможностей. После того как они всё осваивают, холиварить уже нет смысла.


Причины не имеют значения. Факты есть. Даже небольшие изменения синтаксиса массового языка очень сильно "аукаются". Поэтому изменение синтаксиса должно быть хорошо продумано. Нельзя этот вопрос давать на откуп каждому разработчику.


G>>Это все чисто синтаксические примочки, которые на семантику никак не влияют.

G>>К изменению синтаксиса надо подходить очень осторожно.

IT>Но подходить нужно. Иначе бы мы все до сих пор на ассемблере писали. Да и осторожность здесь нужна только по причине того, что обратной дороги нет всем пользователям языка. Если же мне дадут возможность расширять язык в моём собственном огороде, то чего мне осторожничать? Но в результате, во-первых, мне не нужно никого ждать годами, а, во-вторых, из таких огородов может произрости и выкристализоваться что-то ценное и полезное для всех.

Программы как всегда пишутся один раз, а читаются гораздо больше.
Если для функции есть intellisense, F1, Goto Definition, то для новых конструкций языка всего этого нет.

Кроме того затрудняется командная разработка. Конфликты имен функций\классов решаются неймспейсами. Как разрешать конфликт расширений синтаксиса?
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: IT Россия linq2db.com
Дата: 02.02.11 22:16
Оценка:
Здравствуйте, gandjustas, Вы писали:

IT>>Все эти холивары инициируются как раз людьми, которые пока ещё не в теме и не совсем понимают смысл новых возможностей. После того как они всё осваивают, холиварить уже нет смысла.


G>Причины не имеют значения. Факты есть. Даже небольшие изменения синтаксиса массового языка очень сильно "аукаются".


Я же говорю. Давайте жить без ауканья и писать на ассемблере.

G>Поэтому изменение синтаксиса должно быть хорошо продумано. Нельзя этот вопрос давать на откуп каждому разработчику.


Каждый разработчик отвечает за себя сам. Ну и за тех, кто от него зависит. Ты, например, от меня никак не зависишь. Я от тебя тоже. Так почему же ты мне или я тебе должен запрещать использовать или создавать под себя такие инструменты, какие мне или тебе хочется? Не надо думать за всё человечество. Оно как-нибудь само обойдётся без такой заботы.

G>Программы как всегда пишутся один раз, а читаются гораздо больше.

G>Если для функции есть intellisense, F1, Goto Definition, то для новых конструкций языка всего этого нет.

Почему же? Немерле при наведении мышкой на синтаксический макрос выводится код, который он генерирует. Если над этим поработать, то можно и Goto Definition нормальный сделать. В общем, дело техники, никаких концептуальных проблем.

G>Кроме того затрудняется командная разработка. Конфликты имен функций\классов решаются неймспейсами. Как разрешать конфликт расширений синтаксиса?


Точно так же как и другие конфликты имён. В C#, например, решили же проблему конфликта ключевых слов и идентификаторов.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Способно ли метапрограммирование заменить отдельные язык
От: olegkr  
Дата: 02.02.11 22:52
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

В идеальном мире с идеальными программистами идея, конечно, привлекательная. Но как представлю, что индусы начнут еще и свои языки писать по делу и без дела, становится невесело. Хочешь получить себе на саппорт такой проектик из индийской деревни? Как бы хинди учить не пришлось.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.02.11 22:56
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


IT>>>Все эти холивары инициируются как раз людьми, которые пока ещё не в теме и не совсем понимают смысл новых возможностей. После того как они всё осваивают, холиварить уже нет смысла.


G>>Причины не имеют значения. Факты есть. Даже небольшие изменения синтаксиса массового языка очень сильно "аукаются".


IT>Я же говорю. Давайте жить без ауканья и писать на ассемблере.


Не кидайся в крайности.

G>>Поэтому изменение синтаксиса должно быть хорошо продумано. Нельзя этот вопрос давать на откуп каждому разработчику.


IT>Каждый разработчик отвечает за себя сам. Ну и за тех, кто от него зависит. Ты, например, от меня никак не зависишь. Я от тебя тоже. Так почему же ты мне или я тебе должен запрещать использовать или создавать под себя такие инструменты, какие мне или тебе хочется? Не надо думать за всё человечество. Оно как-нибудь само обойдётся без такой заботы.

Так создавай, только сначала подумай чтобы твои инструменты не мешали другим. Вот именно в синтаксисе языка это очень непросто.


G>>Программы как всегда пишутся один раз, а читаются гораздо больше.

G>>Если для функции есть intellisense, F1, Goto Definition, то для новых конструкций языка всего этого нет.

IT>Почему же? Немерле при наведении мышкой на синтаксический макрос выводится код, который он генерирует. Если над этим поработать, то можно и Goto Definition нормальный сделать. В общем, дело техники, никаких концептуальных проблем.

А еще бы ограничить немного, чтобы синтаксис был не произвольный, а укладывался в какие-то рамки, тогда отличия от вызовов функций будут минимальны.
В идеале хорошо бы иметь возможность часть вычислений перенести из runtime в compiletime, не выписывая сложные конструкции в виде макросов. Пусть все выглядит как вызовы функций. Давать каждому менять синтаксис не стоит.


G>>Кроме того затрудняется командная разработка. Конфликты имен функций\классов решаются неймспейсами. Как разрешать конфликт расширений синтаксиса?

IT>Точно так же как и другие конфликты имён. В C#, например, решили же проблему конфликта ключевых слов и идентификаторов.
Ввели contextual keywords и символ @. Но если все подряд начнут менять синтаксис этого явно будет недостаточно.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.02.11 01:01
Оценка:
Здравствуйте, gandjustas, Вы писали:

VD>>А вот как их решать с помощью языка который не поддерживает никакого расширения?

G>А необязательно это делать на уровне языка.

G>Например в .NET Code Contracts реализованы на уровне IL и к языку не привязаны.


Не надо трепаться. Ты реализуй, и посмотрим что у тебя получилось.

Пойми, приведенный мной код был написан вот так же между двумя сообщениями (т.е. он совершенно не напряг писавшего).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 03.02.11 03:13
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А еще бы ограничить немного, чтобы синтаксис был не произвольный, а укладывался в какие-то рамки, тогда отличия от вызовов функций будут минимальны.

G>В идеале хорошо бы иметь возможность часть вычислений перенести из runtime в compiletime, не выписывая сложные конструкции в виде макросов. Пусть все выглядит как вызовы функций. Давать каждому менять синтаксис не стоит.

Макросы могут принимать вид синтаксического расширения, функций и атрибутов. Например, можно написать макрос-аттрибут уровня сборки, который будет запрещать создавать синтаксические макросы
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: 0x7be СССР  
Дата: 03.02.11 05:28
Оценка: +2
Здравствуйте, Eye of Hell, Вы писали:

EOH>Не-е-е-е, тут, ИМХО, мы не создаем свой язык — мы создаем абстракции на базе известного программистам языка/технологии. Если у меня архитектура actor model на Qt, то знающий C++ и Qt человек ее поймет, потому что все примитивы и приемы кодирования ему известны. А вот если я под эту actor model наваяю собственный синтаксис, который уменьшит количество моего кода в пару-тройку раз, то с этим синтаксисом новому человеку будет разобраться намного сложнее. А уж поменять что-нибудь — большой проблемой.

Не согласен. Взять тот же Qt — это своего рода язык, который надо отдельно изучать. Я знаю С++, но покажи мне программу на Qt — с ходу не разберусь. А почему? Qt не знаю.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.02.11 11:42
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


G>>А еще бы ограничить немного, чтобы синтаксис был не произвольный, а укладывался в какие-то рамки, тогда отличия от вызовов функций будут минимальны.

G>>В идеале хорошо бы иметь возможность часть вычислений перенести из runtime в compiletime, не выписывая сложные конструкции в виде макросов. Пусть все выглядит как вызовы функций. Давать каждому менять синтаксис не стоит.

IT>Макросы могут принимать вид синтаксического расширения, функций и атрибутов. Например, можно написать макрос-аттрибут уровня сборки, который будет запрещать создавать синтаксические макросы


Давайте отделять мух от котлет. Несмотря на то что в nemerle "синтаксические расширения, функции и атрибуты" реализованы одним механизмом макросов это совсем не значит что только так и стоит делать.
Яркий пример — code contracts в .NET, реализованы IL-реврайтером и не привязаны к языку. Причем Code Contracts состоят как из "функций", так и из "атрибутов".

Единственное что привязано к языку в указанной выше тройке — синтаксические расширения. Вот именно они вызывают наибольшие сомнения.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 03.02.11 12:24
Оценка: +1
Здравствуйте, olegkr, Вы писали:

O>Здравствуйте, Chrome, Вы писали:


C>>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

O>В идеальном мире с идеальными программистами идея, конечно, привлекательная. Но как представлю, что индусы начнут еще и свои языки писать по делу и без дела, становится невесело. Хочешь получить себе на саппорт такой проектик из индийской деревни? Как бы хинди учить не пришлось.

Думаю, дело привычки.
Вы ведь не отказываете индусам в праве писать собственные классы или библиотеки?
Хотя в природе есть такие стандартизированные и всеохватывающие мегамонстры как .net framework, MFC, stl. Почему бы не заставить своих коллег использовать только определенные в них классы и методы?
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 03.02.11 13:07
Оценка:
Отвечаю на цитаты по отношению ко мне .

>>но тем сложнее и дольше его поддерживать другим людям.
Это заблуждение обычно муссируют те, кто "знаком" с проблемой теоретически. На практике же как раз поддерживать ДСЛ-и куда проще. Обычно ДСЛ-и весьма просты и очень легко осваиваются (намного проще нежели код решающий ту же задачу).


Владислав, вы меня пугаете O_O. Ну давайте померяемся, мне не жалко. У меня больше 10 лет в коммерческой разработке, из крупных проектов в которых участвовал — например, Radmin. Делал много кодегенерации и DSL: XSLT, TT, lisp, python. Последние несколько лет — Ruby. того достаточно, чтобы считать меня знакомым с проблемой практически? Если угостите кофе — могу зайти в гости, убедитесь в моей квалификации лично . Поддержка DSL — плевое дело, пока рядом есть автор. А вот если автор йок, то с DSL очень большие проблемы.

> Соответственно, это не так популярно потому как компании хотят защититься от эффекта падающего кирпича.
Можно описание этого эффекта?


Это когда на голову ведущему разработчику падает кирпич с летальными последствиями .

> Если архитектор DSL покинет компанию или даже заболеет — будут большие проблемы. ОЧЕНЬ большие проблемы.
Чушь полнейшая. Как минимум есть множество примеров ДСЛ-ей широко используемых на практике (BNF, ASP/JSP, Regex). Никаких отличий у доморощенных ДСЛ-ей нет и быть не может.


Есть некая разница между широко распространенным DSL типа rake и тем, что мы сделали сами, нэ?
Если Вы считаете, что в DSL прямо вот так легко разобраться — возьмити любой проект Ruby on Rails и загляните внутрь. Будете приятно удивлены лаконичности кода и полным непонимаем как "это" работает "внутри". И это еще популярный DSL. А если кто такое сам напишет?
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 03.02.11 13:08
Оценка:

Неужели перспектива сократить код в 2-3 раза
не сподвигнет вас на изучение небольшого расширения синтаксиса?


Меня — может быть. Но как team lead я еще должен заботиться о тех, кто этот код будет поддерживать в будующем. Поэтому считаю что чем проще — тем лучше. И стараюсь выбрать разумные рамки. Активное использование DSL на мой взгляд за рамки выходит.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 03.02.11 13:13
Оценка: :)

Если синтаксис действительно настолько крут, что настолько уменьшает количество кода, то затраты на обучение ему (совсем не такие большие как кажутся) окупаются скоростью разработки и качеством результата.


Увы, практика показывает что код больше читается / поддерживается, нежели пишется. Я не считаю, что введение нового языка программирования ради сокращения кода при написании стоит того, чтобы увольнение / найм людей постоянно давали проблемы. Посмотрите в сетевой стек FreeBSD — там как раз собственны DSL на базе C. Это НЕВОЗМОЖНО ни читать, ни поддерживать. Хотя писалось, наверное, быстро. Лично я не хочу тратить лишние 2-3 недели на то, чтобы разработчик ознакомился с дополнительным парком велосипедов. Мне и существующих хватает.

>>А уж поменять что-нибудь — большой проблемой.
А от это уже зависит от качества реализации "собственного синтаксиса".


Согласен. Но сделать хороший DSL — трудно. Поэтому лучше не злоупотреблять. Генерить биндинги — это клево. Но вот писать на собственном синтаксисе ядро программы — это может очень болезненно отразиться в будущем.

Разве никто не здесь не допускает возможности того, что сложность реализации "синтаксиса" эквивалентна написанию библиотеки, а удобство использования в определенных случаях может быть значительно выше?


Именно поэтому я ратую за использование стандартных библиотек. Вот такой я ретроград ^_^.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 03.02.11 13:14
Оценка:

Не согласен. Взять тот же Qt — это своего рода язык, который надо отдельно изучать. Я знаю С++, но покажи мне программу на Qt — с ходу не разберусь. А почему? Qt не знаю.


Вы не поверите — но даже те жалкие крохи с сигналами и foreach в Qt доставляют огромные проблемы огромному количеству программистов. А теперь представьте себе, что будет если налево и направо использовать полноценные DSL? .
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: olegkr  
Дата: 03.02.11 14:55
Оценка:
Здравствуйте, Chrome, Вы писали:

C>Вы ведь не отказываете индусам в праве писать собственные классы или библиотеки?

Библиотеки точно отказываю, публичные интерфейсы надо писать самому, а то они такого напишут.

C>Почему бы не заставить своих коллег использовать только определенные в них классы и методы?

Ну да, и запретить индусам метапрограммировать. Проблема только в том, что обычно манагеры не парятся и тупо сливают проект в Индию, как хотите, так и делайте. Ну они и "делают". Потом сидишь и плачешь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Re[12]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 03.02.11 15:00
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>>>В идеале хорошо бы иметь возможность часть вычислений перенести из runtime в compiletime, не выписывая сложные конструкции в виде макросов. Пусть все выглядит как вызовы функций. Давать каждому менять синтаксис не стоит.

IT>>Макросы могут принимать вид синтаксического расширения, функций и атрибутов. Например, можно написать макрос-аттрибут уровня сборки, который будет запрещать создавать синтаксические макросы

G>Давайте отделять мух от котлет. Несмотря на то что в nemerle "синтаксические расширения, функции и атрибуты" реализованы одним механизмом макросов это совсем не значит что только так и стоит делать.

G>Яркий пример — code contracts в .NET, реализованы IL-реврайтером и не привязаны к языку. Причем Code Contracts состоят как из "функций", так и из "атрибутов".
G>Единственное что привязано к языку в указанной выше тройке — синтаксические расширения. Вот именно они вызывают наибольшие сомнения.

Тебя не поймёшь. Тебе хочется, чтобы всё выглядело как вызовы функций? Получай. Ан нет. Синтаксические расширения всё равно мешаются.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: Silver_S Ниоткуда  
Дата: 03.02.11 15:30
Оценка: +1
Здравствуйте, Eye of Hell, Вы писали:

EOH>Вы не поверите — но даже те жалкие крохи с сигналами и foreach в Qt доставляют огромные проблемы огромному количеству программистов. А теперь представьте себе, что будет если налево и направо использовать полноценные DSL? .


А аналогичные проекты но на MFC,WTL, или голом WinAPI, те же самые программисты быстрее пишут, поддерживают, баги находят (производительность выше)?
Хотя и в MFC есть метапрограммирование(жуткие макросы), да и WTL ... С голым WinAPI,C++ наверно надо сравнивать.
Я не в курсе что там в QT. Переборщили со средствами сокращения кода?
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 03.02.11 17:14
Оценка: 6 (1)
Здравствуйте, Eye of Hell, Вы писали:

EOH>

Если синтаксис действительно настолько крут, что настолько уменьшает количество кода, то затраты на обучение ему (совсем не такие большие как кажутся) окупаются скоростью разработки и качеством результата.



EOH>Увы, практика показывает что код больше читается / поддерживается, нежели пишется.

Вот именно.
Тебе что проще читать вот это:
      // illegal identifiers:
      keyword = ("abstract"     / "as"          / "base"        / "bool"        / "break"
                / "byte"        / "case"        / "catch"       / "char"        / "checked"
                / "class"       / "const"       / "continue"    / "decimal"     / "default"
                / "delegate"    / "do"          / "double"      / "else"        / "enum"
                / "event"       / "explicit"    / "extern"      / "false"       / "finally"
                / "fixed"       / "float"       / "for"         / "foreach"     / "goto"
                / "if"          / "implicit"    / "in"          / "int"         / "interface"
                / "internal"    / "is"          / "lock"        / "long"        / "namespace"
                / "new"         / "null"        / "object"      / "operator"    / "out"
                / "override"    / "params"      / "private"     / "protected"   / "public"
                / "readonly"    / "ref"         / "return"      / "sbyte"       / "sealed"
                / "short"       / "sizeof"      / "stackalloc"  / "static"      / "string"
                / "struct"      / "switch"      / "this"        / "throw"       / "true"
                / "try"         / "typeof"      / "uint"        / "ulong"       / "unchecked"
                / "unsafe"      / "ushort"      / "using"       / "virtual"     / "void"
                / "volatile"    / "while"       ) !identifierPartCharacters;

      letterCharacter       = [Lu, Ll, Lt, Lm, Lo, Nl];
      combiningCharacter    = [Mn, Mc];
      decimalDigitCharacter = [Nd];
      connectingCharacter   = [Pc];
      formattingCharacter   = [Cf];

      identifierStartCharacter  = letterCharacter / "_";
      identifierPartCharacters  = letterCharacter / decimalDigitCharacter / connectingCharacter / combiningCharacter / formattingCharacter;
      identifierBody            = identifierStartCharacter identifierPartCharacters*;
      identifier            : Identifier  = !keyword "@"? identifierBody s;

Или вот это (Я не в состоянии это ни прочитать ни написать):
  Скрытый текст
Там вместо '?' должны быть юниодные символы. Все никак руки не дойдут преттипринтер починить...
private __GENERATED_PEG__RULE__identifier__(pos : int, text : string) : int
{
  unchecked 
  {
    mutable (c : char);
    _  = c;
    
    {
      def pos = 
      {
        def newPos = __GENERATED_PEG__RULE__keyword__(pos, text);
        if (newPos < 0) pos; else -1
      };
      if (pos >= 0) 
      {
        def pos = 
        {
          mutable okPos = -1;
          mutable curPos = pos;
          l4979:
            DEFAULT;
          okPos = curPos;
          when (curPos >= text.Length) goto l4982 [1];;
          c = text[curPos];
          ++curPos;
          when (c == '@') goto l4981 [1];;
          goto l4982 [1];;
          l4981:
            DEFAULT;
          okPos = curPos;
          l4982:
            DEFAULT;
          okPos
        };
        if (pos >= 0) 
        {
          def pos = __GENERATED_PEG__RULE__identifierBody__(pos, text);
          if (pos >= 0) __GENERATED_PEG__RULE__s__(pos, text); else -1
        }; else -1
      }; else -1
    }
  }
}

private __GENERATED_PEG__RULE__identifierBody__(pos : int, text : string) : int
{
  unchecked 
  {
    mutable (c : char);
    _  = c;
    
    {
      def pos = 
      {
        mutable okPos = -1;
        mutable curPos = pos;
        l4985:
          DEFAULT;
        when (curPos >= text.Length) goto l4988 [1];;
        c = text[curPos];
        ++curPos;
        when (if (c >= 'A') 
        {
          if (c >= '?') 
          {
            if (c >= '?') 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= 'a') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= 'z'
                        }
                      }; else 
                      {
                        if (c >= 'A') 
                        {
                          c <= 'Z'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }
            }; else 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }; else 
          {
            if (c >= '?') 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }
            }; else 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          if (c >= '?') 
                          {
                            c <= '?'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= 'o') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= 'O') 
                        {
                          c <= 'o'
                        }; else 
                        {
                          if (c >= 'A') 
                          {
                            c <= 'O'
                          }; else 
                          {
                            c <= '?'
                          }
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= 'µ') 
                        {
                          c <= 'µ'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= 'a') 
                        {
                          c <= 'z'
                        }; else 
                        {
                          if (c >= '_') 
                          {
                            c <= '_'
                          }; else 
                          {
                            c <= 'Z'
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }; else 
        {
          false
        }) goto l4987 [1];;
        goto l4988 [1];;
        l4987:
          DEFAULT;
        okPos = curPos;
        l4988:
          DEFAULT;
        okPos
      };
      if (pos >= 0) 
      {
        def rep (pos : int)  
        {
          def newPos = __GENERATED_PEG__RULE__identifierPartCharacters__(pos, text);
          if (newPos >= 0) 
          {
            ();
            rep(newPos)
          }; else pos
        } : _ ;
        rep(pos)
      }; else -1
    }
  }
}

private __GENERATED_PEG__RULE__identifierPartCharacters__(pos : int, text : string) : int
{
  unchecked 
  {
    mutable (c : char);
    _  = c;
    
    {
      mutable okPos = -1;
      mutable curPos = pos;
      l4991:
        DEFAULT;
      when (curPos >= text.Length) goto l4994 [1];;
      c = text[curPos];
      ++curPos;
      when (if (c >= '0') 
      {
        if (c >= '?') 
        {
          if (c >= '?') 
          {
            if (c >= '?') 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= 'A') 
                    {
                      if (c >= 'a') 
                      {
                        c <= 'z'
                      }; else 
                      {
                        if (c >= '_') 
                        {
                          c <= '_'
                        }; else 
                        {
                          c <= 'Z'
                        }
                      }
                    }; else 
                    {
                      if (c >= '0') 
                      {
                        c <= '9'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }; else 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }
          }; else 
          {
            if (c >= '?') 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }; else 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }; else 
        {
          if (c >= '?') 
          {
            if (c >= '?') 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }; else 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }
          }; else 
          {
            if (c >= '?') 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }
            }; else 
            {
              if (c >= '?') 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }
              }; else 
              {
                if (c >= '?') 
                {
                  if (c >= '?') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }
                  }
                }; else 
                {
                  if (c >= 'A') 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= '?') 
                        {
                          c <= '?'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= 'o') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= 'O') 
                        {
                          c <= 'o'
                        }; else 
                        {
                          c <= 'O'
                        }
                      }
                    }
                  }; else 
                  {
                    if (c >= '?') 
                    {
                      if (c >= '?') 
                      {
                        c <= '?'
                      }; else 
                      {
                        if (c >= 'µ') 
                        {
                          c <= 'µ'
                        }; else 
                        {
                          c <= '?'
                        }
                      }
                    }; else 
                    {
                      if (c >= '_') 
                      {
                        if (c >= 'a') 
                        {
                          c <= 'z'
                        }; else 
                        {
                          c <= '_'
                        }
                      }; else 
                      {
                        if (c >= 'A') 
                        {
                          c <= 'Z'
                        }; else 
                        {
                          c <= '9'
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }; else 
      {
        false
      }) goto l4993 [1];;
      goto l4994 [1];;
      l4993:
        DEFAULT;
      okPos = curPos;
      l4994:
        DEFAULT;
      okPos
    }
  }
}

private __GENERATED_PEG__RULE__keyword__(pos : int, text : string) : int
{
  unchecked 
  {
    mutable (c : char);
    _  = c;
    
    {
      def pos = 
      {
        mutable okPos = -1;
        mutable curPos = pos;
        l4997:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l4998 [1];;
        when (c == 'b') goto l4999 [1];;
        when (c == 'c') goto l5000 [1];;
        when (c == 'd') goto l5001 [1];;
        when (c == 'e') goto l5002 [1];;
        when (c == 'f') goto l5003 [1];;
        when (c == 'g') goto l5151 [1];;
        when (c == 'i') goto l5005 [1];;
        when (c == 'l') goto l5146 [1];;
        when (c == 'n') goto l5006 [1];;
        when (c == 'o') goto l5007 [1];;
        when (c == 'p') goto l5008 [1];;
        when (c == 'r') goto l5159 [1];;
        when (c == 's') goto l5010 [1];;
        when (c == 't') goto l5011 [1];;
        when (c == 'u') goto l5012 [1];;
        when (c == 'v') goto l5058 [1];;
        when (c == 'w') goto l5080 [1];;
        goto l5170 [1];;
        l4998:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'b') goto l5033 [1];;
        when (c == 's') goto l5169 [1];;
        goto l5170 [1];;
        l4999:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5073 [1];;
        when (c == 'o') goto l5004 [1];;
        when (c == 'r') goto l5057 [1];;
        when (c == 'y') goto l5086 [1];;
        goto l5170 [1];;
        l5000:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5076 [1];;
        when (c == 'h') goto l5051 [1];;
        when (c == 'l') goto l5085 [1];;
        when (c == 'o') goto l5067 [1];;
        goto l5170 [1];;
        l5001:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5049 [1];;
        when (c == 'o') goto l5055 [1];;
        goto l5170 [1];;
        l5002:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5073 [1];;
        when (c == 'n') goto l5087 [1];;
        when (c == 'v') goto l5118 [1];;
        when (c == 'x') goto l5048 [1];;
        goto l5170 [1];;
        l5003:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5129 [1];;
        when (c == 'i') goto l5047 [1];;
        when (c == 'l') goto l5056 [1];;
        when (c == 'o') goto l5098 [1];;
        goto l5170 [1];;
        l5004:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5016 [1];;
        goto l5170 [1];;
        l5005:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'm') goto l5032 [1];;
        when (c == 'n') goto l5053 [1];;
        when (c == 'f' || c == 's') goto l5169 [1];;
        goto l5170 [1];;
        l5006:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5093 [1];;
        when (c == 'e') goto l5034 [1];;
        when (c == 'u') goto l5136 [1];;
        goto l5170 [1];;
        l5007:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'b') goto l5044 [1];;
        when (c == 'p') goto l5147 [1];;
        when (c == 'u') goto l5021 [1];;
        when (c == 'v') goto l5141 [1];;
        goto l5170 [1];;
        l5008:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5167 [1];;
        when (c == 'r') goto l5013 [1];;
        when (c == 'u') goto l5163 [1];;
        goto l5170 [1];;
        l5009:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5169 [1];;
        goto l5170 [1];;
        l5010:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'b') goto l5074 [1];;
        when (c == 'e') goto l5156 [1];;
        when (c == 'h') goto l5134 [1];;
        when (c == 'i') goto l5036 [1];;
        when (c == 't') goto l5037 [1];;
        when (c == 'w') goto l5119 [1];;
        goto l5170 [1];;
        l5011:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'h') goto l5030 [1];;
        when (c == 'r') goto l5031 [1];;
        when (c == 'y') goto l5091 [1];;
        goto l5170 [1];;
        l5012:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5088 [1];;
        when (c == 'l') goto l5166 [1];;
        when (c == 'n') goto l5024 [1];;
        when (c == 's') goto l5025 [1];;
        goto l5170 [1];;
        l5013:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5042 [1];;
        when (c == 'o') goto l5132 [1];;
        goto l5170 [1];;
        l5014:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'h') goto l5169 [1];;
        goto l5170 [1];;
        l5015:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5023 [1];;
        goto l5170 [1];;
        l5016:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5169 [1];;
        goto l5170 [1];;
        l5017:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5020 [1];;
        goto l5170 [1];;
        l5018:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5019 [1];;
        when (c == 'l') goto l5160 [1];;
        goto l5170 [1];;
        l5019:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'd') goto l5169 [1];;
        goto l5170 [1];;
        l5020:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5028 [1];;
        goto l5170 [1];;
        l5021:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5169 [1];;
        goto l5170 [1];;
        l5022:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5009 [1];;
        goto l5170 [1];;
        l5023:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5022 [1];;
        goto l5170 [1];;
        l5024:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5059 [1];;
        when (c == 's') goto l5158 [1];;
        goto l5170 [1];;
        l5025:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'h') goto l5134 [1];;
        when (c == 'i') goto l5124 [1];;
        goto l5170 [1];;
        l5026:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'g') goto l5111 [1];;
        goto l5170 [1];;
        l5027:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'f') goto l5169 [1];;
        goto l5170 [1];;
        l5028:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5021 [1];;
        goto l5170 [1];;
        l5029:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'k') goto l5169 [1];;
        goto l5170 [1];;
        l5030:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5092 [1];;
        when (c == 'r') goto l5140 [1];;
        goto l5170 [1];;
        l5031:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5009 [1];;
        when (c == 'y') goto l5169 [1];;
        goto l5170 [1];;
        l5032:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'p') goto l5097 [1];;
        goto l5170 [1];;
        l5033:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5065 [1];;
        goto l5170 [1];;
        l5034:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'w') goto l5169 [1];;
        goto l5170 [1];;
        l5035:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'y') goto l5169 [1];;
        goto l5170 [1];;
        l5036:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'z') goto l5155 [1];;
        goto l5170 [1];;
        l5037:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5038 [1];;
        when (c == 'r') goto l5039 [1];;
        goto l5170 [1];;
        l5038:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5090 [1];;
        when (c == 't') goto l5164 [1];;
        goto l5170 [1];;
        l5039:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5124 [1];;
        when (c == 'u') goto l5028 [1];;
        goto l5170 [1];;
        l5040:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5084 [1];;
        when (c == 'f') goto l5169 [1];;
        when (c == 't') goto l5101 [1];;
        goto l5170 [1];;
        l5041:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'b') goto l5082 [1];;
        goto l5170 [1];;
        l5042:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'v') goto l5111 [1];;
        goto l5170 [1];;
        l5043:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'm') goto l5099 [1];;
        goto l5170 [1];;
        l5044:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'j') goto l5135 [1];;
        goto l5170 [1];;
        l5045:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5029 [1];;
        when (c == 'n') goto l5068 [1];;
        goto l5170 [1];;
        l5046:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'f') goto l5168 [1];;
        when (c == 'n') goto l5099 [1];;
        goto l5170 [1];;
        l5047:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5131 [1];;
        when (c == 'x') goto l5079 [1];;
        goto l5170 [1];;
        l5048:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'p') goto l5097 [1];;
        when (c == 't') goto l5107 [1];;
        goto l5170 [1];;
        l5049:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5060 [1];;
        when (c == 'f') goto l5122 [1];;
        when (c == 'l') goto l5095 [1];;
        goto l5170 [1];;
        l5050:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5021 [1];;
        when (c == 't') goto l5015 [1];;
        goto l5170 [1];;
        l5051:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5062 [1];;
        when (c == 'e') goto l5089 [1];;
        goto l5170 [1];;
        l5053:
          DEFAULT;
        okPos = curPos;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5077 [1];;
        goto l5170 [1];;
        l5054:
          DEFAULT;
        okPos = curPos;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5162 [1];;
        goto l5170 [1];;
        l5055:
          DEFAULT;
        okPos = curPos;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5041 [1];;
        goto l5170 [1];;
        l5056:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5138 [1];;
        goto l5170 [1];;
        l5057:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5064 [1];;
        goto l5170 [1];;
        l5058:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5143 [1];;
        when (c == 'o') goto l5018 [1];;
        goto l5170 [1];;
        l5059:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'h') goto l5157 [1];;
        goto l5170 [1];;
        l5060:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5043 [1];;
        goto l5170 [1];;
        l5061:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5021 [1];;
        goto l5170 [1];;
        l5062:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5169 [1];;
        goto l5170 [1];;
        l5063:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'd') goto l5009 [1];;
        goto l5170 [1];;
        l5064:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5029 [1];;
        goto l5170 [1];;
        l5065:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5017 [1];;
        goto l5170 [1];;
        l5066:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5061 [1];;
        goto l5170 [1];;
        l5067:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5050 [1];;
        goto l5170 [1];;
        l5068:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'g') goto l5169 [1];;
        goto l5170 [1];;
        l5069:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'f') goto l5009 [1];;
        goto l5170 [1];;
        l5070:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5014 [1];;
        goto l5170 [1];;
        l5071:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'k') goto l5079 [1];;
        goto l5170 [1];;
        l5072:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'p') goto l5168 [1];;
        goto l5170 [1];;
        l5073:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5009 [1];;
        goto l5170 [1];;
        l5074:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'y') goto l5086 [1];;
        goto l5170 [1];;
        l5075:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'm') goto l5169 [1];;
        goto l5170 [1];;
        l5076:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5009 [1];;
        when (c == 't') goto l5070 [1];;
        goto l5170 [1];;
        l5077:
          DEFAULT;
        okPos = curPos;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5110 [1];;
        goto l5170 [1];;
        l5078:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5169 [1];;
        goto l5170 [1];;
        l5079:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5019 [1];;
        goto l5170 [1];;
        l5080:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'h') goto l5128 [1];;
        goto l5170 [1];;
        l5081:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5021 [1];;
        goto l5170 [1];;
        l5082:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5009 [1];;
        goto l5170 [1];;
        l5083:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5102 [1];;
        goto l5170 [1];;
        l5084:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'd') goto l5106 [1];;
        goto l5170 [1];;
        l5085:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5104 [1];;
        goto l5170 [1];;
        l5086:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5009 [1];;
        goto l5170 [1];;
        l5087:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5075 [1];;
        goto l5170 [1];;
        l5088:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5021 [1];;
        goto l5170 [1];;
        l5089:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5071 [1];;
        goto l5170 [1];;
        l5090:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'k') goto l5154 [1];;
        goto l5170 [1];;
        l5091:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'p') goto l5155 [1];;
        goto l5170 [1];;
        l5092:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5169 [1];;
        goto l5170 [1];;
        l5093:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'm') goto l5127 [1];;
        goto l5170 [1];;
        l5094:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5062 [1];;
        goto l5170 [1];;
        l5095:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5026 [1];;
        goto l5170 [1];;
        l5096:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5103 [1];;
        goto l5170 [1];;
        l5097:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5096 [1];;
        goto l5170 [1];;
        l5098:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5054 [1];;
        goto l5170 [1];;
        l5099:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5016 [1];;
        goto l5170 [1];;
        l5100:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5078 [1];;
        goto l5170 [1];;
        l5101:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5083 [1];;
        goto l5170 [1];;
        l5102:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5169 [1];;
        goto l5170 [1];;
        l5103:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5081 [1];;
        goto l5170 [1];;
        l5104:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5092 [1];;
        goto l5170 [1];;
        l5105:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'm') goto l5092 [1];;
        goto l5170 [1];;
        l5106:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5114 [1];;
        goto l5170 [1];;
        l5107:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5083 [1];;
        goto l5170 [1];;
        l5108:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5063 [1];;
        goto l5170 [1];;
        l5109:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5035 [1];;
        goto l5170 [1];;
        l5110:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5046 [1];;
        goto l5170 [1];;
        l5111:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5086 [1];;
        goto l5170 [1];;
        l5112:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5094 [1];;
        goto l5170 [1];;
        l5113:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'u') goto l5099 [1];;
        goto l5170 [1];;
        l5114:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5109 [1];;
        goto l5170 [1];;
        l5115:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5009 [1];;
        goto l5170 [1];;
        l5116:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 's') goto l5072 [1];;
        goto l5170 [1];;
        l5117:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5027 [1];;
        goto l5170 [1];;
        l5118:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5088 [1];;
        goto l5170 [1];;
        l5119:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5139 [1];;
        goto l5170 [1];;
        l5120:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5109 [1];;
        goto l5170 [1];;
        l5121:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5108 [1];;
        goto l5170 [1];;
        l5122:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5066 [1];;
        goto l5170 [1];;
        l5123:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5079 [1];;
        goto l5170 [1];;
        l5124:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'n') goto l5068 [1];;
        goto l5170 [1];;
        l5125:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5123 [1];;
        goto l5170 [1];;
        l5126:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5133 [1];;
        goto l5170 [1];;
        l5127:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5116 [1];;
        goto l5170 [1];;
        l5128:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5082 [1];;
        goto l5170 [1];;
        l5129:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5073 [1];;
        goto l5170 [1];;
        l5130:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5121 [1];;
        goto l5170 [1];;
        l5131:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5120 [1];;
        goto l5170 [1];;
        l5132:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5152 [1];;
        goto l5170 [1];;
        l5133:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'c') goto l5169 [1];;
        goto l5170 [1];;
        l5134:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5137 [1];;
        goto l5170 [1];;
        l5135:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5028 [1];;
        goto l5170 [1];;
        l5136:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5016 [1];;
        goto l5170 [1];;
        l5137:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5021 [1];;
        goto l5170 [1];;
        l5138:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5021 [1];;
        goto l5170 [1];;
        l5139:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5070 [1];;
        goto l5170 [1];;
        l5140:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5034 [1];;
        goto l5170 [1];;
        l5141:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5130 [1];;
        goto l5170 [1];;
        l5142:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5079 [1];;
        goto l5170 [1];;
        l5143:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5145 [1];;
        goto l5170 [1];;
        l5144:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5112 [1];;
        goto l5170 [1];;
        l5145:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5113 [1];;
        goto l5170 [1];;
        l5146:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5045 [1];;
        goto l5170 [1];;
        l5147:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5161 [1];;
        goto l5170 [1];;
        l5148:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5126 [1];;
        goto l5170 [1];;
        l5149:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5105 [1];;
        goto l5170 [1];;
        l5150:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 't') goto l5128 [1];;
        goto l5170 [1];;
        l5151:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5100 [1];;
        goto l5170 [1];;
        l5152:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5125 [1];;
        goto l5170 [1];;
        l5153:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5148 [1];;
        goto l5170 [1];;
        l5154:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5153 [1];;
        goto l5170 [1];;
        l5155:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5117 [1];;
        goto l5170 [1];;
        l5156:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5142 [1];;
        goto l5170 [1];;
        l5157:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5089 [1];;
        goto l5170 [1];;
        l5158:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5069 [1];;
        goto l5170 [1];;
        l5159:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'e') goto l5040 [1];;
        goto l5170 [1];;
        l5160:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5150 [1];;
        goto l5170 [1];;
        l5161:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5144 [1];;
        goto l5170 [1];;
        l5162:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5070 [1];;
        goto l5170 [1];;
        l5163:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'b') goto l5165 [1];;
        goto l5170 [1];;
        l5164:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'i') goto l5133 [1];;
        goto l5170 [1];;
        l5165:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'l') goto l5164 [1];;
        goto l5170 [1];;
        l5166:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'o') goto l5124 [1];;
        goto l5170 [1];;
        l5167:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'r') goto l5149 [1];;
        goto l5170 [1];;
        l5168:
          DEFAULT;
        when (curPos >= text.Length) goto l5170 [1];;
        c = text[curPos];
        ++curPos;
        when (c == 'a') goto l5115 [1];;
        goto l5170 [1];;
        l5169:
          DEFAULT;
        okPos = curPos;
        l5170:
          DEFAULT;
        okPos
      };
      if (pos >= 0) 
      {
        def newPos = __GENERATED_PEG__RULE__identifierPartCharacters__(pos, text);
        if (newPos < 0) pos; else -1
      }; else -1
    }
  }
}


EOH>Я не считаю, что введение нового языка программирования ради сокращения кода при написании стоит того, чтобы увольнение / найм людей постоянно давали проблемы.
Вот скажи мне чем ДСЛ отличается от библиотеки?

EOH>Посмотрите в сетевой стек FreeBSD — там как раз собственны DSL на базе C. Это НЕВОЗМОЖНО ни читать, ни поддерживать.

ДСЛ на базе С это бред сивой кобылы. С для содания ДСЛ не предназначен.

EOH> Хотя писалось, наверное, быстро. Лично я не хочу тратить лишние 2-3 недели на то, чтобы разработчик ознакомился с дополнительным парком велосипедов. Мне и существующих хватает.

Там какая разница будет он библиотеки учить или новый синтакс?

EOH>Согласен. Но сделать хороший DSL — трудно. Поэтому лучше не злоупотреблять. Генерить биндинги — это клево. Но вот писать на собственном синтаксисе ядро программы — это может очень болезненно отразиться в будущем.

А ты пробовал? Или умозрительные заключения?

EOH>

Разве никто не здесь не допускает возможности того, что сложность реализации "синтаксиса" эквивалентна написанию библиотеки, а удобство использования в определенных случаях может быть значительно выше?


EOH>Именно поэтому я ратую за использование стандартных библиотек. Вот такой я ретроград ^_^.
Почему "по этому"? Ведь свой синтаксис не редко бывает куда лучше библитеки.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Ziaw Россия  
Дата: 03.02.11 20:07
Оценка:
Здравствуйте, Chrome, Вы писали:

C>2 человеко месяца — не выглядит сколь нибудь серьезным ресурсом.


Не два человеко месяца, а два месяца свободного времени hardcase которое он мог уделить парсеру.

C>меня собственно и заинтересовало — неужели реально с такой скоростью клепать языки?


На самом деле нет. Так легко получилось потому, что nemerle является надмножеством шарпа. Поэтому достаточно было сделать парсер, который выдает AST nemerle почти один в один. F# в принципе тоже должен лечь на nemerle, только кому это надо? Тем более неинтересно изобретать свое подмножество nemerle.

Для клепания своего языка сначала нужно очень очень много работать надо его дизайном и синтаксисом. На самом деле рулят не новые языки, а встроенные DSL, код на которых читается так, как хочется, чтобы он читался.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 02:29
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Владислав, вы меня пугаете O_O. Ну давайте померяемся, мне не жалко. У меня больше 10 лет в коммерческой разработке, из крупных проектов в которых участвовал — например, Radmin. Делал много кодегенерации и DSL: XSLT, TT, lisp, python. Последние несколько лет — Ruby. того достаточно, чтобы считать меня знакомым с проблемой практически?


Достаточно, если опыт программирования на Лиспе был серьезным. Остальные средства могут соформировать не верные представления, так как синтаксических макросов в них нет и манипуляция кодом идет на уровне строк. А это действительно создает проблемы.

EOH>Если угостите кофе — могу зайти в гости, убедитесь в моей квалификации лично .


Если есть желание зайти, познакомиться, то я не буду против.

EOH>Поддержка DSL — плевое дело, пока рядом есть автор. А вот если автор йок, то с DSL очень большие проблемы.


А вот с этим я согласиться никак не могу. Точнее я не согласен, что это проблема ДСЛ-ей.
Конечно если кто-то в одиночку написал большой кусок кода и свалил, то проблемы с поддержкой неизбежны (особенно, если код хреновый и документации на него нет).
Но в случае библиотеки функций или классов будет тоже самое. Даже будет все хуже, так как объем кода который надо будет поддерживать будет больше, ведь это будет не только код библиотеки, но и распухший и кривой прикладной код.

EOH>

> Соответственно, это не так популярно потому как компании хотят защититься от эффекта падающего кирпича.
EOH>Можно описание этого эффекта?


EOH>Это когда на голову ведущему разработчику падает кирпич с летальными последствиями .


Во-во. Следствие выведенное из мифа.

EOH>Есть некая разница между широко распространенным DSL типа rake и тем, что мы сделали сами, нэ?


Не. Никакой, если их приходится поддерживать самостоятельно.

EOH>Если Вы считаете, что в DSL прямо вот так легко разобраться — возьмити любой проект Ruby on Rails и загляните внутрь. Будете приятно удивлены лаконичности кода и полным непонимаем как "это" работает "внутри". И это еще популярный DSL. А если кто такое сам напишет?


Во-во. Берем язык с недометапрограммированием и делаем на его базе далеко идущие выводы.
Я вот могу взять за основу аналог — Nemerle on Rails. В его коде я разберусь без труда (хотя и не причастен к его разработке) и смогу поддерживать и развивать его.

Так что возможность поддерживать чужой код зависит не от того является ли он реализацией ДСЛ-я, а от того насколько качественно он спроектирован и реализован, и от того какими средствами он создан.

Я вот вижу совершенно конкретные факты. Люди без огромного опыта в Nemerle правят макросы написанные за долго до того как они познакомились с языком. Может быть они от природы талантливее, но думаю что дело в другом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 04:03
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Если для функции есть intellisense, F1, Goto Definition, то для новых конструкций языка всего этого нет.


Теоретик! Скачал бы поглядел что обсуждаешь. Обнаружил бы много интересного. Например, тот же интеллисенс для макросов.

G>Кроме того затрудняется командная разработка. Конфликты имен функций\классов решаются неймспейсами. Как разрешать конфликт расширений синтаксиса?


Не поверишь! Нэймспэйсами!

Синтаксис подключается пространствами имен. Так что несовместимые синтаксические макросы можно использовать в разных модулях. Кроме того любой макрос можно использовать без синтаксиса. Тогда его применение в коде будет выглядеть как вызов функции или как кастом-атрибут.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 04:09
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>А кто мешает в рантайме переписывать?

WH>>И машинный код сгенерировать,... и получишь ты макросы немерла вид в профиль.
G>Когда в руках молоток — все вокруг кажется гвоздями.

Ага. А когда и молотка не видел, то остается только выдумывать страшилки о разрушительной силе молотков .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Предлагаю обсудить в таком ключе
От: Ziaw Россия  
Дата: 04.02.11 07:30
Оценка:
Здравствуйте, Wolverrum, Вы писали:

W>Здравствуйте, Chrome, Вы писали:


W>Давайте условимся,

W>что из нижеперечисленных продуктов:
W>- Lisp
Достаточно взлетел, как язык для обкатки концепций и идей других языков.
W>- JetBrains MPS
Внешний DSL это не то, что вообще могло взлететь.
W>- Template Haskell
Не в курсе.
W>- Nemerle

Не взлетел, но язык еще очень молод. Последние годы постепенно взлетают питон и руби, которым 30 и 17 лет. Надо быть отмороженным оптимистом, надеясь завоевать рынок с языком 7 лет от роду.

Nemerle в принципе можно сравнить с boo, который того же возраста, гораздо слабее но вполне применяем для своей ниши.

Nemerle, в отличии от boo разрабатывался неанглоязычными командами (поляки и русские). Поэтому очень мало англоязычных ресурсов по нему, отсюда гораздо меньшая известность.

Есть и еще серьезная причина, nemerle некоторое время был фактически заброшен, главные разработчики ушли в майрософт и гугл, в их университете подхватить язык оказалось некому. Для всего мира это выглядело как смерть проекта. Некоторое время он действительно балансировал между жизнью и смертью, но теперь у него снова есть команда и комьюнити. Большое, человеческое, спасибо за это Владу.

Фактически язык только только вышел из лаборатории, его главная заслуга в исторической перспективе — он дает возможность написать nemerle2 за приемлемое время. Ну и комьюнити постепенно набирается, язык-то уже можно щупать без шаманства. Если наберется критическая масса — инфы в интернете станет навалом, тогда рост комьюнити уже не остановить.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 04.02.11 10:46
Оценка: +1

Тебе что проще читать вот это:
<задание грамматики через PEG>
Или вот это (Я не в состоянии это ни прочитать ни написать):
<парсер грамматики, сгенерированный lex/yacc>


Какое отношение это имеет к обсуждаемому вопросу?

>>Я не считаю, что введение нового языка программирования ради сокращения кода при написании стоит того, чтобы увольнение / найм людей постоянно давали проблемы.
Вот скажи мне чем ДСЛ отличается от библиотеки?


DSL — он специфичен для проекта. Библиотека — готовая и хорошо документированная. Boost, например.

>> Хотя писалось, наверное, быстро. Лично я не хочу тратить лишние 2-3 недели на то, чтобы разработчик ознакомился с дополнительным парком велосипедов. Мне и существующих хватает.
Там какая разница будет он библиотеки учить или новый синтакс?


А надо стандартные библиотеки использовать. Qt, boost, openssl и прочее. Которое программист либо уже знает либо бысро изучет по книжке/статье в блоге. Про свой DSL книжки и статьи писать — тяжко.

>>Согласен. Но сделать хороший DSL — трудно. Поэтому лучше не злоупотреблять. Генерить биндинги — это клево. Но вот писать на собственном синтаксисе ядро программы — это может очень болезненно отразиться в будущем.
А ты пробовал? Или умозрительные заключения?


См. в этой же ветке. Пробовал и не один год. И то и другое.

>>Именно поэтому я ратую за использование стандартных библиотек. Вот такой я ретроград ^_^.
Почему "по этому"? Ведь свой синтаксис не редко бывает куда лучше библитеки.


Потому что холодильник . См. на что я отвечал.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 04.02.11 10:50
Оценка:

>> Я знаю С++, но покажи мне программу на Qt — с ходу не разберусь. А почему? Qt не знаю.
> Вы не поверите — но даже те жалкие крохи с сигналами и foreach в Qt доставляют
> огромные проблемы огромному количеству программистов. А теперь представьте себе,
> что будет если налево и направо использовать полноценные DSL? .

А аналогичные проекты но на MFC,WTL, или голом WinAPI, те же самые программисты быстрее пишут, поддерживают, баги находят (производительность выше)?


Люблю, когда один человек спрашивает, второй отвечает, а третий отвечает на ответ второго не посмотрев на вопрос первого Разговор был не о том, быстрее или медленнее ли они пишут, а о том что смогут они понять код или нет. Скорость написания — параметр важный, но не всегда главный. Поддержка она тоже как бы популярна.

Хотя и в MFC есть метапрограммирование(жуткие макросы), да и WTL ... С голым WinAPI,C++ наверно надо сравнивать.


И человек, который знает MFC сможет их понять. Соответственно, мне достаточно в вакансии указать "знание MFC". А если у меня для того же собственный DSL — представьте себе затраты на ознакомление с ним программистов.

Я не в курсе что там в QT. Переборщили со средствами сокращения кода?


Нет, просто ввели пару архитектурных концепций: асинхронные мультикаст делегаты и иерархию дочерних объектов.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 04.02.11 11:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Достаточно, если опыт программирования на Лиспе был серьезным. Остальные средства могут соформировать не верные представления, так как синтаксических макросов в них нет и манипуляция кодом идет на уровне строк. А это действительно создает проблемы.


В питоне и руби метаклассы и декораторы (питон) никак ни манипулирование строками.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 04.02.11 11:11
Оценка:

Достаточно, если опыт программирования на Лиспе был серьезным. Остальные средства могут соформировать не верные представления, так как синтаксических макросов в них нет и манипуляция кодом идет на уровне строк. А это действительно создает проблемы.


То есть как DSL делается на Ruby вам не нравится только потому, что LISP кроме всего прочего может модифицировать свой код? Ruby, между прочим, специально для DSL затачивалось и там есть много качественного синтаксического сахара.

Если угостите кофе — могу зайти в гости, убедитесь в моей квалификации лично .
>>Если есть желание зайти, познакомиться, то я не буду против.


grigory.v.p@gmail.com

>>Поддержка DSL — плевое дело, пока рядом есть автор. А вот если автор йок, то с DSL очень большие проблемы.
VD>А вот с этим я согласиться никак не могу. Точнее я не согласен, что это проблема ДСЛ-ей.
VD>Конечно если кто-то в одиночку написал большой кусок кода и свалил, то проблемы с поддержкой
VD>неизбежны (особенно, если код хреновый и документации на него нет).


Но в случае библиотеки функций или классов будет тоже самое.


Нет, если мы используем стандартные библиотеки типа boost, qt, gtk, openssl, pango итд. По ним есть книги, статьи, куча блогов. Знание библиотеки можно прописать в вакансии.

Даже будет все хуже, так как объем кода который надо будет поддерживать будет больше, ведь это будет не только код библиотеки, но и распухший и кривой прикладной код.


Код библиотеки поддерживать не надо, если она стандартная. Я — за стандартные библиотеки и против велосипедов ^_^.

Это когда на голову ведущему разработчику падает кирпич с летальными последствиями .
VD>Во-во. Следствие выведенное из мифа.


А я рассматриваю все в реальнй жизни. Реальные проекты — это не идеально документированные системы, на 100% покрытые юнит тестами и выглядящие как набор тасков и связанных с ними хорошо документированных коммитов. В реальной жизни все не так хорошо. И если уходит архитектор, который использовал Qt — то человек, знающий Qt разберется в его кода. А если человек сделал свой DSL — то это йок.

EOH>>Есть некая разница между широко распространенным DSL типа rake и тем, что мы сделали сами, нэ?
VD>Не. Никакой, если их приходится поддерживать самостоятельно.


В том-то и дело, что нам не надо поддерживать самостоятельно популярную библиотеку — за нас это делают другие.

EOH>>Если Вы считаете, что в DSL прямо вот так легко разобраться — возьмити любой проект Ruby on Rails и загляните внутрь. Будете приятно удивлены лаконичности кода и полным непонимаем как "это" работает "внутри". И это еще популярный DSL. А если кто такое сам напишет?
VD>Во-во. Берем язык с недометапрограммированием и делаем на его базе далеко идущие выводы.
VD>Я вот могу взять за основу аналог — Nemerle on Rails. В его коде я разберусь без труда (хотя и не причастен к его разработке) и смогу поддерживать и развивать его.


Я беру его как образец популярного использования концепции DSL. И чем Вам в руби программирование не мета?

VD>Я вот вижу совершенно конкретные факты. Люди без огромного опыта в Nemerle правят макросы написанные за долго до того как они познакомились с языком. Может быть они от природы талантливее, но думаю что дело в другом.


Немерле пока не смотрел. Но мы же говорим про DSL вообще, а не про особо удачную реализацию концепции метапрограммирования? В реальной жизни DSL чаще делают на t4, чем на немерле, увы
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 04.02.11 12:27
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>И человек, который знает MFC сможет их понять. Соответственно, мне достаточно в вакансии указать "знание MFC". А если у меня для того же собственный DSL — представьте себе затраты на ознакомление с ним программистов.


Поддерживаю.
В конторе используется продукт, с помощью которого производится разработка. Продукт использует собственный язык, основанный на Яве.
Продукт очень известный в узких кругах. Были доступны обучающие материалы. Есть комьюнити, форумы и прочее, следовательно, можно было узнать о "лучших практиках" и т.п.
Следовательно, если человек не крутился в этих кругах, то максимум, что он может знать — только Яву.
Большинство новичков приходилось обучать языку. Пусть и непродолжительное время.
Но какой-то процент новичков уже был знаком с языком.

В случае же "языка для проекта" новичков надо будет учить всегда и обязательно.
Вселенная бесконечна как вширь, так и вглубь.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 04.02.11 14:01
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Какое отношение это имеет к обсуждаемому вопросу?

Наипрямейшее.
Грамматика ПЕГ это ДСЛ. В случае с немерле это встроенный ДСЛ. Nemerle.Peg называется.
Тот код что был сгенерирован пришлось бы писать руками.
Поддерживать сгенерированный код не реально.
При этом люди умудряются править исходники самого Nemerle.Peg.

EOH>DSL — он специфичен для проекта. Библиотека — готовая и хорошо документированная. Boost, например.

Ты что ни разу не видел библиотек специфичных для проекта?
Или ты хочешь сказать что не может быть ДСЛ готового и хорошо документированного?
http://www.rsdn.ru/article/nemerle/PegGrammar.xml
Автор(ы): Чистяков Владислав Юрьевич
Дата: 07.06.2011
Макрос PegGrammar – это макрос Nemerle, позволяющий добавлять в приложения парсеры, описываемые в нотации PEG.


EOH>А надо стандартные библиотеки использовать. Qt, boost, openssl и прочее. Которое программист либо уже знает либо бысро изучет по книжке/статье в блоге. Про свой DSL книжки и статьи писать — тяжко.

Так а если нет стандартной библиотеки которая делает то что нужно?
Или есть но все доступные варианты говно? Скажем я так и не смог найти библиотеку для обработки растровых изображений которая бы не портила изображения.
Пришлось писать самому.

EOH>См. в этой же ветке. Пробовал и не один год. И то и другое.

Может ты както не правильно пробовал? Или использовал не правильные инструменты?
Просто я никаких проблем не вижу.

EOH>

>>Именно поэтому я ратую за использование стандартных библиотек. Вот такой я ретроград ^_^.
EOH>Почему "по этому"? Ведь свой синтаксис не редко бывает куда лучше библитеки.

EOH>Потому что холодильник . См. на что я отвечал.
Я то как раз посмотрел. А ты?

Разве никто не здесь не допускает возможности того, что сложность реализации "синтаксиса" эквивалентна написанию библиотеки, а удобство использования в определенных случаях может быть значительно выше?

Тут говорится о том что затраты на разработку библиотеки и новый синтакс примерно равны, а приемущества синтаксиса значительны.
Так по чемуже ты за использование библиотек?
Вот только не надо гнать про "стандартные библиотеки".
Ибо:
1)Могут быть стандартные ДСЛ (см выше).
2)Стандартных библиотек может и не быть.

Кстати. Пожалуйста используй метод цитирования принятый на RSDN. Это я тебя как модератор прошу.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 04.02.11 14:03
Оценка: +1
Здравствуйте, Real 3L0, Вы писали:

R3>В случае же "языка для проекта" новичков надо будет учить всегда и обязательно.

А что архитектуре проекта новичков обучать не нужно? А специфичные для проекта библиотеки они тоже знают?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Способно ли метапрограммирование заменить отдельные
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 04.02.11 15:14
Оценка:
Здравствуйте, WolfHound, Вы писали:

R3>>В случае же "языка для проекта" новичков надо будет учить всегда и обязательно.

WH>А что архитектуре проекта новичков обучать не нужно?

Это — в любом проекте: что на самописном языке, что на общеизвестном.

WH> А специфичные для проекта библиотеки они тоже знают?


Самописный язык 100% избавляет от специфичных библиотек? Т.е. при написании языка заодно напишете все существующие и необходимые специфичные библиотеки?
Вселенная бесконечна как вширь, так и вглубь.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 04.02.11 15:18
Оценка:

А что архитектуре проекта новичков обучать не нужно? А специфичные для проекта библиотеки они тоже знают?


Нужно. И этого я тоже стараюсь избегать использую стандартные дизайн, архитектуру и уменьшая количество специфичных библиотек. В разумных пределах конечно. Чего я хочу, это избежать ситуацию когда программист открывает файл проекта и единственная реакция: "А-а-а-а-а-а-а-а! Что ЭТО?!?" .
Re[11]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 04.02.11 15:22
Оценка: 47 (1) +3
Здравствуйте, Real 3L0, Вы писали:

R3>Самописный язык 100% избавляет от специфичных библиотек? Т.е. при написании языка заодно напишете все существующие и необходимые специфичные библиотеки?

Нет. Но уменьшает их колличество и разобраться в ДСЛ _проще_ чем в библиотеке которая делат тоже самое (причем делает это она значительно хуже и намного многословнее).
Я говорю конечно про разумных людей которые заводят ДСЛ только тогда когда он дает серьезные преимущества перед библиотекой.

Короче мой поинт в том что высказанное здесь мнение что ДСЛ поднимают порог вхождения новых людей в проект не верно.
Разумно примененный ДСЛ снижает порог вхождения по сравнению с другими методами решения задачи.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 04.02.11 15:27
Оценка:

EOH>>Какое отношение это имеет к обсуждаемому вопросу?
WH>Наипрямейшее.
WH>Грамматика ПЕГ это ДСЛ. В случае с немерле это встроенный ДСЛ. Nemerle.Peg называется.
WH>Тот код что был сгенерирован пришлось бы писать руками.
WH>Поддерживать сгенерированный код не реально.
WH>При этом люди умудряются править исходники самого Nemerle.Peg.


PEG — это СТАНДАРТНЫЙ DSL. Так же как Regexp. Если у меня в проекте много PEG — то я просто пишу в вакансии: "Знанание PEG". Ну или там Antlr. А автор топика настаивал на добавлении в язык СОБСТВЕННОГО DSL. Согласитесь, разные вещи — Antlr, по которому есть книга и никому неизвестное расширение Java от компании Рога и Копыта, которое поддерживает кучу специфических для них вещей. Плюс еще криво, косо, архитектурно нецелостно, без нормальной документации, with bugs и автор которой уволился два года назад потому что уехал в Китай поступать в монастырь.

WH>Ты что ни разу не видел библиотек специфичных для проекта?
WH>Или ты хочешь сказать что не может быть ДСЛ готового и хорошо документированного?
WH>http://www.rsdn.ru/article/nemerle/PegGrammar.xml


Видел конечно. И я за то, чтобы их не множить без необходимости. На мой взгляд введение DSL — это множить такие проектно-специфические вещи без необходимости.

EOH>>А надо стандартные библиотеки использовать. Qt, boost, openssl и прочее. Которое программист либо уже знает либо бысро изучет по книжке/статье в блоге. Про свой DSL книжки и статьи писать — тяжко.
WH> Так а если нет стандартной библиотеки которая делает то что нужно?
WH>Или есть но все доступные варианты говно? Скажем я так и не смог найти библиотеку для обработки растровых изображений которая бы не портила изображения.


Ну понятное дело что если надо, то надо. Но автор то за легкое добавление собственных расширений языка! У вас ведь библиотека не на собственном языке написана небось?

EOH>>См. в этой же ветке. Пробовал и не один год. И то и другое.
WH>Может ты както не правильно пробовал? Или использовал не правильные инструменты?
WH>Просто я никаких проблем не вижу.


Может быть. Я просто достаточно давно в отрасли, видел что случается с разными решениями когда меняются поколения разработчиков и авторы покидают компанию. Чем проще код — чем лучше он переживает ротацию кадров.

WH>Тут говорится о том что затраты на разработку библиотеки и новый синтакс примерно равны, а приемущества синтаксиса значительны.
WH>Так по чемуже ты за использование библиотек?
WH>Вот только не надо гнать про "стандартные библиотеки".
WH>Ибо:
WH>1)Могут быть стандартные ДСЛ (см выше).
WH>2)Стандартных библиотек может и не быть.


Я за стандартные DSL. Если можно написать библиотеку или DSL то я за библиотеку, потому что она проще в понимании для человека, знающего язык и экосистему, на основе которых она написана. Это как бы мое ИМХО после многолетнего общения с DSL и кодогенерацией. Понять как работает SVN API проще, чем разобраться как работает Rails и поменять там что-то внутри при отсутствии доступа к автору.

Кстати. Пожалуйста используй метод цитирования принятый на RSDN. Это я тебя как модератор прошу.


А разве тэг "q" не для этого? O_O. Где можно про правила цитирования почитать?
Re[11]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 04.02.11 15:36
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

WH>>А что архитектуре проекта новичков обучать не нужно? А специфичные для проекта библиотеки они тоже знают?

EOH>Нужно. И этого я тоже стараюсь избегать использую стандартные дизайн, архитектуру и
Стандартную архитектуру? Это какую?
Только давай чтобы она подошла для компилятора, фотошапа, ядра ОС, прошивки микроконтроллера, гуглопоиска,...

EOH>уменьшая количество специфичных библиотек.

Я тоже против велосипедов но жизнь такова что иногда приходится их изобретать.

EOH>В разумных пределах конечно. Чего я хочу, это избежать ситуацию когда программист открывает файл проекта и единственная реакция: "А-а-а-а-а-а-а-а! Что ЭТО?!?" .

А я хочу избежать ситуации когда человек вместо файлика на десяток другой килобайт видит мегабайт исходников.
Это вполене реальное отношение Грамматика C# и его препроцессора занимают 44 138 байт.
Сгенерированный код распечатанный преттипринтом занимает 2 334 568 байт.
Ты можешь говорить что хочешь но разобраться с грамматикой на ПЕГе минимум на два порядка проще чем с тем кодом который из нее получается.
Просто по тому что кода на два порядка меньше.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 04.02.11 15:54
Оценка: +1
Здравствуйте, Eye of Hell, Вы писали:

EOH>PEG — это СТАНДАРТНЫЙ DSL.

Когда я его писал он небыл стандартным.
Хотя признание того что ДСЛ может быть стандартным уже большой шаг вперед.

EOH>Так же как Regexp.

Люди в соседних флеймах с тобой яростно не согласяться.

EOH>Если у меня в проекте много PEG — то я просто пишу в вакансии: "Знанание PEG". Ну или там Antlr. А автор топика настаивал на добавлении в язык СОБСТВЕННОГО DSL. Согласитесь, разные вещи — Antlr, по которому есть книга и никому неизвестное расширение Java от компании Рога и Копыта, которое поддерживает кучу специфических для них вещей. Плюс еще криво, косо, архитектурно нецелостно, без нормальной документации, with bugs и автор которой уволился два года назад потому что уехал в Китай поступать в монастырь.

И чем это отличается от библиотеки?
То что ДСЛ можно сделать плохо не означает что его нельзя сделать хорошо.

EOH>Видел конечно. И я за то, чтобы их не множить без необходимости. На мой взгляд введение DSL — это множить такие проектно-специфические вещи без необходимости.

Поправка: Введение ДСЛ без необходимости.
А если ДСЛ значительно уменьшает объем работы то как ни крути, а необходимость на лицо.

EOH>Ну понятное дело что если надо, то надо.

Уже прогресс.

EOH>Но автор то за легкое добавление собственных расширений языка!

Естественно за легкое. Ктож будет расширять язык если его тяжело расширять?

EOH>У вас ведь библиотека не на собственном языке написана небось?

Если ты про библиотеку обработки изоражений то там есть кодогенератор.
Нужно было сгенерировать некоторое колличество говнокода по очень сложным правилам.

В любом случае нет разници между ДСЛ и библиотекой.

EOH>Может быть. Я просто достаточно давно в отрасли, видел что случается с разными решениями когда меняются поколения разработчиков и авторы покидают компанию. Чем проще код — чем лучше он переживает ротацию кадров.

Полностью согласен.
А код на правильном ДСЛ значительно проще.

EOH>Я за стандартные DSL. Если можно написать библиотеку или DSL то я за библиотеку, потому что она проще в понимании для человека, знающего язык и экосистему, на основе которых она написана. Это как бы мое ИМХО после многолетнего общения с DSL и кодогенерацией.

+100
Тебе осталось признать две вещи:
1)Иногда стандартных инструментов просто нет.
2)Иногда ДСЛ значительно проще библиотеки.

EOH>Понять как работает SVN API проще, чем разобраться как работает Rails и поменять там что-то внутри при отсутствии доступа к автору.

Не стои сравнивать не сравнимое.
Ты сравни грамматику ПЕГ и тот код который из нее получается...

EOH>А разве тэг "q" не для этого? O_O.

Она для втыканя левых цитат.

EOH>Где можно про правила цитирования почитать?

В почти 100% сообщений на форуме.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 17:08
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Чот, Влад, путаешься местами в последнее время. Поясни мне, как mutable словари процессов (которые, насколько я понимаю, используются реже чем unsafe на платформе, под которую ты пишешь) стали вдруг глобальными? Ну не надо так-то уж явно


А что же они локальными вдруг стали? Это тот самый mutable state о вреде которого поют все поклонники ФП. У нас больше нет функций которые берут на входе значение и возвращают другое. Значение может зависеть от состояния словаря.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 17:13
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Меня — может быть. Но как team lead я еще должен заботиться о тех, кто этот код будет поддерживать в будующем.


Твоя ошибка заключается в том, что ты путаешь "проще" в смысле программного решения и "проще" в смысле проще жить HR-отделу. Поэтому считаю что чем проще — тем лучше.

EOH>И стараюсь выбрать разумные рамки. Активное использование DSL на мой взгляд за рамки выходит.


Из твоей позиции проистекает, что на работу надо брать только индусов (по развитию и образу мысли), так как их всегда будет легко найти. Ведь если взять на роботу не заурядную личность, и с ним случится (как ты мам его называл?) эффект кирпича, то найти другую незаурядную личность будет сложно.

Так можно писать только совсем примитивный софт. И все равно качество его будет очень низким.
Ну, а для сложных задач нужны сложные инструменты и хорошие специалисты. Их выбор конечно риск в некотором смысле, но по другому сложные задачи не решаются.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: Курилка Россия http://kirya.narod.ru/
Дата: 04.02.11 17:28
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Курилка, Вы писали:


К>>Чот, Влад, путаешься местами в последнее время. Поясни мне, как mutable словари процессов (которые, насколько я понимаю, используются реже чем unsafe на платформе, под которую ты пишешь) стали вдруг глобальными? Ну не надо так-то уж явно


VD>А что же они локальными вдруг стали? Это тот самый mutable state о вреде которого поют все поклонники ФП. У нас больше нет функций которые берут на входе значение и возвращают другое. Значение может зависеть от состояния словаря.


Ты удивишься, но в Эрланге гораздо больше функций, возвращающих разные значения на одно и то же входное, и без всяких словарей, ибо есть передача сообщений и взаимодействие с "внешнимим" (по отношению к Эрлангу) миром, видимо по твоей терминологии это тоже глобальные переменные.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 04.02.11 19:16
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Нужно. И этого я тоже стараюсь избегать использую стандартные дизайн, архитектуру и уменьшая количество специфичных библиотек. В разумных пределах конечно. Чего я хочу, это избежать ситуацию когда программист открывает файл проекта и единственная реакция: "А-а-а-а-а-а-а-а! Что ЭТО?!?" .


Не знаю, хорошо ли это

Недавний пример с переходом на FW 4.0. Единственная реакция при переходе на новый ASP была как раз: "А-а-а-а-а-а-а-а! Что ЭТО?!?". Поплыл рендеринг контролов, изменилась модель секьюрити и изменилась логика обработки HTTP реквеста.
Зато наши доморощенные быблиотечки как жужжали, так и жужжат.

В общем, очередной притянутый за уши аргумент.
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 04.02.11 19:22
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Короче мой поинт в том что высказанное здесь мнение что ДСЛ поднимают порог вхождения новых людей в проект не верно.

WH>Разумно примененный ДСЛ снижает порог вхождения по сравнению с другими методами решения задачи.

Порог вхождения, конечно же, возрастает. Всё же надо что-то изучить против ничего не изучать. Но это окупается тем, что не приходится копаться в горах императивщины, где за деревьями леса не видно. Работать приходится в основном с логикой, описанной декларативно. А как известно, декларация как раз и есть тот самый идеал, к которому нужно стремиться.
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 04.02.11 19:24
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Чем проще код — чем лучше он переживает ротацию кадров.


Что в данном случае подразумевается под "проще"?
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:24
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>

Тебе что проще читать вот это:
EOH><задание грамматики через PEG>
EOH>Или вот это (Я не в состоянии это ни прочитать ни написать):
EOH><парсер грамматики, сгенерированный lex/yacc>


EOH>Какое отношение это имеет к обсуждаемому вопросу?


Вообще-то прямое. Приведенный код как раз макросом и сгенерирован.
Если его переписать "на библиотеках", то все равно получишь кашу. При этом эта каша еще и работать будет медленнее.

И так будет с любым мало-мальски сложным ДСЛ-ем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:30
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>А ты пробовал? Или умозрительные заключения?[/q]


EOH>См. в этой же ветке. Пробовал и не один год. И то и другое.


Смотри как интересно получается... У меня, вольфхаунда, зива, хардкейса и тебя есть опыт работы с ДСЛ-ями. Но у тебя он отрицательный, а у остальных перечисленных — положительный. Тебя это не наталкивает на мысль, что может быть дело не в подходе, а в чем-то другом? Может в тебе или используемых тобой инструментах?

Мне кажется над этим стоит задуматься.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 04.02.11 19:34
Оценка:
Здравствуйте, IT, Вы писали:

IT>Порог вхождения, конечно же, возрастает. Всё же надо что-то изучить против ничего не изучать.

А что библиотеку изучать не надо?
Чем изучание библиотеки отличается от изучения ДСЛ?

IT>Но это окупается тем, что не приходится копаться в горах императивщины, где за деревьями леса не видно. Работать приходится в основном с логикой, описанной декларативно. А как известно, декларация как раз и есть тот самый идеал, к которому нужно стремиться.

+100
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:40
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>PEG — это СТАНДАРТНЫЙ DSL. Так же как Regexp. Если у меня в проекте много PEG — то я просто пишу в вакансии: "Знанание PEG". Ну или там Antlr. А автор топика настаивал на добавлении в язык СОБСТВЕННОГО DSL. Согласитесь, разные вещи — Antlr, по которому есть книга и никому неизвестное расширение Java от компании Рога и Копыта, которое поддерживает кучу специфических для них вещей. Плюс еще криво, косо, архитектурно нецелостно, без нормальной документации, with bugs и автор которой уволился два года назад потому что уехал в Китай поступать в монастырь.


На мой взгляд твоя позиция развалилась в пух и прах.

Вот суди сам. Ты изначально заявлял, что проблемой является не примеение ДСЛ-я, а поддержка МП кода. Я правильно тебя понял?

Но нет никакой стандартной реализации PEG-а которую можно было бы требовать в резюме. PEG — это всего лишь общие мысли на тему языка описывающего парсер. А его реализация может быть любой (и есть их не мало).

Стало быть если кто-то в рамках твоего проекта или даже отдельно сделает реализацию PEG-а, то ты будешь зависеть от нее на 100%. И нанимая кого-то поддерживать эту реализацию ты точно так же будешь не в состоянии взять кого-то со стороны.

При этом использовать сам PEG очень просто. Даже если ты его не знаешь, то изучить его можно где-то за неделю. Изучив его разобраться в проекте в котором он использован будет в сто раз проще, нежели в проекте где используются "библиотеки", так как под красивым термином "библиотеки" скрывается голимый рукописный код парсеров. На его изучение надо будет убить далеко не одну неделю. Получается, что экономя неделю на изучение DSL-я мы теряем месяцы на изучение всего проекта, коды на его поддержку, так как изменять декларативный ДСЛ в сто раз проще нежели рукописный код.

И совершенно по фигу стандартен ли PEG как язык. Ведь на его изучение тратится копеечное время (по сравнению с временем затрачиваемым на изучение проекта где он используется).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:45
Оценка:
Здравствуйте, WolfHound, Вы писали:

EOH>>Может быть. Я просто достаточно давно в отрасли, видел что случается с разными решениями когда меняются поколения разработчиков и авторы покидают компанию. Чем проще код — чем лучше он переживает ротацию кадров.

WH>Полностью согласен.
WH>А код на правильном ДСЛ значительно проще.

Ага. Вот это пожалуй ключевой момент!

Несомненно говнокод и ошибки в архитектуре являются первопричиной большинства проблем в области разработки ПО.
Несомненно, что ДСЛ является ответственным шагом и его не стоит сувать во все дыры, так как херово спроектированный или реализованный ДСЛ будет тем же самым говнокодом. Но если ДСЛ применен по месту, спроектирован грамотно и качественно реализован, то ПО созданное с его помощью (и его самого) будет поддерживать намного проще нежели то же ПО сделанное в лоб (без применения ДСЛ-я).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:47
Оценка:
Здравствуйте, 0x7be, Вы писали:

EOH>>Не-е-е-е, тут, ИМХО, мы не создаем свой язык — мы создаем абстракции на базе известного программистам языка/технологии. Если у меня архитектура actor model на Qt, то знающий C++ и Qt человек ее поймет, потому что все примитивы и приемы кодирования ему известны. А вот если я под эту actor model наваяю собственный синтаксис, который уменьшит количество моего кода в пару-тройку раз, то с этим синтаксисом новому человеку будет разобраться намного сложнее. А уж поменять что-нибудь — большой проблемой.

0>Не согласен. Взять тот же Qt — это своего рода язык, который надо отдельно изучать. Я знаю С++, но покажи мне программу на Qt — с ходу не разберусь. А почему? Qt не знаю.

А если тебе показать огромное ГУИ-приложение без Qt (и других библиотек) и написанное еще не самым лучшим образом, то ты разберешься в нем быстрее?

Может лучше изучить этот самый Qt и потом уже разобраться в приложении которое будет в разы проще из-за его применения?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:54
Оценка:
Здравствуйте, Real 3L0, Вы писали:

R3>>>В случае же "языка для проекта" новичков надо будет учить всегда и обязательно.

WH>>А что архитектуре проекта новичков обучать не нужно?

R3>Это — в любом проекте: что на самописном языке, что на общеизвестном.


А ты не задумывался о том, что если проект написан на более подходящем для этого языке (а ДСЛ-и обычно декларативные), то сам проект будет понять значительно проще?

Ты же сам сказал, что "большинство приходилось обучать, но незначительное время.". Ключевое слово здесь "незначительное". А выигрыш очевиден.

WH>> А специфичные для проекта библиотеки они тоже знают?


R3>Самописный язык 100% избавляет от специфичных библиотек?


Зависит от задачи. Но он 100% уменьшит потребность в них. Более того. Он 100% уменьшит и упростит код проекта для того кто знаком с ДСЛ-ем. А это уже не просто небольшая фича или улучшение. Это уже качественно новый уровень! Ведь мы повысили уровень кода! Теперь мы можем решать более сложные задачи, или решать те же задачи быстрее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 19:57
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>

А что архитектуре проекта новичков обучать не нужно? А специфичные для проекта библиотеки они тоже знают?


EOH>Нужно. И этого я тоже стараюсь избегать использую стандартные дизайн, архитектуру и уменьшая количество специфичных библиотек. В разумных пределах конечно.


Так в чем разница то? Мы же не агитируем за пихание ДСЛ-ей во все дыры? Если ДСЛ упростит реализацию на 5% и будет сложным в изучении, то толку от него скорее всего не будет. Скорее всего будет даже вред.

EOH>Чего я хочу, это избежать ситуацию когда программист открывает файл проекта и единственная реакция: "А-а-а-а-а-а-а-а! Что ЭТО?!?" .


Это ни разу не проблема, если люди делаю свое дело грамотно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 20:00
Оценка:
Здравствуйте, FR, Вы писали:

VD>>Достаточно, если опыт программирования на Лиспе был серьезным. Остальные средства могут соформировать не верные представления, так как синтаксических макросов в них нет и манипуляция кодом идет на уровне строк. А это действительно создает проблемы.


FR>В питоне и руби метаклассы и декораторы (питон) никак ни манипулирование строками.


Опять лукавишь. На классах МП не заканчивается. За Питон не скажу, а в руби чтобы сгенерировать код (т.е. вычисления) есть только один способ — конкатенация строк.

Короче говоря средств Руби не хватает на все случаи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 20:32
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>То есть как DSL делается на Ruby вам не нравится только потому, что LISP кроме всего прочего может модифицировать свой код? Ruby, между прочим, специально для DSL затачивалось и там есть много качественного синтаксического сахара.


Руби может и затачивался, но не дозадочился. Единственный способ сгенерировать в нем новый код (не метаклассы поменять или реинтерпетировать синтаксис) — это конкатенация текста. А это кирдык с точки зрения поддерживаемости.

Лисп тоже не идеал. Но все же в нем макры работают на уровне АСТ. Это ближе всего к подходу немерла.

EOH>

Если угостите кофе — могу зайти в гости, убедитесь в моей квалификации лично .
>>>Если есть желание зайти, познакомиться, то я не буду против.


EOH>

Но в случае библиотеки функций или классов будет тоже самое.


EOH>Нет, если мы используем стандартные библиотеки типа boost, qt, gtk, openssl, pango итд. По ним есть книги, статьи, куча блогов. Знание библиотеки можно прописать в вакансии.


Да, если мы используем стандартные библиотеки типа Nemerle.Macros, Nemerle.Peg, Nemerle.Xml, Nemerle.Async итд. По ним есть книги, статьи, куча блогов. Знание библиотеки макросов можно прописать в вакансии.

EOH>

Даже будет все хуже, так как объем кода который надо будет поддерживать будет больше, ведь это будет не только код библиотеки, но и распухший и кривой прикладной код.


EOH>Код библиотеки поддерживать не надо, если она стандартная. Я — за стандартные библиотеки и против велосипедов ^_^.


Код макро-библиотеки поддерживать не надо, если она стандартная. Я — за стандартные библиотеки и против велосипедов ^_^.

У вас что на работе "Здарова Мир!" пишут? Или весь код вы запихиваете в конечные проекты и доводите его уровень до гипер-говнокода?


EOH>

Это когда на голову ведущему разработчику падает кирпич с летальными последствиями .
VD>>Во-во. Следствие выведенное из мифа.


EOH>А я рассматриваю все в реальнй жизни. Реальные проекты — это не идеально документированные системы, на 100% покрытые юнит тестами и выглядящие как набор тасков и связанных с ними хорошо документированных коммитов.


Какой-то хреновенький у вас мир. Тестов нет. Кругом говнокод. А чтобы его как-то разгребать рассчитываете на набор детей из индусских школ.

EOH>В реальной жизни все не так хорошо. И если уходит архитектор, который использовал Qt — то человек, знающий Qt разберется в его кода. А если человек сделал свой DSL — то это йок.


Единственный вывод кторый я могу сделать из этих слов заключается в том, что задачи у вас очень примитивные и укладывающиеся в небольшое количество вызовов стандартных библиотек (да еще и С++). Ну, что же. Для таких проектов возможно идея закидывания их индусами не так уж и плоха. Язык только странно выбран. Индусы на нем плохо писать умеют. Надо было брать Яву.

Но что делать тем у кого основная сложность в собственном коде? Что если стандартных библиотек для проекта нет (или они не покрывают значимого объема кода)?

Надо или писать библиотеки самому, или пихать всю сложность в основной код. И тут получается парадокс. Гонясь за простотой и по этой причине боясь использовать ДСЛ вы получаете многократное усложнение решения. Да, в каждой отдельной строке вашего проекта сможет разобраться даже выпускник индусского ПТУ. Но в проекте в целом уже не сможет разобраться и его архитектор.

Мы же ведь говорим о реальной жизни, а не о образцово-показательном проекте, так? А в реальной жизни проект в которой напихано много кода очень быстро превращается в ад с точки зрения поддержки.

Сложность, вот реальная проблема при разработке ПО! И сложность в обучении ДСЛ-ю компенсируется простотой изучения решения сделанного на этом ДСЛ-е. А сложность поддержки ДСЛ-я компенсируется простотой поддержки решения сделанного на этом ДСЛ-е. И наоборот. Экономия на обучении выливается в сложность возникающую из-за роста объемов кода.

EOH>

EOH>>Есть некая разница между широко распространенным DSL типа rake и тем, что мы сделали сами, нэ?
VD>>Не. Никакой, если их приходится поддерживать самостоятельно.


EOH>В том-то и дело, что нам не надо поддерживать самостоятельно популярную библиотеку — за нас это делают другие.


Ну, так в чем разница с библиотеками то? Будут стандартные ДСЛ-и будете их точно так же использовать.

А не будет, будете решать что делать. Писать свою библиотеку или ДСЛ. Тут опять же разницы никакой. А вот разница в результате может быть огромной.

Если вместо написания библиотеки или макро-библиотеки вам вздумается обойтись без абстракций, то вы получите еще большее усложнение, так как весь этот код будет размазан по проекту.

EOH>

EOH>>Если Вы считаете, что в DSL прямо вот так легко разобраться — возьмити любой проект Ruby on Rails и загляните внутрь. Будете приятно удивлены лаконичности кода и полным непонимаем как "это" работает "внутри". И это еще популярный DSL. А если кто такое сам напишет?
VD>>Во-во. Берем язык с недометапрограммированием и делаем на его базе далеко идущие выводы.
VD>>Я вот могу взять за основу аналог — Nemerle on Rails. В его коде я разберусь без труда (хотя и не причастен к его разработке) и смогу поддерживать и развивать его.


EOH>Я беру его как образец популярного использования концепции DSL. И чем Вам в руби программирование не мета?


А мне в нем МП нравится. Я против решения тех же задач вручную. Я вообще не люблю заката солнца вручну.
Ну, и мне не нравится сам Руби, так как это скрипт со всеми вытекающими (тормозами и ошибками на каждом шагу).
Так что то, что у Руби МП не очень мощный по стравнениюб с лиспом и тем более немерлом — это уже детали.

Более того, я согласен с тем, что если есть готовая реализация ДСЛ-я, или тем более, фрэймворк вроде рельсов, то глупо писать свой аналог. Но что делать если для задачи такого решения нет? Или есть те же рельсы на Руби, но код надо писать на дотнете или яве? Писать проект полностью в рукопашную? Написать библиотеку и мучиться с ее ограничениями? Или, может быть, все же написать свой фрэймворк?

EOH>

VD>Я вот вижу совершенно конкретные факты. Люди без огромного опыта в Nemerle правят макросы написанные за долго до того как они познакомились с языком. Может быть они от природы талантливее, но думаю что дело в другом.


EOH>Немерле пока не смотрел. Но мы же говорим про DSL вообще, а не про особо удачную реализацию концепции метапрограммирования? В реальной жизни DSL чаще делают на t4, чем на немерле, увы


Дык проблем в том, что собравшиеся тут люди делятся на два лагеря. Одни уже попробовали (посмотреть мало) Немерл и его МП, а другие судят об МП на основании Т4 и других поделок. Вот и получаются совсем разные выводы.

Концепция ДСЛ-ей "вообще" не должна страдать от того, что где-то она реализована криво. Не так ли?

Немерл 1 далеко идеал с точки зрения поддержки в ЯП ДСЛ-ей и МП. Но это значимый шаг вперед. Он отчетливо демонстрирует, что многие легенды о ДСЛ-ях и МП являются мифами сформировавшимися под давлением тех или иных факторов (заблуждений, негативного использования плохо подходящих средств и т.п.), но не имеющих под собой объективных оснований.

Мое мнение очень простое. Хороший код писать очень сложно. Писать хорошие ДСЛ-и в двойне сложнее. Но писать (поддерживать, развивать) хороший код с использованием хороших ДСЛ-ей проще и продуктивнннее.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 20:39
Оценка:
Здравствуйте, FR, Вы писали:

FR>А зачем базовые, ладно к C++ прикрутить синтаксический макропроцессор очень сложно, но к той же Ява или Шарпу

FR>вполне реально (для производителей языка) вместо выдумывания гораздо более слабых T4.

Ага. Реально. В итоге получается Nemerle.

Тут проблема в том, что если без изменения языка к Шарпу прикрутить МП, то в итоге сложность реализации МП-процедур будет такая, что кроме авторов языка и, возможно, пары очень упорных товарищей, таким МП мало кто будет пользоваться.

В Немерле, Лиспе, Руби и Питоне МП не просто есть, а им довольно легко воспользоваться.

Потом проблема в ведь в том, что манагеры языков вроде Явы и Шарпа разделяют скепсис который тут продвигают товарищи вроде Eye of Hell.

VD>>Ну, а что ты хочешь? Динамика да еще и лиспоподобная. Хотя выглдяит все же по проще чем Лисп.


FR>Все-таки гибрид, изначально можно задавать типы.


Плавали, знаем. Это плохой подход. Лучше изначально типы выводить. Немного проигрываем в полиморфизме, но за-то выигрываем по всем остальным фронтам.

FR>От липсоподобности (синтаксической) там как раз и старались избавится, по моему вполне получилось.


А причины провала (забрасывания) кто-то озвучивал?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 20:40
Оценка:
Здравствуйте, Mystic, Вы писали:

M>Чище не значит проще для понимания. Это значит, что под тем, что я вижу, находится еще некоторая скрытая логика, которую надо хорошо понимать. Это увеличивает порог вхождения, требуемую квалификацию и т. д. и т. п.


Ага. Но это отнюдь не означает, что эта логика не может быть интуитивно понятна.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: 0x7be СССР  
Дата: 04.02.11 20:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А если тебе показать огромное ГУИ-приложение без Qt (и других библиотек) и написанное еще не самым лучшим образом, то ты разберешься в нем быстрее?

Нет, конечно.

VD>Может лучше изучить этот самый Qt и потом уже разобраться в приложении которое будет в разы проще из-за его применения?

Лучше изучить. Мой поинт в том, что DSL по сути не так уж сильно отличаются от фреймворков и просто навороченных в конкретной программе систем абстракций. Их так же надо изучать, и если они сложны, то порог вхождения будет высоким.
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 20:43
Оценка:
Здравствуйте, night beast, Вы писали:

NB>ты все таки найди время на tex посмотреть.

NB>думаю, не малую роль в его популярности сыграло наличие в свободном доступе Texbook'a, на пальцах описывающего весь язык.

Где брать?

NB>Сможете подобное для немерла сделать?


А что там такого не обычного? Вот это не похоже на то о чем ты говоришь?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 04.02.11 21:06
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>А ты не задумывался о том, что если проект написан на более подходящем для этого языке (а ДСЛ-и обычно декларативные), то сам проект будет понять значительно проще?

VD>Ты же сам сказал, что "большинство приходилось обучать, но незначительное время.". Ключевое слово здесь "незначительное". А выигрыш очевиден.

Пример, который я привёл, как раз и использовал "более подходящий язык".
Моя мысль в том, что вхождение в проект, использующий более-менне распространённые вещи, может требовать обучения, а может — нет. В проектах, использующих "закрытые" техники — обучение всегда обязательно.
Про остальное не спорю, т.к. не компетентен.

VD>Зависит от задачи. Но он 100% уменьшит потребность в них. Более того. Он 100% уменьшит и упростит код проекта для того кто знаком с ДСЛ-ем. А это уже не просто небольшая фича или улучшение. Это уже качественно новый уровень! Ведь мы повысили уровень кода! Теперь мы можем решать более сложные задачи, или решать те же задачи быстрее.


За это я всеми руками за только в том случае, если с помощью этого "создателя языков" будет создан язык, который не усложняет программирование, а упрощает.
Объяснюсь. Я всю жизнь писал только бизнес-приложения, и использовал языки в следующей последовательности: C++ -> C++&MFC -> .NET. При каждом переходе на следующий язык, я очень сильно плевался на предыдущий. Я уже раза 3 читал все эти захватывающие отзывы о Немерле и начинал читать о нём, но... меня хватало только до того момента, как начинался идти синтаксис, напоминающий сишную "точко-запятуюшную" пунктуацию (только с ещё большим разнообразием ). Вот этот язык мне не нужен (а также ещё очень большой куче народа).
Вселенная бесконечна как вширь, так и вглубь.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 04.02.11 21:15
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>В питоне и руби метаклассы и декораторы (питон) никак ни манипулирование строками.


VD>Опять лукавишь. На классах МП не заканчивается. За Питон не скажу, а в руби чтобы сгенерировать код (т.е. вычисления) есть только один способ — конкатенация строк.


В питоне есть еще декораторы для функций, которые вполне используются для метапрограммирования.

VD>Короче говоря средств Руби не хватает на все случаи.


Не знаю как в руби, но в питоне никакой необходимости генерировать код строками нет (хотя это возможно как и в любом динамическом языке и
в простых случаях удобней), компилятор доступен в виде стандартной библиотеки:
>>> from compiler.ast import *
>>> Module('This is an example module.\n\nThis is the docstring.\n',
...    Stmt([Function(None, 'double', ['x'], [], 0,
...                   'Return twice the argument',
...                   Stmt([Return(Mul((Name('x'), Const(2))))]))]))


http://docs.python.org/library/compiler.html
Re[10]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 21:37
Оценка: :)
Здравствуйте, Курилка, Вы писали:

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


Это глобальное состояние, которое как раз таки противоречит идеям ФП.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 21:44
Оценка:
Здравствуйте, Real 3L0, Вы писали:

R3>Пример, который я привёл, как раз и использовал "более подходящий язык".

R3>Моя мысль в том, что вхождение в проект, использующий более-менне распространённые вещи, может требовать обучения, а может — нет.

Это не правда.

R3>В проектах, использующих "закрытые" техники — обучение всегда обязательно.


В проектах не использующих технологий придется учить сам проект. Точнее его все равно учить, но без "технологий" объем изучения резко возрастает.

А так, да. Лучше использовать стандартный ДСЛ чем не стандартный, лучше быть богатым и здоровым, чем бедным и больным. Тут все верно.

VD>>Зависит от задачи. Но он 100% уменьшит потребность в них. Более того. Он 100% уменьшит и упростит код проекта для того кто знаком с ДСЛ-ем. А это уже не просто небольшая фича или улучшение. Это уже качественно новый уровень! Ведь мы повысили уровень кода! Теперь мы можем решать более сложные задачи, или решать те же задачи быстрее.


R3>За это я всеми руками за только в том случае, если с помощью этого "создателя языков" будет создан язык, который не усложняет программирование, а упрощает.


Дык обратное — это уже натуральное преступление.

R3>Объяснюсь. Я всю жизнь писал только бизнес-приложения, и использовал языки в следующей последовательности: C++ -> C++&MFC -> .NET. При каждом переходе на следующий язык, я очень сильно плевался на предыдущий.


Та же фигня. Только языков было чуть больше. Но ведь это проходит?

R3>Я уже раза 3 читал все эти захватывающие отзывы о Немерле и начинал читать о нём, но... меня хватало только до того момента, как начинался идти синтаксис, напоминающий сишную "точко-запятуюшную" пунктуацию (только с ещё большим разнообразием ). Вот этот язык мне не нужен (а также ещё очень большой куче народа).


Что-то я не понял. "точко-запятуюшная" пунктуация вроде бы есть и в С++ и в шарпе. Так о чем ты?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 21:47
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Лучше изучить. Мой поинт в том, что DSL по сути не так уж сильно отличаются от фреймворков и просто навороченных в конкретной программе систем абстракций. Их так же надо изучать, и если они сложны, то порог вхождения будет высоким.


Да, КО! Для любой сложной задачи нужны подходящие инструменты. И если инструменты сложны, то для их изучения нужно больше усилий. Но без этого сложные задачи не решить.

То же самое происходит и со знаниями. Чем более сложная задача, тем больше базовых знаний нужно для ее понимания и решения.

Причем тут ДСЛ-и и МП? Это же общая проблема сложных задач.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 21:50
Оценка:
Здравствуйте, FR, Вы писали:

FR>в простых случаях удобней), компилятор доступен в виде стандартной библиотеки:

FR>
>>>> from compiler.ast import *
>>>> Module('This is an example module.\n\nThis is the docstring.\n',
FR>...    Stmt([Function(None, 'double', ['x'], [], 0,
FR>...                   'Return twice the argument',
FR>...                   Stmt([Return(Mul((Name('x'), Const(2))))]))]))
FR>


АААААААААА!!! (рвет волосы на голове) И эти люди говорят что Лисп или Немрле сложный?!!!

Вот это и есть ужас! И конечно же люди выбирают генерацию и интерпретацию строк, со всеми вытекающими, чтобы его не видеть.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 04.02.11 21:50
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>А зачем базовые, ладно к C++ прикрутить синтаксический макропроцессор очень сложно, но к той же Ява или Шарпу

FR>>вполне реально (для производителей языка) вместо выдумывания гораздо более слабых T4.

VD>Ага. Реально. В итоге получается Nemerle.


Если не увлекаться то Caml4p

VD>Тут проблема в том, что если без изменения языка к Шарпу прикрутить МП, то в итоге сложность реализации МП-процедур будет такая, что кроме авторов языка и, возможно, пары очень упорных товарищей, таким МП мало кто будет пользоваться.


Так я же не про кодогенерерацию, а про аналог Camlp4

VD>В Немерле, Лиспе, Руби и Питоне МП не просто есть, а им довольно легко воспользоваться.


Это органично вписать может быть непросто.

VD>Потом проблема в ведь в том, что манагеры языков вроде Явы и Шарпа разделяют скепсис который тут продвигают товарищи вроде Eye of Hell.


Я скепсис не разделяю, но он вполне обоснован.

FR>>Все-таки гибрид, изначально можно задавать типы.


VD>Плавали, знаем. Это плохой подход. Лучше изначально типы выводить. Немного проигрываем в полиморфизме, но за-то выигрываем по всем остальным фронтам.


По моему вполне нормальный подход.

FR>>От липсоподобности (синтаксической) там как раз и старались избавится, по моему вполне получилось.


VD>А причины провала (забрасывания) кто-то озвучивал?


Могу напутать, но очень похоже на историю Smalltalk, дорогая коммерческая реализация которая в конце концов стала никому не нужна и
была отдана в open source когда поезд ушел. Ну и до этого Apple отказалась от языка.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.11 21:52
Оценка:
Здравствуйте, FR, Вы писали:

FR>Могу напутать, но очень похоже на историю Smalltalk, дорогая коммерческая реализация которая в конце концов стала никому не нужна и

FR>была отдана в open source когда поезд ушел. Ну и до этого Apple отказалась от языка.

Т.е. доступного бесплатно решения не было?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 04.02.11 22:02
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>АААААААААА!!! (рвет волосы на голове) И эти люди говорят что Лисп или Немрле сложный?!!!


Да нет там ничего страшного, близко к лиспу. Вручную как было выше редко собирать надо, чаще трансформация AST, да и обычные функции
как макросы работают.

VD>Вот это и есть ужас! И конечно же люди выбирают генерацию и интерпретацию строк, со всеми вытекающими, чтобы его не видеть.


И в результате получают на порядок более страшный ужас
Re[11]: Способно ли метапрограммирование заменить отдельные
От: FR  
Дата: 04.02.11 22:06
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Т.е. доступного бесплатно решения не было?


Насколько знаю не было, open source версию пилили и никак допилить не могли, а коммерческая была с IDE, отладчиком, средой вполне на уровне, там была и ограниченная free версия я ее ставил игрался как-то.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 04.02.11 22:21
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Тут проблема в том, что если без изменения языка к Шарпу прикрутить МП, то в итоге сложность реализации МП-процедур будет такая, что кроме авторов языка и, возможно, пары очень упорных товарищей, таким МП мало кто будет пользоваться.


А с Nemerle ситуация другая чтоли?
Re[14]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 04.02.11 23:38
Оценка:
Здравствуйте, WolfHound, Вы писали:

IT>>Порог вхождения, конечно же, возрастает. Всё же надо что-то изучить против ничего не изучать.

WH>А что библиотеку изучать не надо?
WH>Чем изучание библиотеки отличается от изучения ДСЛ?

Если речь идёт о библиотеке vs. DSL, то тут, конечно, вопрос спорный. Но товарищ утверждал, что он старается ничем таким не пользоваться вообще.
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 07:22
Оценка:
EOH>>Если у меня в проекте много PEG — то я просто пишу в вакансии: "Знанание PEG". Ну или там Antlr. А автор топика настаивал на добавлении в язык СОБСТВЕННОГО DSL. Согласитесь, разные вещи — Antlr, по которому есть книга и никому неизвестное расширение Java от компании Рога и Копыта, которое поддерживает кучу специфических для них вещей. Плюс еще криво, косо, архитектурно нецелостно, без нормальной документации, with bugs и автор которой уволился два года назад потому что уехал в Китай поступать в монастырь.
WH>И чем это отличается от библиотеки?
WH>То что ДСЛ можно сделать плохо не означает что его нельзя сделать хорошо.

С этим никто не спорит. Автор интересовался, что в мейнстриме со встраиванием DSL в язык. Я рассказал про проблемы. Понятное дело, что кому надо — те используют. Но в мейнстрим, ИМХО, не пойдет — страшно. Вот посмотрим года через 3-4 что будет с руби в мейнстриме — он как бы под DSL заточен.

EOH>>Может быть. Я просто достаточно давно в отрасли, видел что случается с разными решениями когда меняются поколения разработчиков и авторы покидают компанию. Чем проще код — чем лучше он переживает ротацию кадров.

WH>Полностью согласен.
WH>А код на правильном ДСЛ значительно проще.

Давайте попробую так сформулировать: "написать правильный DSL который был бы правильным как в использовании так и в поддержке сложнее, нежели написать правильную библиотеку. Поэтому мейнстрим за библиотеками".

EOH>>Я за стандартные DSL. Если можно написать библиотеку или DSL то я за библиотеку, потому что она проще в понимании для человека, знающего язык и экосистему, на основе которых она написана. Это как бы мое ИМХО после многолетнего общения с DSL и кодогенерацией.

WH>+100
WH>Тебе осталось признать две вещи:
WH>1)Иногда стандартных инструментов просто нет.
WH>2)Иногда ДСЛ значительно проще библиотеки.

Я же не против DSL вообще. Понятное дело, что для частного случая можно и нужно использовать то, что для этого частного случая будет лучше. Но если у меня команда 20+ человек и старший программист Вася приползает ко мне со словами "а вот давай я тут DSL вверну, оно понятнее будет" — я не разрешу. Потому что сейчас Вася тут, а завтра в Яндексе. И что он там напишет — непонятно. Пусть лучше кода будет немного больше, зато у проекта через год головной боли будет меньше.

EOH>>Понять как работает SVN API проще, чем разобраться как работает Rails и поменять там что-то внутри при отсутствии доступа к автору.

WH>Не стои сравнивать не сравнимое.
WH>Ты сравни грамматику ПЕГ и тот код который из нее получается...

ИМХО не очень удачный пример потому что эксплоитит ту область, в которой DSL must have — создание парсеров. Но ведь парсеры не так часто создаются?

EOH>>Где можно про правила цитирования почитать?

WH>В почти 100% сообщений на форуме.

Действительно, зелененьким расскрашивает О_О. Как-то не обратил внимание, бывает.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 07:24
Оценка:
EOH>>Чем проще код — чем лучше он переживает ротацию кадров.
IT>Что в данном случае подразумевается под "проще"?

Проще — это значет, что после того как автор кода покидает компанию, нанятый на его место сотрудник сравнимой квалификации может без усилий поддерживать и модифицировать этот код.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 05.02.11 07:24
Оценка:
Здравствуйте, VladD2, Вы писали:

R3>>Пример, который я привёл, как раз и использовал "более подходящий язык".

R3>>Моя мысль в том, что вхождение в проект, использующий более-менне распространённые вещи, может требовать обучения, а может — нет.
VD>Это не правда.

Почему "не правда", если этот пример — реальная ситуация? (Под "распространёнными вещами" я имею в виду только средства разработки.)

R3>>Объяснюсь. Я всю жизнь писал только бизнес-приложения, и использовал языки в следующей последовательности: C++ -> C++&MFC -> .NET. При каждом переходе на следующий язык, я очень сильно плевался на предыдущий.

VD>Та же фигня. Только языков было чуть больше. Но ведь это проходит?

Языков тоже было больше, но остальные не много использовал.
Не проходит. Наверное потому, что специфика разработки бизнес-приложений такова: много из того, что предоставляет "предыдущий уровень" языка для разработки бизнес-приложений не нужно.

R3>>Я уже раза 3 читал все эти захватывающие отзывы о Немерле и начинал читать о нём, но... меня хватало только до того момента, как начинался идти синтаксис, напоминающий сишную "точко-запятуюшную" пунктуацию (только с ещё большим разнообразием ). Вот этот язык мне не нужен (а также ещё очень большой куче народа).

VD>Что-то я не понял. "точко-запятуюшная" пунктуация вроде бы есть и в С++ и в шарпе. Так о чем ты?

Например:
~
*
&
->
::
>>
<<

.NET показал, что это не нужно.

У Немерле — свои "точки в голове". Получается, что лично мне он не нужен. Не те потребности.
Но вот если с помощью Немерле будет создан супер-пупер язык для разработки бизнес-приложений ...
Вселенная бесконечна как вширь, так и вглубь.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 07:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Eye of Hell, Вы писали:

EOH>>PEG — это СТАНДАРТНЫЙ DSL. Так же как Regexp. Если у меня в проекте много PEG — то я просто пишу в вакансии: "Знанание PEG". Ну или там Antlr. А автор топика настаивал на добавлении в язык СОБСТВЕННОГО DSL. Согласитесь, разные вещи — Antlr, по которому есть книга и никому неизвестное расширение Java от компании Рога и Копыта, которое поддерживает кучу специфических для них вещей. Плюс еще криво, косо, архитектурно нецелостно, без нормальной документации, with bugs и автор которой уволился два года назад потому что уехал в Китай поступать в монастырь.
VD>На мой взгляд твоя позиция развалилась в пух и прах.

Если бы моя позиция была приварена к полу — наверное, я был бы плохим архитектором?

VD>Вот суди сам. Ты изначально заявлял, что проблемой является не примеение ДСЛ-я, а поддержка МП кода. Я правильно тебя понял?


Если вернуться к истокам, то на вопрос автора топика:

Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

Я высказал свое мнение:

Кроме плюсов возникают минусы. Посмотрите на практику применения DSL: чем более сложный DSL мы применяем, тем поще и быстрее нам код писать, но тем сложнее и дольше его поддерживать другим людям. Соответственно, это не так популярно потому как компании хотят защититься от эффекта падающего кирпича. Если архитектор DSL покинет компанию или даже заболеет — будут большие проблемы. ОЧЕНЬ большие проблемы.


Далее я по мере возможностей свою позицию аргументировал .

VD>Но нет никакой стандартной реализации PEG-а которую можно было бы требовать в резюме. PEG — это всего лишь общие мысли на тему языка описывающего парсер. А его реализация может быть любой (и есть их не мало).


Вот на википедии внизу список из реализаций. Но тут вы атаковали небольшой фрагмент моей позиции, где я высказался, что если уж использовать DSL — то не свое расширение к языку писать, а использовать что-то готовое, в качестве примера приведя PEG и Regexp.

VD>Стало быть если кто-то в рамках твоего проекта или даже отдельно сделает реализацию PEG-а, то ты будешь зависеть от нее на 100%. И нанимая кого-то поддерживать эту реализацию ты точно так же будешь не в состоянии взять кого-то со стороны.


Я как раз против того, чтобы делать DSL самому направо и налево . Для подавляющего большинства задач не надо самому писать PEG — есть готовые имплементации. А если пишут, то велика вероятность что сорудник просто играется с фенечками за счет работодателя. И после его увольнения мы получим кучку недоделанных игрушек и пораченные на это наши деньги.

VD>При этом использовать сам PEG очень просто. Даже если ты его не знаешь, то изучить его можно где-то за неделю. Изучив его разобраться в проекте в котором он использован будет в сто раз проще, нежели в проекте где используются "библиотеки", так как под красивым термином "библиотеки" скрывается голимый рукописный код парсеров. На его изучение надо будет убить далеко не одну неделю. Получается, что экономя неделю на изучение DSL-я мы теряем месяцы на изучение всего проекта, коды на его поддержку, так как изменять декларативный ДСЛ в сто раз проще нежели рукописный код.


Вообщем развернули вы мою возицию неподобающим местом и теперь пытаетесь с ней сделать что-то противоестественное O_O. Я не говорил, что надо вручную реализовывать PEG. Я говорил, что мейнстрим — это использование готовых библиотек. Если очень надо — то готовых DSL (у которых есть сайт, мануал, сообщество, mailing list наконец).

VD>И совершенно по фигу стандартен ли PEG как язык. Ведь на его изучение тратится копеечное время (по сравнению с временем затрачиваемым на изучение проекта где он используется).


С этим я не спорю. Я против того, чтобы Вася вместо использования Qt, PEG или Antlr сел и написал собственное расширение к C++ и потом радостно использовал его, к примеру, для чтения конфиг файлов. Потому что когда он уволится — этот его велоспиед кому-то поддерживать. И будет он, скорее всего, реализован намного хуже чем тот же Boost::Spirit .

P.S. И вообще, вы как-то настоятельно клоните к задачам создания парсеров. В рамках программирования вообще это не самая частая задача. DSL чаще используется для задания поведения программы, нежели для создания собственного языка программирования.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 07:42
Оценка:
EOH>>См. в этой же ветке. Пробовал и не один год. И то и другое.
VD>Смотри как интересно получается... У меня, вольфхаунда, зива, хардкейса и тебя есть опыт работы с ДСЛ-ями. Но у тебя он отрицательный, а у остальных перечисленных — положительный. Тебя это не наталкивает на мысль, что может быть дело не в подходе, а в чем-то другом? Может в тебе или используемых тобой инструментах?

Программирование — оно большое. Я рассматриваю со своей колокольни — создание коммерческих, коробочных продуктов. Тоесть ПО для продажи. А вы для чего DSL использовали? Вольфхаунд, Хардкейс — выскажитесь пожалуйста, дабы сравнить.

В моей практике DSL и кодогенерация применяется для двух задач:
1. Уменьшение количества ошибок, связанного с копи-пастом при решении неких стандартых задач. Типичный пример — создание контейнера в Qt или имплементации по описанию интерфейса.
2. Уменьшение времени написания кода. Как показывает практика, за редким исключением SOAP на 500 методов это не очень релевантный параметр.

И не раз приходилось видеть, когда на создание, поддержку и багфикс DSL в рамках компании/отдела уходило намного больше времени, чем было бы потрачено если просто взять и написать код вручную. А когда автор покидал компанию, начинался тихий ужас, потому что ИМХО есть очень мало людей, которые могут сделать действительно качественный DSL. А руби тогда был менее популярен . И приходилось потом тратить еще больше времени чтобы разобраться в ЭТОМ. Уж лучше бы он в своих двух проектах вручную конфиги читал .
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.11 08:41
Оценка: -1
Здравствуйте, Eye of Hell, Вы писали:

EOH>

Если синтаксис действительно настолько крут, что настолько уменьшает количество кода, то затраты на обучение ему (совсем не такие большие как кажутся) окупаются скоростью разработки и качеством результата.


EOH>Увы, практика показывает что код больше читается / поддерживается, нежели пишется.

С этим утверждением никто не спорит. Вот в чём вопрос: ты считаешь, что введение custom syntax затруднит чтение?

Мне вот кажется, что как минимум не всегда. К примеру, читать linq в форме query comprehensions всяко проще, чем те же запросы в форме вызовов функций.
И таких вариантов ещё много. DSL на C — в общем-то, хороший пример. То есть люди всё-таки мучительно рожают новые языки в рамках существующих, и оно окупается — судя по тому, что сетевой стек в FreeBSD таки работает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: 0x7be СССР  
Дата: 05.02.11 09:57
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Да, КО! Для любой сложной задачи нужны подходящие инструменты. И если инструменты сложны, то для их изучения нужно больше усилий. Но без этого сложные задачи не решить.

VD>То же самое происходит и со знаниями. Чем более сложная задача, тем больше базовых знаний нужно для ее понимания и решения.
VD>Причем тут ДСЛ-и и МП? Это же общая проблема сложных задач.
Мы с тобой одинаково мыслим, так что относительно тебя я — КО.
А, вот, Eye of Hell так не думает
Re[15]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 10:21
Оценка:
IT>Если речь идёт о библиотеке vs. DSL, то тут, конечно, вопрос спорный. Но товарищ утверждал, что он старается ничем таким не пользоваться вообще.

Это про меня? ^_^"
Re[12]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 10:29
Оценка:
WH>>>А что архитектуре проекта новичков обучать не нужно? А специфичные для проекта библиотеки они тоже знают?
EOH>>Нужно. И этого я тоже стараюсь избегать использую стандартные дизайн, архитектуру и
WH>Стандартную архитектуру? Это какую?
WH>Только давай чтобы она подошла для компилятора, фотошапа, ядра ОС, прошивки микроконтроллера, гуглопоиска,...

А там под области есть. MVC для GUI, threadpool для распределения задач, marhsalling для передачи данных и прочее. А вот когда народ вместо того, чтобы взять QThreadPool пишет свой велосипед потому что "так будет на пять процентов быстрее и расширяемее" — то при условии, что мы не пишем кластер, у нас сразу проблемы.

EOH>>уменьшая количество специфичных библиотек.

WH>Я тоже против велосипедов но жизнь такова что иногда приходится их изобретать.

Ну так я про общий случай, а не про частности. Понятно что для каждого случая мы стараемся применять лучшие инструменты и подходы. Но, ИМХО, в общем случае стандартные подходы более благотворно влияют на поддерживаемость проектов. А добавлять свои DSL на пустом месте — это ой.

EOH>>В разумных пределах конечно. Чего я хочу, это избежать ситуацию когда программист открывает файл проекта и единственная реакция: "А-а-а-а-а-а-а-а! Что ЭТО?!?" .

WH>А я хочу избежать ситуации когда человек вместо файлика на десяток другой килобайт видит мегабайт исходников.
WH>Это вполене реальное отношение Грамматика C# и его препроцессора занимают 44 138 байт.
WH>Сгенерированный код распечатанный преттипринтом занимает 2 334 568 байт.
WH>Ты можешь говорить что хочешь но разобраться с грамматикой на ПЕГе минимум на два порядка проще чем с тем кодом который из нее получается.
WH>Просто по тому что кода на два порядка меньше.

Коллега, как я уже говорил, вы взяли крайне удобный ракурс для обсуждения DSL — написание компиляторов . То, что для написания компилятора DSL — это единственное разумное и естественное решение я не спорю. Но ведь топикстертер наверняка не про разработку компиляторов спрашивал? ^_^. Да и оцените объем задач по разработке компиляторов по отношению к остальным задачам разработки — это, ИМХО, достаточно узкая ниша.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 10:32
Оценка:
IT>Недавний пример с переходом на FW 4.0. Единственная реакция при переходе на новый ASP была как раз: "А-а-а-а-а-а-а-а! Что ЭТО?!?". Поплыл рендеринг контролов, изменилась модель секьюрити и изменилась логика обработки HTTP реквеста.
IT>Зато наши доморощенные быблиотечки как жужжали, так и жужжат.
IT>В общем, очередной притянутый за уши аргумент.

Если бы ответ на вопрос был бы очевиден, вопрос бы не стоял? ^_^.

А теперь представьте на секунду, что вместо документированного, с книгами/блогами/евангелистами asp.net у вас написанный пять лет назад Васей Пупкиным фреймворк с собственным DSL. Без хорошей документации, с кучей написанного слабыми программистами кода (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много) и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 10:36
Оценка:
EOH>>Нужно. И этого я тоже стараюсь избегать использую стандартные дизайн, архитектуру и уменьшая количество специфичных библиотек. В разумных пределах конечно.
VD>Так в чем разница то? Мы же не агитируем за пихание ДСЛ-ей во все дыры? Если ДСЛ упростит реализацию на 5% и будет сложным в изучении, то толку от него скорее всего не будет. Скорее всего будет даже вред.

Вообще-то я о том же говорил . А автор как раз интересовался почему не делают легкодоступные DSL, интегрированные в сами языки программирования. Видимо, чтобы не злоупотребляли? А то вот в руби есть зачатки — и вы не поверите, злоупотребляют!

EOH>>Чего я хочу, это избежать ситуацию когда программист открывает файл проекта и единственная реакция: "А-а-а-а-а-а-а-а! Что ЭТО?!?" .

VD>Это ни разу не проблема, если люди делаю свое дело грамотно.

Так то в идеальном мире. А в реальном мире, увы, не всегда удается нанять достаточно квалифицированных специалистов. Потому что с одной стороны бюджет не резиновый, а с другой стороны специалистов мало и не хочется чтобы текучка кадров стала для проекта фатальной. Это разработчикам просто — код написал, деньги получил. А менеджерам приходится еще думать кто будет этот код поддерживать, когда этот разработчик уйдет в Яндекс и придется брать замену. Причем быстро, а не полгода искать гуру. O_O
Re[6]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 10:39
Оценка:
VD>А если тебе показать огромное ГУИ-приложение без Qt (и других библиотек) и написанное еще не самым лучшим образом, то ты разберешься в нем быстрее?
VD>Может лучше изучить этот самый Qt и потом уже разобраться в приложении которое будет в разы проще из-за его применения?

Напоминаю свою точку зрения: вместо написания собственных DSL для решения задач, не связанных с разработкой компиляторов, предпочтительнее использовать либо уже существующие библиотеки, которые известны широким нанимаемым массам, либо уже существующие DSL, которые так же известны широким массам. А вот свои DSL за исключением редких случаев лучше, ИМХО, не писать.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 10:55
Оценка:
VD>Лисп тоже не идеал. Но все же в нем макры работают на уровне АСТ. Это ближе всего к подходу немерла.

Оффтопик. Да, потому что в нем это АСТ — полторы ветки и четыре чахлых листика ;-E~. В tcl то же самое.

EOH>>Код библиотеки поддерживать не надо, если она стандартная. Я — за стандартные библиотеки и против велосипедов ^_^.

VD>Код макро-библиотеки поддерживать не надо, если она стандартная. Я — за стандартные библиотеки и против велосипедов ^_^.
VD>У вас что на работе "Здарова Мир!" пишут? Или весь код вы запихиваете в конечные проекты и доводите его уровень до гипер-говнокода?

Да нет, вот на последней работе Radmin делаем, он вроде бы не маленький. И с кодом там на мой взгляд все неплохо.

EOH>>А я рассматриваю все в реальнй жизни. Реальные проекты — это не идеально документированные системы, на 100% покрытые юнит тестами и выглядящие как набор тасков и связанных с ними хорошо документированных коммитов.

VD>Какой-то хреновенький у вас мир. Тестов нет. Кругом говнокод. А чтобы его как-то разгребать рассчитываете на набор детей из индусских школ.

Именно так. Это реалии большинства софтовых проектов, увы. Не всем же делать что-то новое, с нуля и одному . А как только появляется команда из нескольких человек — то все начинает удручающе ухудшаться.

EOH>>В реальной жизни все не так хорошо. И если уходит архитектор, который использовал Qt — то человек, знающий Qt разберется в его кода. А если человек сделал свой DSL — то это йок.

VD>Единственный вывод кторый я могу сделать из этих слов заключается в том, что задачи у вас очень примитивные и укладывающиеся в небольшое количество вызовов стандартных библиотек (да еще и С++). Ну, что же. Для таких проектов возможно идея закидывания их индусами не так уж и плоха. Язык только странно выбран. Индусы на нем плохо писать умеют. Надо было брать Яву.

Примитивность задач — вопрос очень субъективных. Сетевые протоколы, высоконагруженные сервера, отказоустойчивые системные сервисы — это примитивно? ^_^.

VD>Но что делать тем у кого основная сложность в собственном коде? Что если стандартных библиотек для проекта нет (или они не покрывают значимого объема кода)?

VD>Надо или писать библиотеки самому, или пихать всю сложность в основной код. И тут получается парадокс. Гонясь за простотой и по этой причине боясь использовать ДСЛ вы получаете многократное усложнение решения. Да, в каждой отдельной строке вашего проекта сможет разобраться даже выпускник индусского ПТУ. Но в проекте в целом уже не сможет разобраться и его архитектор.

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

VD>Мы же ведь говорим о реальной жизни, а не о образцово-показательном проекте, так? А в реальной жизни проект в которой напихано много кода очень быстро превращается в ад с точки зрения поддержки.


Для борьбы с этим есть не только DSL. Есть декомпизиция на иерархию слабосвязанных модулей.

VD>Сложность, вот реальная проблема при разработке ПО! И сложность в обучении ДСЛ-ю компенсируется простотой изучения решения сделанного на этом ДСЛ-е. А сложность поддержки ДСЛ-я компенсируется простотой поддержки решения сделанного на этом ДСЛ-е. И наоборот. Экономия на обучении выливается в сложность возникающую из-за роста объемов кода.


Я в курсе. Но вот так получилось, что мой опыт показывает, что с DSL в поддержке сложнее. Видимо, сильно от прикладной области зависит?

EOH>>

EOH>>Есть некая разница между широко распространенным DSL типа rake и тем, что мы сделали сами, нэ?
VD>>>Не. Никакой, если их приходится поддерживать самостоятельно.

EOH>>В том-то и дело, что нам не надо поддерживать самостоятельно популярную библиотеку — за нас это делают другие.
VD>Ну, так в чем разница с библиотеками то? Будут стандартные ДСЛ-и будете их точно так же использовать.
VD>А не будет, будете решать что делать. Писать свою библиотеку или ДСЛ. Тут опять же разницы никакой. А вот разница в результате может быть огромной.

В таком ракурсе может быть. Я больше сравниваю использование стандартных библиотек против собственного DSL ^_^.

VD>Более того, я согласен с тем, что если есть готовая реализация ДСЛ-я, или тем более, фрэймворк вроде рельсов, то глупо писать свой аналог. Но что делать если для задачи такого решения нет? Или есть те же рельсы на Руби, но код надо писать на дотнете или яве? Писать проект полностью в рукопашную? Написать библиотеку и мучиться с ее ограничениями? Или, может быть, все же написать свой фрэймворк?


Вы продолжаете подкидывать очень специфические примеры, где сбственный DSL — это единственное решение. Портирование с рельсов на .net — это не очень частая задача

EOH>>Немерле пока не смотрел. Но мы же говорим про DSL вообще, а не про особо удачную реализацию концепции метапрограммирования? В реальной жизни DSL чаще делают на t4, чем на немерле, увы

VD>Дык проблем в том, что собравшиеся тут люди делятся на два лагеря. Одни уже попробовали (посмотреть мало) Немерл и его МП, а другие судят об МП на основании Т4 и других поделок. Вот и получаются совсем разные выводы.

Убедили, я прочитаю мануал по Немерле .
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 11:00
Оценка:
EOH>>Увы, практика показывает что код больше читается / поддерживается, нежели пишется.
S>С этим утверждением никто не спорит. Вот в чём вопрос: ты считаешь, что введение custom syntax затруднит чтение?

Да нет, читается он замечательно. Только вот если в самом DSL баги, нужно его поддерживать и расширять — то при отсутствии автора это превращается в небольшой филиал ада. Не всегда, конечно, но часто

S>Мне вот кажется, что как минимум не всегда. К примеру, читать linq в форме query comprehensions всяко проще, чем те же запросы в форме вызовов функций.


А теперь попробуйте модифицировать сам LINQ

S>И таких вариантов ещё много. DSL на C — в общем-то, хороший пример. То есть люди всё-таки мучительно рожают новые языки в рамках существующих, и оно окупается — судя по тому, что сетевой стек в FreeBSD таки работает.


Ну, работает много чего. Но многие коммерческие продукты за время жизни переписываются с нуля много раз
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 11:09
Оценка:
Здравствуйте, 0x7be, Вы писали:

0>Здравствуйте, VladD2, Вы писали:


VD>>Да, КО! Для любой сложной задачи нужны подходящие инструменты. И если инструменты сложны, то для их изучения нужно больше усилий. Но без этого сложные задачи не решить.

VD>>То же самое происходит и со знаниями. Чем более сложная задача, тем больше базовых знаний нужно для ее понимания и решения.
VD>>Причем тут ДСЛ-и и МП? Это же общая проблема сложных задач.
0>Мы с тобой одинаково мыслим, так что относительно тебя я — КО.
0>А, вот, Eye of Hell так не думает

Увы. Меня, как программиста с большим стажем конечно очень волнует технологическая сторона вопроса. Трогает судьба Qt и будующее Java. Но как менеджеру мне жизненно необхоимо думать о жизни проектов через полгода, через год, через пять лет. Об изменении хотелок "заказчиков". О том, что будет если вот этот и вон тут программисты завтра уйдут в Яндекс или лягут в больницу. Поэтому в условиях не нишевых задач (напомню, что я занимаюсь коробочными продуктами, в данный момент это radmin) я вынужден выбирать не подходящий инструмент, а инструмент который будет наиболее предсказуемым и который легко смогут использовать другие люди в будующем. Тут, понятное дело, как и везде приходится проводить некую черту, чтобы н скатиться к использованию чистого C и WinAPI . Но проблема выбора технологий — это отдельная песня. Сейчас ведь любую задачу можно решить сотней разных технологий и решений. И невозможно угадать какая более подходящая. Так и работаем -_-.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.02.11 11:22
Оценка: +1
S>К примеру, читать linq в форме query comprehensions всяко проще, чем те же запросы в форме вызовов функций.

конечно, затрудняет, т.к. добавляет сущности сверх необходимости.
query comprehensions ради решения частной задачи: примитивная обработка коллекции — полностью поменяли синтаксис.
при этом если сравнивать плюсы и минусы, то будет следущее:
вместо точек и запятых пишутся пробелы — вкусовщина
параметры функции пишутся без скобок — есть в этом и хорошее, и плохое,
"стандартные" слова(where,select) пишутся с маленькой буквы, а не с большой — вкусовщина
а добавился только один существенный плюс:
присваивание имени одиночному элементу списка происходит один раз, а не в каждой функции


и соответственно, вместо того чтобы научить стандартный синтаксис такой штуке — в язык тащится чужеродный синтаксис для частной маленькой задаче

зы
если взять код
from cust in customers
    where cust.City == "London"
    orderby cust.Name ascending
    select cust;

то этот код и в нормальном синтаксисе хорошо смотрится, если придумать как переменную cust объявлять только один раз,
и как использовать контекстно-зависимые идентификаторы без необходимости указания полного имени
например, так:
customers
.As(cust*)
.Where(cust.City == "London)
.OrderBy(cust.Name, ascending)
.Select(cust)



ззы
ортогональность — наше всё.
а DSL — это нарушает.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.11 11:32
Оценка:
Здравствуйте, DarkGray, Вы писали:
DG>если взять код
DG>
DG>from cust in customers
DG>    where cust.City == "London"
DG>    orderby cust.Name ascending
DG>    select cust;
DG>

DG>то этот код и в нормальном синтаксисе хорошо смотрится, если придумать как переменную cust объявлять только один раз,
DG>и как использовать контекстно-зависимые идентификаторы без необходимости указания полного имени
DG>например, так:
DG>
DG>customers
DG>.As(cust*)
DG>.Where(cust.City == "London)
DG>.OrderBy(cust.Name, ascending)
DG>.Select(cust)
DG>


Это не C#. Это какой-то другой DSL, который явно не лучше, чем query comprehension. Для эксперимента перепиши на честный C#, и тогда станет понятно преимущество нового синтаксиса.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.02.11 11:34
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Да нет, читается он замечательно. Только вот если в самом DSL баги, нужно его поддерживать и расширять — то при отсутствии автора это превращается в небольшой филиал ада. Не всегда, конечно, но часто

Как раз в этом-то всё и дело. Код пишется один раз, а читается — много. Поэтому мучительные инвестиции в DSL должны окупиться за счёт того, что потом программы на DSL будет проще читать.

S>>Мне вот кажется, что как минимум не всегда. К примеру, читать linq в форме query comprehensions всяко проще, чем те же запросы в форме вызовов функций.


EOH>А теперь попробуйте модифицировать сам LINQ

Это, имхо, неудачный пример. Linq вшит в компилятор намертво — кстати, и даже с ним народ ухитряется так корёжить семантику, что только ух! У Барта де Смета есть linq to Z3.

EOH>Ну, работает много чего. Но многие коммерческие продукты за время жизни переписываются с нуля много раз
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.02.11 11:41
Оценка: +1
S>Это не C#.

конечно, не c#, там в сообщении об этом написано, если ты конечно его читал.
но это в C# можно было добавить, и было бы намного полезнее, чем херотень с query comprehensions

и соответственно, моя основная мысль:
что менять синтаксис под частные задачи особого смысла не имеет,
и что синтаксис имеет смысл менять глобально, повышая его ортогональность и выразительность.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.02.11 11:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Eye of Hell, Вы писали:


EOH>>

Если синтаксис действительно настолько крут, что настолько уменьшает количество кода, то затраты на обучение ему (совсем не такие большие как кажутся) окупаются скоростью разработки и качеством результата.


EOH>>Увы, практика показывает что код больше читается / поддерживается, нежели пишется.

S>С этим утверждением никто не спорит. Вот в чём вопрос: ты считаешь, что введение custom syntax затруднит чтение?
Введение произвольной кастомизации синтаксиса — затруднит.

S>Мне вот кажется, что как минимум не всегда. К примеру, читать linq в форме query comprehensions всяко проще, чем те же запросы в форме вызовов функций.

query comprehensions — скорее антипример. Во-первых он основан на дофига проработанной теоретически и практически конепции монад. Во-вторых довольное сильное влияние на query comprehensions произвел не менее проработанный SQL. Несмотря на то что linq дает очень много возможностей это далеко не custom syntax, а хорошо продуманное и теоретически обоснованное расширение языка. Сомневаюсь что средний разработчик сможет такое расширение сделать.

S>И таких вариантов ещё много.

На самом деле очень мало.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.02.11 11:46
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>query comprehensions ради решения частной задачи: примитивная обработка коллекции — полностью поменяли синтаксис.


А ты Rx видел? А Reacive Parsers? А Linq to Z3?

Покажешь где там "примитивная обработка коллекции"?
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.02.11 11:56
Оценка:
DG>>query comprehensions ради решения частной задачи: примитивная обработка коллекции — полностью поменяли синтаксис.

G>А ты Rx видел? А Reacive Parsers? А Linq to Z3?


почему там недостаточно обычных extension?
Re[10]: Способно ли метапрограммирование заменить отдельные
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.02.11 12:00
Оценка:
Здравствуйте, DarkGray, Вы писали:


DG>>>query comprehensions ради решения частной задачи: примитивная обработка коллекции — полностью поменяли синтаксис.


G>>А ты Rx видел? А Reacive Parsers? А Linq to Z3?


DG>почему там недостаточно обычных extension?

Обычные extension оказываются более многословные и требуют гораздо больше скобочек в записи.
Именно поэтому и придумывают синтаксис для монад, а не используют вызовы методов.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.02.11 12:15
Оценка:
DG>>почему там недостаточно обычных extension?
G>Обычные extension оказываются более многословные и требуют гораздо больше скобочек в записи.
G>Именно поэтому и придумывают синтаксис для монад, а не используют вызовы методов.

что не хватает в C# синтаксисе для того, чтобы работать с монадами так же, как из linq comp?

зы
ответ. не хватает только:
аналогов слов from и let, которые умеют навешивать алиасы с областью видимости до конца statement-а,
автоматической конвертации выражения в лямбду(делегат), если функция объявлена как принимающая лямбду
Re[10]: Способно ли метапрограммирование заменить отдельные
От: 0x7be СССР  
Дата: 05.02.11 12:46
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Увы. Меня, как программиста с большим стажем конечно очень волнует технологическая сторона вопроса. Трогает судьба Qt и будующее Java. Но как менеджеру мне жизненно необхоимо думать о жизни проектов через полгода, через год, через пять лет. Об изменении хотелок "заказчиков". О том, что будет если вот этот и вон тут программисты завтра уйдут в Яндекс или лягут в больницу. Поэтому в условиях не нишевых задач (напомню, что я занимаюсь коробочными продуктами, в данный момент это radmin) я вынужден выбирать не подходящий инструмент, а инструмент который будет наиболее предсказуемым и который легко смогут использовать другие люди в будующем. Тут, понятное дело, как и везде приходится проводить некую черту, чтобы н скатиться к использованию чистого C и WinAPI . Но проблема выбора технологий — это отдельная песня. Сейчас ведь любую задачу можно решить сотней разных технологий и решений. И невозможно угадать какая более подходящая. Так и работаем -_-.

Я думаю, что это не вопрос предсказуемости, а вопрос баланса между стоимостью вхождения и стоимостью разработки и сопровождения. И DSL и фреймворки увеличивают стоимость вхождения, поскольку требуют освоения. Они же дают выгоду — ускоряют разработку и упрощают сопровождение. В какую сторону смещать этот баланс, это вопрос другой. На него нельзя ответить, оставаясь исключительно в технической плоскости, тут я с тобой соглашусь. Например, плохо иметь высокую стоимость вхождения, если компания может позволить себе только студентов, с вытекающими из этого последствиями: низкой квалификацией и высокой текучкой. Но, хочу повториться: мой поинт в том, что принципиальной разницы между DSL и фреймворками в этом смысле нет. Я даже так скажу — DSL это всего лишь более удобный способ представления фреймворка
Re[12]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.11 13:11
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>С этим я не спорю. Я против того, чтобы Вася вместо использования Qt, PEG или Antlr сел и написал собственное расширение к C++ и потом радостно использовал его, к примеру, для чтения конфиг файлов. Потому что когда он уволится — этот его велоспиед кому-то поддерживать. И будет он, скорее всего, реализован намного хуже чем тот же Boost::Spirit .


А откуда возьмутся эти Qt, PEG, Antlr или Boost::Spirit, если никто не будет создавать нового?

Пойми, никто не спорит, с тем что если есть готовое решение удовлетворяющее потребности, то глупо создавать новое.

Но для массы задач таких решений нет. Чем более специфична задача, тем меньше шансов найти готовое решение.

По-твоему получается, что если готового решения нет, то надо или поднять лапки к верху и ничего не делать, или тупо писать все от печки на уровне близком к плинтусу. Но это же глупо! Получается что боясь сложности ты призываешь к многократному ее увеличению.

EOH>P.S. И вообще, вы как-то настоятельно клоните к задачам создания парсеров.


Потому что сами этим занимаемся, и потому что это хрестоматийный пример использования ДСЛ-я.

EOH>В рамках программирования вообще это не самая частая задача. DSL чаще используется для задания поведения программы, нежели для создания собственного языка программирования.


ДСЛ есть ДСЛ в любой задаче. Просто грамматики — это очень очевидный пример. А так примеров масса. Те же Рельсы, например.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.02.11 13:23
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Напоминаю свою точку зрения: вместо написания собственных DSL для решения задач, не связанных с разработкой компиляторов, предпочтительнее использовать либо уже существующие библиотеки, которые известны широким нанимаемым массам, либо уже существующие DSL, которые так же известны широким массам.


О, да КО! Предлагаю больше не повторять эту банальность. Я даже больше скажу, ДСЛ не стоит использовать, если решение с ним и решение без него приблизительно равнозначны.

EOH>А вот свои DSL за исключением редких случаев лучше, ИМХО, не писать.


А вот это утверждение неверно. И убедительных обоснований к нему не приведено. Да и как их привести то к ошибочной позиции?

Свои ДСЛ-и писать можно и нужно. Но как и любой другой код это должно быть: а) действительно необходимо (т.е. давать ощутимые преимущества), б) ДСЛ должен быть тщательно спроектирован и продуман, в) ДСЛ должен быть качественно реализован на подходящих для этого средствах.

То что твое опыт негативный никак не может влиять на сам подход. Просто вы нарушали одно (или несколько) из приведенных выше условий.

Вообще одно то, что вы пишите ГУЙ на С++ уже говорит о том, что средства разработки под задачи вы подбираете, мягко говоря, не очень хорошо. Плюс применимы только в одном случае — когда нужно выжимать из процессора последние биты. Для гуя есть масса куда более подходящих средств.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 05.02.11 14:31
Оценка: 47 (1)
Здравствуйте, Eye of Hell, Вы писали:

EOH>С этим никто не спорит. Автор интересовался, что в мейнстриме со встраиванием DSL в язык. Я рассказал про проблемы. Понятное дело, что кому надо — те используют. Но в мейнстрим, ИМХО, не пойдет — страшно. Вот посмотрим года через 3-4 что будет с руби в мейнстриме — он как бы под DSL заточен.


Руби и рельсы давно уже в мейнстриме. Подавляющее большинство веб решений выбирают между PHP, Rails, Django, ASP.NET и Java. 5 лет рельсы пережили и пережили неплохо. А самому руби скоро 20 лет будет.

Посмотри на все популярные ruby gems, там сплошное метапрограммирование и DSLи. Не стесняются люди применять метапрограммирование и DSL как в своих проектах, так и использовать чужие.

Кстати, в руби вообще нет защиты от конфликтов, один gem определит свой String.to_html, другой — свой, средств для борьбы с этим нет вообще. Победит будет подключен последним, и ничего, живут.

Там давно стерлась грань между синтаксисом руби и синтаксисом библиотеки:
class MyClass
  singleton :per => :request
end


Этот код сложно читать и поддерживать? Да я уверен, что его смогут понять люди не знакомые с руби вообще, не то, что с библиотекой которая это реализует. Для этого надо знать паттерн синглтон и немного о вебе. А ведь его семантика не говорит нам ровно ничего что могло бы помочь нам понять, что делает этот вызов.

Давай не будем про формоклепов, вот ты сам, придя на новый проект, что быстрее поймешь, код выше или:
public class MyClass
{
  public MyClass() {} // заметь, конструктор придется оставит публичным, для того, чтобы DI контейнер мог его юзать
  // тут нужно тайное знание, что этот класс нельзя создавать явно, только через DI
}
// плюс еще огромный макаронный конфиг черт знает где, который содержит строчку
container.RegisterType<MyClass>(new HttpContextLifetimeManager());


А для низкоквалифицированных разработчиков метапрограммирование просто незаменимо. Они могут начать его использовать совершенно не понимая, что происходит под капотом. Не имея квалификации написать тот код, который будет сгенерен у них обычно не выходит.

Знаком код?
private MyCoolClass _myCoolClass;
public MyCoolClass MyCoolClass
{
  get 
  { 
    if (_myCoolClass == null)
    {
       _myCoolClass = new MyCoolClass();
    }
    return _myCoolClass;
  }
}

Его писал наверное каждый C# программист хоть раз в жизни. В нем есть проблема, про которую не подозревают многие формоклепы, он не является thread safe.

В nemerle это делается так:
public MyCoolClass: MyCoolClass
{
  [Memoize]
  get 
  { 
    MyCoolClass()
  }
}


Все, оно по умолчанию надежно. Спец, который точно знает, что многопоточности не будет, а лишние локи ему не нужны — отключит синхронизацию в параметрах макроса.
Re[15]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 05.02.11 14:40
Оценка:
Здравствуйте, Real 3L0, Вы писали:

VD>>Что-то я не понял. "точко-запятуюшная" пунктуация вроде бы есть и в С++ и в шарпе. Так о чем ты?


R3>Например:

R3>
R3>~
R3>*
R3>&
->>
R3>::
>>>
R3><<
R3>

R3>.NET показал, что это не нужно.

Ничего не понятно. Ты бы лучше показал пример на C# и аналогичный на nemerle, чтобы понять, что конкретно не нравится.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 05.02.11 14:44
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>А теперь представьте на секунду, что вместо документированного, с книгами/блогами/евангелистами asp.net у вас написанный пять лет назад Васей Пупкиным фреймворк с собственным DSL. Без хорошей документации, с кучей написанного слабыми программистами кода (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много) и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.


Ты уверен, что проблема именно в том, что этот фреймворк был с собственным DSL?
Re[12]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 05.02.11 15:57
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Давайте попробую так сформулировать: "написать правильный DSL который был бы правильным как в использовании так и в поддержке сложнее, нежели написать правильную библиотеку. Поэтому мейнстрим за библиотеками".

Это не правда.
Там где ДСЛ уместен ДСЛ сделать проще.

EOH>Я же не против DSL вообще. Понятное дело, что для частного случая можно и нужно использовать то, что для этого частного случая будет лучше. Но если у меня команда 20+ человек и старший программист Вася приползает ко мне со словами "а вот давай я тут DSL вверну, оно понятнее будет" — я не разрешу. Потому что сейчас Вася тут, а завтра в Яндексе. И что он там напишет — непонятно. Пусть лучше кода будет немного больше, зато у проекта через год головной боли будет меньше.

1)Ты в одном абзаце противоречишь сам себе.
2)Вся жизнь состоит из частных случаев.
3)Немного больше кода это во сколько раз? В два? В три? В десять? В сто?

Я однажды на С++ написал кодогенератор который генерировал примерно столькоже кода сколько занимал сам.
Сделал я это по тому что кодогенератор был прост, а вот генерируемый код содержал кучу мутных связей и волшебных чисел.
Более того при небольших изменениях исходной модели весь генерируемый код менялся до неузноваемости.

EOH>ИМХО не очень удачный пример потому что эксплоитит ту область, в которой DSL must have — создание парсеров. Но ведь парсеры не так часто создаются?

Так у меня еще есть...
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/ComputationExpressions/Test/AsyncTest.n
http://nemerle.org/wiki/index.php?title=Late_Binding_Macro
И список можно продолжать долго.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 05.02.11 16:11
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>А там под области есть. MVC для GUI,

Реактивный MVVM гораздо лучше. Но для него ДСЛ нужен.

EOH>threadpool для распределения задач, marhsalling для передачи данных и прочее. А вот когда народ вместо того, чтобы взять QThreadPool пишет свой велосипед потому что "так будет на пять процентов быстрее и расширяемее" — то при условии, что мы не пишем кластер, у нас сразу проблемы.

К сожелению стандартные вещи не всегда подходят.
Все идет к тому что мне придется написать пул потоков для немерле 2.
Ибо поведение стандартного заточено на IO а у нас много CPU.

EOH>Ну так я про общий случай, а не про частности. Понятно что для каждого случая мы стараемся применять лучшие инструменты и подходы. Но, ИМХО, в общем случае стандартные подходы более благотворно влияют на поддерживаемость проектов.

Нут так жизнь состоит из частных случаев.

EOH>А добавлять свои DSL на пустом месте — это ой.

А кто говорит про пустое место?

EOH>Коллега, как я уже говорил, вы взяли крайне удобный ракурс для обсуждения DSL — написание компиляторов . То, что для написания компилятора DSL — это единственное разумное и естественное решение я не спорю. Но ведь топикстертер наверняка не про разработку компиляторов спрашивал? ^_^. Да и оцените объем задач по разработке компиляторов по отношению к остальным задачам разработки — это, ИМХО, достаточно узкая ниша.

Так ведь есть много других задач в которых ДСЛи заруливают не на два порядка, а всего на один.
Но в 10 раз меньше кода это тоже очень существенно.
Да даже такие мелочи как Record экономят кучу времени и сил.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 05.02.11 16:15
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Программирование — оно большое. Я рассматриваю со своей колокольни — создание коммерческих, коробочных продуктов. Тоесть ПО для продажи. А вы для чего DSL использовали? Вольфхаунд, Хардкейс — выскажитесь пожалуйста, дабы сравнить.

ДСЛ создается для удаления из кода паттернов которые по другому не удалить.

EOH>И не раз приходилось видеть, когда на создание, поддержку и багфикс DSL в рамках компании/отдела уходило намного больше времени, чем было бы потрачено если просто взять и написать код вручную. А когда автор покидал компанию, начинался тихий ужас, потому что ИМХО есть очень мало людей, которые могут сделать действительно качественный DSL. А руби тогда был менее популярен . И приходилось потом тратить еще больше времени чтобы разобраться в ЭТОМ. Уж лучше бы он в своих двух проектах вручную конфиги читал .

Ну так может это по тому что автор использовал плохие инструменты?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: WolfHound  
Дата: 05.02.11 16:18
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Да нет, читается он замечательно. Только вот если в самом DSL баги, нужно его поддерживать и расширять — то при отсутствии автора это превращается в небольшой филиал ада. Не всегда, конечно, но часто

Скажем тот же Nemerle.Peg люди правят и без меня.
Может дело в авторе и/или инструментах?

EOH>А теперь попробуйте модифицировать сам LINQ

В немерле 2 такие модификации будут делаться на раз.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[12]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 05.02.11 16:51
Оценка: +1
Здравствуйте, Eye of Hell, Вы писали:

EOH>>>Чем проще код — чем лучше он переживает ротацию кадров.

IT>>Что в данном случае подразумевается под "проще"?

EOH>Проще — это значет, что после того как автор кода покидает компанию, нанятый на его место сотрудник сравнимой квалификации может без усилий поддерживать и модифицировать этот код.


Так не бывает. Примитивными инструментами (включая примитивные мозги) сложные задачи просто решать нельзя. Так что ты где-то лукавишь. Либо у вас несложные задачи, либо всё же требуются усилия и немалые, чтобы поддерживать то, что у вас есть, либо квалификация твоих сотрудников на вполне приличном уровне.
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 05.02.11 16:57
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>А теперь представьте на секунду, что вместо документированного, с книгами/блогами/евангелистами asp.net у вас написанный пять лет назад Васей Пупкиным фреймворк с собственным DSL. Без хорошей документации, с кучей написанного слабыми программистами кода (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много) и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.


Найми трёх, а лучше четырёх индусов на зарплату двоих. Заменяемость Вась Пупкиных повысится неимоверно. Любой винтик в команде можно будет без труда заменить таким же тупым. Вот только что они тебе нарешают? К сожалению, к IQ не применима функция сложения, работает только функция Max и 10 индусов с IQ равным 10 никогда не решат качественно задачу, требующую IQ 100.
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 17:25
Оценка:
Z>Руби и рельсы давно уже в мейнстриме. Подавляющее большинство веб решений выбирают между PHP, Rails, Django, ASP.NET и Java. 5 лет рельсы пережили и пережили неплохо. А самому руби скоро 20 лет будет.

Я бы сказал что именно в мейнстриме они пару лет. То, что они появились пять лет назад — они же сразу мейнстримом не стали? .

Z>Посмотри на все популярные ruby gems, там сплошное метапрограммирование и DSLи. Не стесняются люди применять метапрограммирование и DSL как в своих проектах, так и использовать чужие.Кстати, в руби вообще нет защиты от конфликтов, один gem определит свой String.to_html, другой — свой, средств для борьбы с этим нет вообще. Победит будет подключен последним, и ничего, живут.

Там давно стерлась грань между синтаксисом руби и синтаксисом библиотеки:

Вот года через три-четыре и узнаем, хорошо это или плохо

Z>
Z>class MyClass
Z>  singleton :per => :request
Z>end
Z>

Z>Этот код сложно читать и поддерживать? Да я уверен, что его смогут понять люди не знакомые с руби вообще, не то, что с библиотекой которая это реализует. Для этого надо знать паттерн синглтон и немного о вебе. А ведь его семантика не говорит нам ровно ничего что могло бы помочь нам понять, что делает этот вызов.

Это, на мой взгляд, не очень хороший пример — он маленький. Да, ЭТО легко прочесть и, я думаю, нетрудно будет поддерживать. Но в сложном коммерческом проекте хотя бы от миллиона строк исходников DSL будет несколько слоажнее — и тут то проблемы и начнутся.

Z>А для низкоквалифицированных разработчиков метапрограммирование просто незаменимо. Они могут начать его использовать совершенно не понимая, что происходит под капотом. Не имея квалификации написать тот код, который будет сгенерен у них обычно не выходит.


При этом они полностью зависят от тех, кто поддерживает сам DSL. Стоит такому человеку / людям уволиться или заболеть — у нас двадцать формоклеперов с проблемами ^_^.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 05.02.11 17:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Все идет к тому что мне придется написать пул потоков для немерле 2.

WH>Ибо поведение стандартного заточено на IO а у нас много CPU.

На это смотрел?
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 17:39
Оценка:
EOH>>Давайте попробую так сформулировать: "написать правильный DSL который был бы правильным как в использовании так и в поддержке сложнее, нежели написать правильную библиотеку. Поэтому мейнстрим за библиотеками".
WH>Это не правда.
WH>Там где ДСЛ уместен ДСЛ сделать проще.

Тут, я думаю, никто из нас не сможет аргументировать свою позицию — не думаю, что есть репрезентативная статистика по данному вопросу

EOH>>Я же не против DSL вообще. Понятное дело, что для частного случая можно и нужно использовать то, что для этого частного случая будет лучше. Но если у меня команда 20+ человек и старший программист Вася приползает ко мне со словами "а вот давай я тут DSL вверну, оно понятнее будет" — я не разрешу. Потому что сейчас Вася тут, а завтра в Яндексе. И что он там напишет — непонятно. Пусть лучше кода будет немного больше, зато у проекта через год головной боли будет меньше.

WH>1)Ты в одном абзаце противоречишь сам себе.
WH>2)Вся жизнь состоит из частных случаев.
WH>3)Немного больше кода это во сколько раз? В два? В три? В десять? В сто?

1) Где? O_O
2) Мой опыт показывает, что в разработке можно для большей части случаев выделить много общего.
3) Это зависит от контекста задачи, сами понимаете. В каждом конкретном случае нужно принимать решение. Я — за то, чтобы учитывать проблемы с DSL при поддержке.

EOH>>ИМХО не очень удачный пример потому что эксплоитит ту область, в которой DSL must have — создание парсеров. Но ведь парсеры не так часто создаются?

WH>Так у меня еще есть...
WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
WH>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/ComputationExpressions/Test/AsyncTest.n
WH>http://nemerle.org/wiki/index.php?title=Late_Binding_Macro
WH>И список можно продолжать долго.

Парсер XML, парсер языка юнит-тестов, и расширение языка. Про первые два я писал. Про расширение языка... Ну пока оно одно — оно безвредно. Когда из будет полторы сотни как в ядре FreeBSD — у нас будут проблемы.
Re[15]: Способно ли метапрограммирование заменить отдельные
От: WolfHound  
Дата: 05.02.11 17:42
Оценка:
Здравствуйте, IT, Вы писали:

IT>На это смотрел?

Влад мне этой байдой все уши прожужал пока я ему с рефлектором на перевес не показал что там происходит на самом деле...
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 17:47
Оценка:
EOH>>Проще — это значет, что после того как автор кода покидает компанию, нанятый на его место сотрудник сравнимой квалификации может без усилий поддерживать и модифицировать этот код.
IT>Так не бывает. Примитивными инструментами (включая примитивные мозги) сложные задачи просто решать нельзя. Так что ты где-то лукавишь. Либо у вас несложные задачи, либо всё же требуются усилия и немалые, чтобы поддерживать то, что у вас есть, либо квалификация твоих сотрудников на вполне приличном уровне.

Я к этому стремлюсь. И соответственно процессы стараюсь поставить так, чтобы они к этому постремлялись. Это такая недостижимая цель — но, на мой взгляд, она достаточно хорошая . Про сложные задачи — есть такие хорошие вещи как декомпозиция и уровни абстракции . И DSL я рассматриваю как один из уровней абстракции со своими плюсами (бесспорными) и минусами (по поводу которых уже четвертый день тут обсуждаем).
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 17:53
Оценка:
VD>А откуда возьмутся эти Qt, PEG, Antlr или Boost::Spirit, если никто не будет создавать нового?

Новое пусть высококлассные архитекторы создают, которые в этом разбираются.

VD>По-твоему получается, что если готового решения нет, то надо или поднять лапки к верху и ничего не делать, или тупо писать все от печки на уровне близком к плинтусу. Но это же глупо! Получается что боясь сложности ты призываешь к многократному ее увеличению.


Вы утрируете мою позицию — она не настолько бинарна. Я за то, чтобы в случаях если есть опции, склоняться к не использованию собственного DSL если можно его не использовать. Понятное дело, что если опций нет то и DSL будем использовать, и на бейсике писать, и ядро патчить. Я просто стараюсь избегать таких практик. Почему — уже четвертый день рассказываю. Возможно, я не прав — время покажет
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 18:02
Оценка: :)
EOH>>А теперь представьте на секунду, что вместо документированного, с книгами/блогами/евангелистами asp.net у вас написанный пять лет назад Васей Пупкиным фреймворк с собственным DSL. Без хорошей документации, с кучей написанного слабыми программистами кода (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много) и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.

Z>Ты уверен, что проблема именно в том, что этот фреймворк был с собственным DSL?


Был бы я уверен — я бы достаточно быстро доказал свою позицию и никто бы тут четыре дня не обсуждал . Не уверен, но практика показывает что без DSL в общем случае попроще поддерживать будет.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 18:07
Оценка:
0>Например, плохо иметь высокую стоимость вхождения, если компания может позволить себе только студентов, с вытекающими из этого последствиями: низкой квалификацией и высокой текучкой.

Соглашусь. Но мне как менеджеру комфортнее работать со средним по рынку. Среднее по рынку Москвы сейчас, увы, довольно низкое. Они и слова то такого "DSL" не знают .

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


Может быть. На личном опыте могу сказать что Qt читается проще чем Rails человеком, который знает C++ и Ruby но не знает соответствующего фреймворка и DSL ^_^.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 05.02.11 18:42
Оценка: 48 (1)
EOH>>А вот свои DSL за исключением редких случаев лучше, ИМХО, не писать.
VD>А вот это утверждение неверно. И убедительных обоснований к нему не приведено. Да и как их привести то к ошибочной позиции?

Были бы убедительные доказательства — вопрос бы не стоял. Могу сказать, что по результатам данной дискуссии я будут думать и, возможно, несколько пересмотрю свои позиции.

VD>Свои ДСЛ-и писать можно и нужно. Но как и любой другой код это должно быть: а) действительно необходимо (т.е. давать ощутимые преимущества), б) ДСЛ должен быть тщательно спроектирован и продуман, в) ДСЛ должен быть качественно реализован на подходящих для этого средствах.


а) Программист среднего уровня не сможет понять, когда это действительно необходмо. А на рынке, увы, проще нанять среднего уровня, нежели высокого. Поэтому я стараюсь просто так в руки DSL никому не давать ^_^.
б) Увы, мало кто может тщательно продумать и спроектировать DSL. На мой взгляд, плохо спроектированный DSL страшнее плохо спроектированного кода .
в) Ну и про качественную реализацию я молчу.

VD>То что твое опыт негативный никак не может влиять на сам подход. Просто вы нарушали одно (или несколько) из приведенных выше условий.


Конечно. Я же не могу позволить себе нанимать только высококлассных программистов .

VD>Вообще одно то, что вы пишите ГУЙ на С++ уже говорит о том, что средства разработки под задачи вы подбираете, мягко говоря, не очень хорошо. Плюс применимы только в одном случае — когда нужно выжимать из процессора последние биты. Для гуя есть масса куда более подходящих средств.


Увы, у меня нет своей компании чтобы единолично выбирать технологии и решения с нуля. Я работаю за деньги с тем, что дадут
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 05.02.11 21:41
Оценка: +1
Здравствуйте, Eye of Hell, Вы писали:

EOH>Это, на мой взгляд, не очень хороший пример — он маленький. Да, ЭТО легко прочесть и, я думаю, нетрудно будет поддерживать. Но в сложном коммерческом проекте хотя бы от миллиона строк исходников DSL будет несколько слоажнее — и тут то проблемы и начнутся.


Да не будет миллиона строк на DSL, нет проектов такой сложности, чтобы предметная область на специальном языке описывалась в миллион строк. Хотя 20 формоклепов способны с помощью копипаста и такой-то матери выдавать по нескольку десятков тысяч строк в день, вне зависимости от используемого языка. Так что твои беспокойства я вполне понимаю.

Z>>А для низкоквалифицированных разработчиков метапрограммирование просто незаменимо. Они могут начать его использовать совершенно не понимая, что происходит под капотом. Не имея квалификации написать тот код, который будет сгенерен у них обычно не выходит.


EOH>При этом они полностью зависят от тех, кто поддерживает сам DSL. Стоит такому человеку / людям уволиться или заболеть — у нас двадцать формоклеперов с проблемами ^_^.


Если эти люди не будут поддерживать DSL, они будут поддерживать в проекте что-то другое, с чем придется взаимодействовать формоклепам. От чего почти наверняка будут примерно те же проблемы у 20 неспособных работать без нянек ребят.

Проблема еще в том, что ты представляешь DSL как совершенно новый язык для которого пишется свой компилятор (ну или что-то подобное по сложности). На самом деле в язык вводятся просто небольшие конструкции, которые пишутся, тестируются и работают. Чтобы поддерживать макры немерла не надо быть семи пядей во лбу. Да и не надо сидеть и поддерживать какой-то там новый язык, надо поддерживать несколько кирпичиков, которые делают код более декларативным. Обезьянки всегда смогут писать код по старому, если вдруг перестали что-то понимать в одном из кирпичиков и объяснить им некому.

На этом месте, те, кто не работал с nemerle начинают сомневаться в совместимости кирпичиков. Поэтому сразу скажу, что проблем с этим обычно нет, по крайней мере я их не видел, не слышал о них и не представляю себе как они могут вылезти.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 01:25
Оценка: +1
Здравствуйте, Eye of Hell, Вы писали:

EOH>Я же не против DSL вообще. Понятное дело, что для частного случая можно и нужно использовать то, что для этого частного случая будет лучше. Но если у меня команда 20+ человек и старший программист Вася приползает ко мне со словами "а вот давай я тут DSL вверну, оно понятнее будет" — я не разрешу. Потому что сейчас Вася тут, а завтра в Яндексе. И что он там напишет — непонятно. Пусть лучше кода будет немного больше, зато у проекта через год головной боли будет меньше.


Это потому, что ты знаешь, что Вася ДСЛ будет делать каменным молотком и взлетит этот ДСЛ только если Вася прыгнет выше головы. А теперь представь, что у Васи есть тул который позволяет делать ДСЛ за пол дня, и результат получается таким очевидным, что его смогут поддерживать дети после недели обучения. И все это не волшебство, а технология описанная в учебнике. Что тогда?

EOH>ИМХО не очень удачный пример потому что эксплоитит ту область, в которой DSL must have — создание парсеров. Но ведь парсеры не так часто создаются?


ДСЛ он много где "должен быть", но вот нет культуры, инструментов и привычки его создания и поддержки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 01:36
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Это, на мой взгляд, не очень хороший пример — он маленький. Да, ЭТО легко прочесть и, я думаю, нетрудно будет поддерживать. Но в сложном коммерческом проекте хотя бы от миллиона строк исходников DSL будет несколько слоажнее — и тут то проблемы и начнутся.


Правда в том, что при правильном использовании ДСЛ-я (по делу) вместо миллиона строк будет 10 тысяч, или хотя бы 100 тысяч. И их поддержка будет не сравнима по сложности.

EOH>При этом они полностью зависят от тех, кто поддерживает сам DSL. Стоит такому человеку / людям уволиться или заболеть — у нас двадцать формоклеперов с проблемами ^_^.


Ну, так требуй чтобы те кто писли ДСЛ-и делали это а) качественно (ты им деньги не малые платишь), б) документируя свой код, и в) смотри чтобы ДСЛ не появлялся ради ЧСВ программиста.

Короче, все просто как не учить уроки. Использование ДСЛ должен давать приемущество овре 9000 по сравнению с лобовыми подходами (рукопашниной или библиотеками). И тогда даже сомнений не возникнет. Или ДСЛ должен быть прост как пробка. Тогда и разговоров о поддержке не возникнет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 01:57
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Да нет, читается он замечательно. Только вот если в самом DSL баги, нужно его поддерживать и расширять — то при отсутствии автора это превращается в небольшой филиал ада. Не всегда, конечно, но часто


На С/С++?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 02:10
Оценка:
Здравствуйте, WolfHound, Вы писали:

EOH>>А теперь попробуйте модифицировать сам LINQ

WH>В немерле 2 такие модификации будут делаться на раз.

Это и в Немерел 1 делается на раз. Код не так уж и сложен:
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/Linq/Macro/LinqImpl.n
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 02:20
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>что не хватает в C# синтаксисе для того, чтобы работать с монадами так же, как из linq comp?


Макросов?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 02:32
Оценка:
Здравствуйте, Real 3L0, Вы писали:

R3>>>Моя мысль в том, что вхождение в проект, использующий более-менне распространённые вещи, может требовать обучения, а может — нет.

VD>>Это не правда.

R3>Почему "не правда",


Потому что вхождение в проект требует вкуривание всего его кода. И если код использует только "более-менне распространённые вещи", то ежу понятно, что вся сложность будет сосредоточена в коде проекта. То что не надо будет учить синтаксис на 5 ключевых слов отнюдь не означает, что не придется копаться в мало-понятных исходниках долгие годы.

VD>>Та же фигня. Только языков было чуть больше. Но ведь это проходит?


R3>Не проходит. Наверное потому, что специфика разработки бизнес-приложений такова: много из того, что предоставляет "предыдущий уровень" языка для разработки бизнес-приложений не нужно.


Причем тут нужно не нужно? Ты плевался от непривычки, так?

R3>>>Я уже раза 3 читал все эти захватывающие отзывы о Немерле и начинал читать о нём, но... меня хватало только до того момента, как начинался идти синтаксис, напоминающий сишную "точко-запятуюшную" пунктуацию (только с ещё большим разнообразием ). Вот этот язык мне не нужен (а также ещё очень большой куче народа).

VD>>Что-то я не понял. "точко-запятуюшная" пунктуация вроде бы есть и в С++ и в шарпе. Так о чем ты?

R3>Например:

R3>
R3>~
R3>*
R3>&
->>
R3>::
>>>
R3><<
R3>

R3>.NET показал, что это не нужно.

Кто показал? Может шарп? Только все перечисленые операторы в C# есть. Ну, кроме ->> и >>> которых нет и в С/С++. Потом это 7 операторов. Не уж того оно так напрягало?

Просто надо понять, что разница между С++ и шарпом не в наборе операторов, а в том что Шарпа — это тпобезопасный (без ансэйфа) язык с автоматическим управлением памятью и причесанной библиотекой. Вот опыт управлению памятью и указателями и становится невостребованным.

Та же фигня и с немерлом. То на что ты тратишь годы для него (при мышлении на нем) просто не проблема. Все паттерны проектирования остаются вдруг в прошлой жизни. Оказывается, что софт можно писать просто по рдугому.

R3>У Немерле — свои "точки в голове". Получается, что лично мне он не нужен. Не те потребности.


Получается, что ты спешишь записаться в стадо трепачей. Вот и все. Очень жаль, что люди вместо осмысления чужого опыта просто ищут банальный отбрех (чтобы не тратить время на изучение нового).

R3>Но вот если с помощью Немерле будет создан супер-пупер язык для разработки бизнес-приложений ...


За тебя никто не создаст супер-язык. Немерл всего лишь "инструмент" снимающий ограничения и оковы. Необходимости работать он не отменят.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 02:36
Оценка:
Здравствуйте, WolfHound, Вы писали:

IT>>На это смотрел?

WH>Влад мне этой байдой все уши прожужал пока я ему с рефлектором на перевес не показал что там происходит на самом деле...

Ага. Они тупо используют стандартный пул.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.02.11 02:42
Оценка: -1
Здравствуйте, Eye of Hell, Вы писали:

EOH>А теперь представьте на секунду, что вместо документированного, с книгами/блогами/евангелистами asp.net у вас написанный пять лет назад Васей Пупкиным фреймворк с собственным DSL.


Ага представил. Вот как-то ради разнообразия написал свой велосипедик:
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
В МС аналог (Рэзор) писали 10 лет. Мне потребовалось неделя. Причем мое решение гибче. Только привязано к немерлу.

Ну, так что там на счет невероятных затрат на ДСЛ-и?

EOH> Без хорошей документации,


Лучше хороший ДСЛ без документации, нежели лобовое решение без нее же (да и с ней не всегда лучше).

EOH>с кучей написанного слабыми программистами кода


Слушай, уволь ты их, а.

EOH> (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много)


Ну, на фиг платить двадцати мудакам по 20 тасяч, когда можно заплатить 100 т.р., но одному-двум программистам?

EOH> и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.


Я смотрю у тебя прямо этот яндекс больной вопрос.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 06.02.11 05:22
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

WH>>Так у меня еще есть...

WH>>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
WH>>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/ComputationExpressions/Test/AsyncTest.n
WH>>http://nemerle.org/wiki/index.php?title=Late_Binding_Macro
WH>>И список можно продолжать долго.

EOH>Парсер XML, парсер языка юнит-тестов, и расширение языка. Про первые два я писал. Про расширение языка... Ну пока оно одно — оно безвредно. Когда из будет полторы сотни как в ядре FreeBSD — у нас будут проблемы.


Первое это не парасер xml, а его билдер. Второе не парсер тестов, а пример тестов на асинхронные продолжения, которые в виде method chain будут выглядеть настолько страшно, что применять их гораздо опаснее для поддержки, чем ввести в проект десяток DSL. Третье это dynamic из 4го фреймворка реализованный за несколько лет до него и сильно дешевле (впрочем Late чуть проще, но свою задачу делает).

Да, это все примеры расширения языка.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 06.02.11 06:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, на фиг платить двадцати мудакам по 20 тасяч, когда можно заплатить 100 т.р., но одному-двум программистам?


Конечно потому, что эффект кирпича пугает.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: FR  
Дата: 06.02.11 09:44
Оценка: :)
Здравствуйте, VladD2, Вы писали:

EOH>>Да нет, читается он замечательно. Только вот если в самом DSL баги, нужно его поддерживать и расширять — то при отсутствии автора это превращается в небольшой филиал ада. Не всегда, конечно, но часто


VD>На С/С++?


На C++ уже есть вещи сильно упрощающие написание EDSL http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/preface.html
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 06.02.11 12:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Eye of Hell, Вы писали:


EOH>>Я же не против DSL вообще. Понятное дело, что для частного случая можно и нужно использовать то, что для этого частного случая будет лучше. Но если у меня команда 20+ человек и старший программист Вася приползает ко мне со словами "а вот давай я тут DSL вверну, оно понятнее будет" — я не разрешу. Потому что сейчас Вася тут, а завтра в Яндексе. И что он там напишет — непонятно. Пусть лучше кода будет немного больше, зато у проекта через год головной боли будет меньше.

VD>Это потому, что ты знаешь, что Вася ДСЛ будет делать каменным молотком и взлетит этот ДСЛ только если Вася прыгнет выше головы. А теперь представь, что у Васи есть тул который позволяет делать ДСЛ за пол дня, и результат получается таким очевидным, что его смогут поддерживать дети после недели обучения. И все это не волшебство, а технология описанная в учебнике. Что тогда?

Тогда я всячески за . Но такого пока нету .
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 06.02.11 12:07
Оценка:
VD>Ага представил. Вот как-то ради разнообразия написал свой велосипедик:
VD>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
VD>В МС аналог (Рэзор) писали 10 лет. Мне потребовалось неделя. Причем мое решение гибче. Только привязано к немерлу.

Ну так таких как ты много не наймешь

EOH>> Без хорошей документации,

VD>Лучше хороший ДСЛ без документации, нежели лобовое решение без нее же (да и с ней не всегда лучше).

Так хороший еще сделать надо .

EOH>>с кучей написанного слабыми программистами кода

VD>Слушай, уволь ты их, а.

И делать все одному?

EOH>> (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много)

VD>Ну, на фиг платить двадцати мудакам по 20 тасяч, когда можно заплатить 100 т.р., но одному-двум программистам?

Проблема высококлассных спецов не только в том, что они берут больше за свои услуги. Им потом замену гораздо труднее искать . Тоесть когда уходит человек на 50-60, можно достаточно легко найти замену. Когда уходит человек на 100 — найти замену гораздо труднее.

EOH>> и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.

VD>Я смотрю у тебя прямо этот яндекс больной вопрос.

У меня туда уходили
Re[16]: Способно ли метапрограммирование заменить отдельные
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 06.02.11 15:57
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Потому что вхождение в проект требует вкуривание всего его кода. И если код использует только "более-менне распространённые вещи", то ежу понятно, что вся сложность будет сосредоточена в коде проекта. То что не надо будет учить синтаксис на 5 ключевых слов отнюдь не означает, что не придется копаться в мало-понятных исходниках долгие годы.


Про архитектуру я уже говорил, что согласен.
Но ведь не редки ситуации, когда человека сажают просто починить один бажик, а это не всегда выливается в изучение всей архитектуры. А починить один бажик в коде, состоящим из знакомых слов всяко проще, чем из незнакомых.

R3>>Не проходит. Наверное потому, что специфика разработки бизнес-приложений такова: много из того, что предоставляет "предыдущий уровень" языка для разработки бизнес-приложений не нужно.

VD>Причем тут нужно не нужно? Ты плевался от непривычки, так?

Не понял, о какой привычке ты говоришь.
Например, сейчас я плююсь на С++ потому, что весь нужный мне код я пишу без использования указателей. В С++ такое не проходило.

R3>>Например:

R3>>
R3>>~
R3>>*
R3>>&
->>>
R3>>::
>>>>
R3>><<
R3>>

R3>>.NET показал, что это не нужно.

VD>Кто показал? Может шарп?


Может шарп.

VD> Только все перечисленые операторы в C# есть. Ну, кроме ->> и >>> которых нет и в С/С++. Потом это 7 операторов. Не уж того оно так напрягало?


Прикольно. Я о них и не знал, потому что всё, что мне надо, можно написать без этих операторов.
Получается, что мне мало надо.

VD>Та же фигня и с немерлом. То на что ты тратишь годы для него (при мышлении на нем) просто не проблема. Все паттерны проектирования остаются вдруг в прошлой жизни. Оказывается, что софт можно писать просто по рдугому.

VD>Получается, что ты спешишь записаться в стадо трепачей. Вот и все. Очень жаль, что люди вместо осмысления чужого опыта просто ищут банальный отбрех (чтобы не тратить время на изучение нового).
VD>За тебя никто не создаст супер-язык. Немерл всего лишь "инструмент" снимающий ограничения и оковы. Необходимости работать он не отменят.

Ок, попробую в четвёртый раз сесть за изучение.
Но пока получается, что немерле мне нужен только для одной цели — чтобы создать более простой язык.
Вселенная бесконечна как вширь, так и вглубь.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.02.11 21:48
Оценка: -1
Здравствуйте, VladD2, Вы писали:

VD>Ага представил. Вот как-то ради разнообразия написал свой велосипедик:

VD>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
VD>В МС аналог (Рэзор) писали 10 лет.
Пруфлинк?
Ты обманываешь.

VD>Мне потребовалось неделя. Причем мое решение гибче. Только привязано к немерлу.


Оно даже на 10% не razor.

Вместо того чтобы по форумам писать (причем откровенное вранье) написали бы лучше этот самый Razor для ASP.NET MVC3.
Re: Способно ли метапрограммирование заменить отдельные язык
От: Lloyd Россия  
Дата: 06.02.11 21:54
Оценка: :)
Здравствуйте, Chrome, Вы писали:

C>Подключаемая грамматика – наподобие подключаемой библиотеки – выглядит очень привлекательной альтернативой полностью определенному языку.

C>Позволяет самим реализовать фичи, которые нужны вам сейчас.
C>Позволяет отказаться от ненужного наследства.
C>Эти два фактора, как мне кажется, являются двужущей силой для изобретения новых языков программирования и смерти существующих.
C>Наличие платформы метапрограммирования резко снижает расходы на создание собственного языка или диалекта существующего.

Неужели пример сопоставления Linux-а и Mac OS вас не навел ни на какие мысли. Конструктор "собери сам" (Linux) никогда не будет лучше, чем тщательно спроектированная система (Mac OS). Так же и с языками.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: night beast СССР  
Дата: 07.02.11 05:17
Оценка:
Здравствуйте, VladD2, Вы писали:

NB>>ты все таки найди время на tex посмотреть.

NB>>думаю, не малую роль в его популярности сыграло наличие в свободном доступе Texbook'a, на пальцах описывающего весь язык.

еще думаю, необходимо наличие централизованного хранилища библиотек (ctan, cpan, чего там у Руби)

VD>Где брать?


исходник
если вдруг надумаешь читать, вышлю перевод русский (djvu).

NB>>Сможете подобное для немерла сделать?


VD>А что там такого не обычного? Вот это не похоже на то о чем ты говоришь?


на книгу конечно не тянет, но да, что-то похожее на это.
Re[13]: Способно ли метапрограммирование заменить отдельные
От: Undying Россия  
Дата: 08.02.11 05:45
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Знаком код?

Z>Его писал наверное каждый C# программист хоть раз в жизни. В нем есть проблема, про которую не подозревают многие формоклепы, он не является thread safe.

И чем код с Memoize лучше? Если программист не подозревает о проблемах с многопоточностью, то откуда он узнает, что здесь надо написать memoize? А если знает, то чем Memoize лучше, тем что буковок меньше?

Memoize на самом деле намного хуже, т.к. lock это универсальный принцип, поняв который один раз, можно решить любую задачу синхронизации. А достоинство Memoize только в большей лаконичности на простейших случаях, зато как только задача становится чуть сложнее (например, надо лочить не весь метод, а его половину или по условию задачи надо одновременно лочиться на несколько объектов синхронизации), человек применявший memoize, но не использовавший lock впадет в ступор.
Re[14]: Способно ли метапрограммирование заменить отдельные
От: Ziaw Россия  
Дата: 08.02.11 09:16
Оценка:
Здравствуйте, Undying, Вы писали:

U>И чем код с Memoize лучше? Если программист не подозревает о проблемах с многопоточностью, то откуда он узнает, что здесь надо написать memoize? А если знает, то чем Memoize лучше, тем что буковок меньше?


Тем, что он декларативно описывает желаемое поведение. Запомнить первый вызов и всегда возвращать его значение.

U>Memoize на самом деле намного хуже, т.к. lock это универсальный принцип, поняв который один раз, можно решить любую задачу синхронизации. А достоинство Memoize только в большей лаконичности на простейших случаях, зато как только задача становится чуть сложнее (например, надо лочить не весь метод, а его половину или по условию задачи надо одновременно лочиться на несколько объектов синхронизации), человек применявший memoize, но не использовавший lock впадет в ступор.


Такой универсальный принцип хорошо реализован в Си. Код без lock становится еще более гибким, при этом все что делает lock реализовать совершенно несложно. Однако там через define творят черт знает что, чтобы от этой универсальности избавиться.
Re[2]: Способно ли метапрограммирование заменить отдельные я
От: Chrome  
Дата: 08.02.11 15:31
Оценка:
Здравствуйте, Lloyd, Вы писали:


L>Неужели пример сопоставления Linux-а и Mac OS вас не навел ни на какие мысли. Конструктор "собери сам" (Linux) никогда не будет лучше, чем тщательно спроектированная система (Mac OS). Так же и с языками.


Ну, если опускаться до такого уровня аргументации,
вот вам другая аналогия:
Перед вами на выбор
1) столовка с комплексным обедом, где комплексный обед в роли "тщательно спроектированной системы"
то есть все выбрали за вас.
2) ресторан — где блюда можно выбрать самому (тот самый конструктор)

чем предпочтете воспользоваться?
Re[3]: Способно ли метапрограммирование заменить отдельные я
От: Lloyd Россия  
Дата: 08.02.11 16:08
Оценка: +1
Здравствуйте, Chrome, Вы писали:

C>Ну, если опускаться до такого уровня аргументации,

C>вот вам другая аналогия:
C>Перед вами на выбор
C> 1) столовка с комплексным обедом, где комплексный обед в роли "тщательно спроектированной системы"
C> то есть все выбрали за вас.
C> 2) ресторан — где блюда можно выбрать самому (тот самый конструктор)

Можно создать самому. Не путайте 2 вещи.

C>чем предпочтете воспользоваться?


Конечно же первое. Ниже — объяснение.

Все будет немножко не так. Не забывайте, что новых продуктов куда как меньше, чем тех, которые развиваются и живут долго.
Т.е. если придерживаться вашей аналогии, вы придете в ресторан, но будет у вас не меню с блюдами, которые умеет делать шеф-повар и делает это хорошо, а стол, заваленый объедками предыдущих посетителей и объедки будут от блюд, которые они сами выдумали и приготовили.

Вам — приятного аппетита, а я как-нибудь стандартным пюре с котлетой обойдусь. С компотом.
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.02.11 23:55
Оценка: +1
Здравствуйте, night beast, Вы писали:

NB>исходник

NB>если вдруг надумаешь читать, вышлю перевод русский (djvu).

Давай.

VD>>А что там такого не обычного? Вот это не похоже на то о чем ты говоришь?


NB>на книгу конечно не тянет, но да, что-то похожее на это.


Ну, так там пока три главы из задуманных шести. Плюс еще должен быть раздел вроде мануала геде будет описание фич и короткие примеры.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.02.11 23:59
Оценка:
Здравствуйте, Ziaw, Вы писали:

VD>>Ну, на фиг платить двадцати мудакам по 20 тасяч, когда можно заплатить 100 т.р., но одному-двум программистам?


Z>Конечно потому, что эффект кирпича пугает.


Сдается мне, что если бы народ был бы по смелее и тупо поддержал бы проект, то и эффекта этого бояться бы не пришлось.

Я хоть сейчас сколочу команду человек из 4-5 которая будет работать очень шустро и качественно. Были бы деньги.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.02.11 00:09
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

VD>>Ага представил. Вот как-то ради разнообразия написал свой велосипедик:

VD>>http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml/Test/Main.n
VD>>В МС аналог (Рэзор) писали 10 лет. Мне потребовалось неделя. Причем мое решение гибче. Только привязано к немерлу.

EOH>Ну так таких как ты много не наймешь


Ошибайся. Я глупее, ленивее и необразованность очень многих из тех кто здесь отстаивает Немерл (да и из тех кто ему противостоит). Но у меня есть дни талант. Я четко чую, что перспективно, а что является сиюминутной фигней. И еще я упорный (не смотря на мою лень).

Макрос подобный Nemerle.Xml сможет сделать 70% тех кто называет себя программистами (после не продолжительного обучения и тренировки).

EOH>>> Без хорошей документации,

VD>>Лучше хороший ДСЛ без документации, нежели лобовое решение без нее же (да и с ней не всегда лучше).

EOH>Так хороший еще сделать надо .


Ага. А ты думаешь, что хороший код легче написать?
Тут есть одна проблема — отсутствие должной методологии. Но это дело тоже наживное.


EOH>>>с кучей написанного слабыми программистами кода

VD>>Слушай, уволь ты их, а.

EOH>И делать все одному?


Не уж то на всей Руси матушке нет нормальных программистов?

EOH>>> (потому что бюджет нерезиновый, а высококлассных программистов мало и хотят они много)

VD>>Ну, на фиг платить двадцати мудакам по 20 тасяч, когда можно заплатить 100 т.р., но одному-двум программистам?

EOH>Проблема высококлассных спецов не только в том, что они берут больше за свои услуги. Им потом замену гораздо труднее искать . Тоесть когда уходит человек на 50-60, можно достаточно легко найти замену. Когда уходит человек на 100 — найти замену гораздо труднее.


Ну, держать их надо! Они же куда эффективнее нежели тех что 50-60.

В общем, манки-драйвен-девелопмнет возможно и работает. Но что-то я не верю, что он эффективен. Кончено же обезьянок сажать писать макросы нельзя. Так что если вы боитесь брать хороших программистов, то Немерл не для вас.

Но на мой взгляд проще взять двух хороших спецов которые написали бы проект за 10 обезьяно. К обезьянок брать на оставшиеся рутинные оператора. Двое человек будут страховать друг друга (уйдет один, другой сможет подготовить им смену). Плюс еще поставить условие, что уход только через 2-4 месяца при условии подготовки смены.

EOH>>> и, что самое обидное — без Васи Пупкина, потому что в Яндекс ушел . Представили? И вам в такой проект нужно нанять двоих человек, потому что бизнес и надо решать задачи.

VD>>Я смотрю у тебя прямо этот яндекс больной вопрос.

EOH>У меня туда уходили


Сочувствую.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.02.11 00:19
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

EOH>Были бы убедительные доказательства — вопрос бы не стоял. Могу сказать, что по результатам данной дискуссии я будут думать и, возможно, несколько пересмотрю свои позиции.


Это приятно слышать. Обычно противники МП и макросов уверены в своих словах на 120%.

EOH>а) Программист среднего уровня не сможет понять, когда это действительно необходмо. А на рынке, увы, проще нанять среднего уровня, нежели высокого. Поэтому я стараюсь просто так в руки DSL никому не давать ^_^.


Ну, очень хорошего спеца найти и правда трудно. Но просто не идиота все же можно. А тут важно именно чтобы человек был не идиот.

EOH>б) Увы, мало кто может тщательно продумать и спроектировать DSL.


Я вот уверен, что зачастую спроектирвоать то сам ДСЛ могут (определить что в нем должно быть и т.п.), а вот реализовать — нет. Но вот тут то встает вопрос на чем реализуется этот самый ДСЛ. Нужны хорошие инструменты и хорошая методологическая база. Тогда все будет ОК.

Немерел 1 уже не плохой интрумент. Немерле 2 будет просто, что называется, супер-тул для ДСЛ-естроителей. Мы упростим создание даже сложных синтаксических конструкций и повысим возможности расширения синтаксиса. Так же я постараюсь сделать ряд статей по методике разработки ДСЛ-ей.

Думаю в итоге получится очень простой в использовании ДСЛ-естроительный язык который снимет проблему сложности создания и поддержки ДСЛ-ей.

EOH>На мой взгляд, плохо спроектированный DSL страшнее плохо спроектированного кода .


А на мой — одна фигня. Наворотить можно и без ДСЛ-ей.

EOH>Конечно. Я же не могу позволить себе нанимать только высококлассных программистов .


Думаю, ты переоцениваешь требования к таким программистам.

EOH>Увы, у меня нет своей компании чтобы единолично выбирать технологии и решения с нуля. Я работаю за деньги с тем, что дадут


Вот это проблема! Куда страшнее и важнее нежели найти программистов способных создавать и поддерживать ДСЛ-и.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.02.11 00:21
Оценка:
Здравствуйте, FR, Вы писали:

VD>>АААААААААА!!! (рвет волосы на голове) И эти люди говорят что Лисп или Немрле сложный?!!!


FR>Да нет там ничего страшного, близко к лиспу.


О чем ты? Ты же привел пример с голимым ручным формированием АСТ!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Способно ли метапрограммирование заменить отдельные
От: IT Россия linq2db.com
Дата: 09.02.11 01:02
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Плюс еще поставить условие, что уход только через 2-4 месяца при условии подготовки смены.


Может сразу в кандалы и на галеры?
Если нам не помогут, то мы тоже никого не пощадим.
Re[17]: Способно ли метапрограммирование заменить отдельные
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.02.11 01:23
Оценка:
Здравствуйте, IT, Вы писали:

VD>>Плюс еще поставить условие, что уход только через 2-4 месяца при условии подготовки смены.


IT>Может сразу в кандалы и на галеры?


2 месяца — это КЗОТ-у. А там его проблемы. Не хочет хорошую зарплату получать, пусть ищет другое место.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: Способно ли метапрограммирование заменить отдельные
От: Lloyd Россия  
Дата: 09.02.11 01:32
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Может сразу в кандалы и на галеры?


VD>2 месяца — это КЗОТ-у.


КЗОТ уже не действует, в Трудовом Кодексе — 2 недели.
Re[11]: Способно ли метапрограммирование заменить отдельные
От: FR  
Дата: 09.02.11 05:42
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>Да нет там ничего страшного, близко к лиспу.


VD>О чем ты? Ты же привел пример с голимым ручным формированием АСТ!


Там пример отвечающий на твое утверждение

За Питон не скажу, а в руби чтобы сгенерировать код (т.е. вычисления) есть только один способ — конкатенация строк.


и показывающий что в питоне легко генерировать код не строками.
Ну и реально чтобы использовать этот модуль не нужно ручками формировать AST.
Re[4]: Способно ли метапрограммирование заменить отдельные я
От: i1yich  
Дата: 26.02.11 23:28
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>более понятен нежели:

VD>
VD>          surroundwith (write_lock)
VD>            foreach(kv in range)
VD>              hashtable.Add(kv.Key, kv.Value);
VD>


Кстати, по поводу изоляции применения этого макроса, вот это определение write_lock и read_lock, оно действует только на файл или целиком на сборку?
[assembly: DefineSurround("read_lock", true, locker.EnterReadLock(), locker.ExitReadLock())]
[assembly: DefineSurround("write_lock", true, locker.EnterWriteLock(), locker.ExitWriteLock())]
Re[5]: Способно ли метапрограммирование заменить отдельные я
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.11 00:47
Оценка:
Здравствуйте, i1yich, Вы писали:

I>Кстати, по поводу изоляции применения этого макроса, вот это определение write_lock и read_lock, оно действует только на файл или целиком на сборку?

I>
I>[assembly: DefineSurround("read_lock", true, locker.EnterReadLock(), locker.ExitReadLock())]
I>[assembly: DefineSurround("write_lock", true, locker.EnterWriteLock(), locker.ExitWriteLock())]
I>


На проект.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.