Re[10]: Языково-ориентированное программирование: следующая
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.06 20:21
Оценка:
Здравствуйте, Oyster, Вы писали:

O>На самом деле, можно и сейчас писать Si.Mass(10), как и раньше, конечно.


Думаю, что Адонц просто не понимает, что kg — это такой забавный оператор явного приведения типов, или даже фунция "int -> Si.Mass".

O>Вообще идею с "физическими литералами" придумал я но вот очень-очень её захотел видеть vdimas.


Думаю, что это та мысль которая что называется витает в воздухе и она приходит в голову всем людям с развитым воображеним и чувством гормонии.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Языково-ориентированное программирование: следующая п
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.06 20:21
Оценка:
Здравствуйте, Oyster, Вы писали:

O>В общем, опять началась охота на ведьм


Точно!

O>Советую снова — попробуй Nemerle и мою библиотеку в действии, прежде чем критиковать их.


Можешь создать некий пакет чтобы его можно было загрузить из Интернета или взять с диска и одним запуском батника попробовать? Ну, и инструкцию к нему, что можно менять...

Думаю, это простило бы ситуацию и убрало бы барьер восприятия. Ведь попробовав на практике многие вопросы бы отпали сами собой.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Языково-ориентированное программирование: следующая
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 21:37
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Нет. И не надо. Учи матчасть. Посмотри как это реализовано и не говори глупостей.


С таким уровнем аргументации далеко не уедешь. Nemrle не распространён, у него даже официальной документации нет. Если знаешь что-то важное — говори, а RTFM неуместен.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[9]: Языково-ориентированное программирование: следующая п
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 21:41
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>
VD>def x : int = любое_выражение;
VD>

VD>"x" будет иметь тип int независимо от того, что за тип выводится из "любое_выражение". Если тип несовместим или требует рантайм-приведения, то компилятор просто откажется компилитовать код.
VD>Надесь, на этом данная дискусиия будет закрыта.

Влад, это понятно, это ты вопроса не понял. Вопрос такой
def acceleration_derivative_by_distance : ?что тут писать? = (acceleration2 - acceleration1) / (coord2 - coord1)
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[9]: Языково-ориентированное программирование: следующая п
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 21:47
Оценка:
Здравствуйте, VladD2, Вы писали:

A>> А ведь это более естественно Да и где гарантия, что никто не забудет это самое k. Ошибка в 1000 раз на пустом месте.

VD>Нда. Тяжолый случай. Рассуждения без малейшено понимания о предмете рассуждения. Еше раж. "10" и "10 kg" разные типы данных для языка. "10" — это int, а "10 kg" это 10 килограм, то есть другой тип данных. Так как нет неявного приведения, то они несовместимы и компилятор выдаст ошибку.

Влад, ты невнимательно читаешь. Ещё раз — "Да и где гарантия, что никто не забудет это самое k"?
То есть вместо 10 kg мы получим 10 g. Между ними как раз очень даже есть преобразование.

A>>Мне подход с явным указанием типов, а не суффиксов, нравиться больше.

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

Влад, давай не будем говорить за всех, ОК?

A>>И, учитывая, что Nemerle язык новый, а Си++ старый, я бы это рассматривал как большой плюс Си++. Хотя конечно на Nemerle всё удобнее.

VD>Логика изумительная. Нет слов! Тогда давай PL1 рассматр как идеальный язык. Оно ведь куда старше.

Влад, ты читаешь, то что я пишу? Я сказал — достоинством Си++ является то, что на нём можно реализовать довольно новые идеи, пусть и не очень удобно. Причём тут идеальный язык?

VD>Короче, мне все меньше и меньеш интересен этот разговр.


Ну если ты просто придумываешь мои слова, вместо того чтобы их читать, тогда и правда не интересно.

VD>"value_t<1, 1, -2>"- это бред сивой кобылы. Эта строчка только в очень багатом воображении может оказаться осмысленной. Между тем имея полноценный ДСЛ описывающий взамиоотношения типов ты в силах описать любую комбинацию очень кратко и понятно.


Нет value_t<1, 1, -2> это величина с разверностью
м*кг
-----
с^2
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[7]: Языково-ориентированное программирование: следующая п
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 21:56
Оценка:
Здравствуйте, VladD2, Вы писали:

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


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

VD>
VD>regexp match (str)
VD>{ | "a+.*" => printf("a\n");
VD>  | @"(?<num : int>\d+)-\w+" => printf("%d\n", num + 3);
VD>  | "(?<name>(Ala|Kasia))? ma kota" =>
VD>     match(name)
VD>     { | Some (n) => printf("%s\n", n)
VD>       | None => printf("noname?\n")
VD>     }
VD>  | _ => printf("default\n");
VD>}
VD>

VD>Думаю, что ты поймешь ее даже незня, что такое match и т.п. Изменение каких приоритетов может нарушить логику этой конструкции?

ОК, очень просто. Насколько я понял тут выполняется одно из нескольких условий (| я воспринял как оператор OR, Если это не так — интуитивная понятность отметается). Пусть str подходит под несколько (why собственно not?). Просто поменяй условия местами — вот и всё.

VD>Если в ДСЛ появляются приоритеты — это это уже путь в неверном направлении. ДЧЛ должен максимально декларативно описывать суть задачи, а макросы превращать это описание в реальный код отрабатывающий ее решение.


Декларативные языки удобнее в использовании, но вот создавать их эффективные реализации труднее. Не говоря уже о хоть каких-то реализациях.

VD>Так что ошибиться в описании ДСЛ-я куад сложенее чем при проектировании библиотеки.


Это ты как великий теоритик говоришь или я всё таки увижу созданный тобой и используемый где либо кроме лаборатории DSL? Подмножества универсальных языков типа XML конфига или кода Designer.cs не в счёт.

VD>Нда. И где я уже видил эту аргументацию? А, у АВК. Когда аргументы по делу кончаются, то почему-то сразу начинаются "аргументы" вроде "Это что серебрянная пуля? Их не быват... Не пудрите мне мозги...".


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

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


Заканчивал курсы маркетологов? Почём брали за месяц?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[9]: Языково-ориентированное программирование: следующая п
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 21:58
Оценка:
Здравствуйте, Oyster, Вы писали:

O>
O>def a : Si.Area = 10 m * 15 m
O>

O>Приведёт к ошибке во время компиляции, т.к. площадь — это не объём. Насколько я понимаю, это именно то, что тебе нужно?

В коде у тебя что-то не то, но понял ты правильно.
А теперь внимание — я хочу тип производной скорости по расстоянию.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Языково-ориентированное программирование: следующая п
От: Lloyd Россия  
Дата: 16.04.06 22:01
Оценка: +2 :))) :)
Здравствуйте, VladD2, Вы писали:

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


Выделенное улыбнуло.
Re[9]: Языково-ориентированное программирование: следующая п
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 22:01
Оценка:
Здравствуйте, Oyster, Вы писали:

O>Кстати, ты всерьёз считаешь, что value_t<1, 1, -2> удобнее хоть в каком-то случае?


Конечно нет. Конечно же для всех базовых величин надо сделать typedef. НО! Если я захочу производную размерность, причём не важно какую, она у меня есть. Причём именно в том виде в котором я её записываю — единицы измерения со степенями, ибо названия нет.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[11]: Языково-ориентированное программирование: следующая
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 22:03
Оценка:
Здравствуйте, Oyster, Вы писали:

O>А если нет, то всё тоже замечательно сработает:

O>
O>def v = Si.Volume(Si.Velocity(30) * Si.Time(20) * 100 cm)
O>

O>Ты бы хоть попробовал, всё-таки, чтобы больше говорить по существу.

А для размерности м^5*кг^3*с^(-7) что писать?

O>Ты, как и vdimas когда-то
Автор: vdimas
Дата: 29.03.06
, всё не можешь понять, что я на Nemerle решил точно ту же задачу, но без скалярных параметров шаблонов, и что скалярные параметры шаблонов для решения этой задачи совсем не нужны. vdimas-а я смог переубедить
Автор: vdimas
Дата: 14.04.06
. Надеюсь, что смогу и тебя


Мне нужен м^5*кг^3*с^(-7), убеждай
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[10]: Языково-ориентированное программирование: следующая
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 22:06
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Можешь создать некий пакет чтобы его можно было загрузить из Интернета или взять с диска и одним запуском батника попробовать? Ну, и инструкцию к нему, что можно менять...

VD>Думаю, это простило бы ситуацию и убрало бы барьер восприятия. Ведь попробовав на практике многие вопросы бы отпали сами собой.

Влад, давай хоть что-то конструктивное сделаем, может интегрировать Nemerle в студию? Чтобы был нормальный проект типа file\new\project\nemerle console application? Дело-то не хитрое, ну на недельку от силы. Ниже этого барьер не опустить. Но с тебя иконки
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[10]: Языково-ориентированное программирование: следующая
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.06 22:10
Оценка: +1
Здравствуйте, adontz, Вы писали:

A>Влад, ты невнимательно читаешь. Ещё раз — "Да и где гарантия, что никто не забудет это самое k"?


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

Надо все же понимать, что имешь дело с полноценной настраиваемой системой типов. И что ты можешь настроить ее как тебе нужно.

A>То есть вместо 10 kg мы получим 10 g. Между ними как раз очень даже есть преобразование.


Тебу тут уже радом объясняли, что с тем же успехом ты можешь перепутать "+" и "*". Это докапывание не по существу.

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

В общем, это не проблема языка.

Лично я вижу что ты пыташся найти проблему там где ее нет. Ну, да ты тут не первый. Я уже привык к пдобному поведению. Оно возникает от нежелания принять новое. Вместо понимания начинаются поиски ведьм.

A>>>Мне подход с явным указанием типов, а не суффиксов, нравиться больше.

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

A>Влад, давай не будем говорить за всех, ОК?


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

A>>>И, учитывая, что Nemerle язык новый, а Си++ старый, я бы это рассматривал как большой плюс Си++. Хотя конечно на Nemerle всё удобнее.

VD>>Логика изумительная. Нет слов! Тогда давай PL1 рассматр как идеальный язык. Оно ведь куда старше.

A>Влад, ты читаешь, то что я пишу? Я сказал — достоинством Си++ является то, что на нём можно реализовать довольно новые идеи, пусть и не очень удобно. Причём тут идеальный язык?


Я не вижу в твоих словах рассуждений о реализации. Я вижу утверждение "С++ старый и это плюс".

VD>>"value_t<1, 1, -2>"- это бред сивой кобылы. Эта строчка только в очень багатом воображении может оказаться осмысленной. Между тем имея полноценный ДСЛ описывающий взамиоотношения типов ты в силах описать любую комбинацию очень кратко и понятно.


A>Нет value_t<1, 1, -2> это величина с разверностью

A>м*кг
A>-----
A>с^2

Это домыслы. На самом деле это какие-то цифирьки дающие весма неинтуитивные побочные эффекты.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Языково-ориентированное программирование: следующая
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 22:16
Оценка: :)
Здравствуйте, VladD2, Вы писали:

A>>Влад, ты читаешь, то что я пишу? Я сказал — достоинством Си++ является то, что на нём можно реализовать довольно новые идеи, пусть и не очень удобно. Причём тут идеальный язык?


VD>Я не вижу в твоих словах рассуждений о реализации. Я вижу утверждение "С++ старый и это плюс".


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

VD>>>"value_t<1, 1, -2>"- это бред сивой кобылы. Эта строчка только в очень багатом воображении может оказаться осмысленной. Между тем имея полноценный ДСЛ описывающий взамиоотношения типов ты в силах описать любую комбинацию очень кратко и понятно.


A>>Нет value_t<1, 1, -2> это величина с разверностью

A>>м*кг
A>>-----
A>>с^2

VD>Это домыслы.

Нажимаем Ctrl+Space.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[11]: Языково-ориентированное программирование: следующая
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.06 23:30
Оценка:
Здравствуйте, adontz, Вы писали:

A>Влад, давай хоть что-то конструктивное сделаем, может интегрировать Nemerle в студию? Чтобы был нормальный проект типа file\new\project\nemerle console application?


Да, на уровне редактирование, подсветка, отладка. К сожалению комлита нет. А отладка кривовата. Но хоть что-то.
Ссылки можно найти здесь:
Re: Микро-аддин для VS 2005
Автор: Oyster
Дата: 06.03.06

Интеграция с IDE
Автор: VladD2
Дата: 10.03.06


A> Дело-то не хитрое, ну на недельку от силы. Ниже этого барьер не опустить. Но с тебя иконки


Какие иконци? С Немерлей уже идут иконки.

Если интересен язык, то могу на этих условиях прислать предварительные версии статей.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Языково-ориентированное программирование: следующая п
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.06 23:30
Оценка: 23 (3)
Здравствуйте, adontz, Вы писали:

A>А ты пробовал?


Естественно, да.

A> Я просил привести пример, но так и не увидел его.


Пример чего? ДСЛ-я? Я тебе их несколько привел.

A>ОК, очень просто. Насколько я понял тут выполняется одно из нескольких условий (| я воспринял как оператор OR, Если это не так — интуитивная понятность отметается).


Почти. Смысл очень похож. Хотя я бы сказал, что "|" используется как некая префиксная запятая.

A> Пусть str подходит под несколько (why собственно not?). Просто поменяй условия местами — вот и всё.


А зачем менять местами? Если ты ифы местами поменяшь, тоже смысл изменится.
К моту же я уже говорил, что если компилятор или макрос может вычислить, что условия идущие после недоступны, то выдается ошибка. С регепсами конечно не просто, но в принципе такую проверку сделать можно.

A>Декларативные языки удобнее в использовании, но вот создавать их эффективные реализации труднее. Не говоря уже о хоть каких-то реализациях.


На то в Немерле и встроена мощьнейшая система макросов. Она является результатом акумуляции опыта большого числа языков имеющих встроенные системы метапрограммирования. С ее помощью создание эффективных алгоритмов реализции резко упрощается. Хотя несомненно, работа есть работа. Но эту работу все равно прийдетя делать.

VD>>Так что ошибиться в описании ДСЛ-я куад сложенее чем при проектировании библиотеки.


A>Это ты как великий теоритик говоришь или я всё таки увижу созданный тобой и используемый где либо кроме лаборатории DSL? Подмножества универсальных языков типа XML конфига или кода Designer.cs не в счёт.


Хм. А почему собственно не в счет? То что я создавал на Немерле пока что пробы пера. Хотя одна из них мне самоу понравилась. Я написал забавный макрос автоматизирующий перевод программ на другие языки. В программе ты используешь строки вида %%"ля-ля-ля $(выражение) тополя", а макрос при компиляции сам их разбирает и генерирует файл заготовку для перевода (в формате ХМЛ). Далее когда программа запускается она читает этот файл и формирует строки. При чтении она проверяет не содержит ли файл строк для текущего языка процесса и если содержит выбирает его. Так что можно изменить этот файл введя текс на других языках и получить переведенную программу. Сама же программа при этом пишется как будто ее не требуется переводить. Более того любая имеющаяса Немерловая программа может быть простой контекстной заменой превращена в переводимую на другие языки.

Вот как выглядит программа с использованием этого макроса:
using Localization;

[assembly: LocalizationFile("Strings.xml")]

using System.Console;

def nums = array[1, 2, 3];
def x = 5;

WriteLine(%%"a=$(nums[1]) x = $x");

def F(y : int){ y * y }
WriteLine(%%"F(3)=$(F(3))");

Вот что формируется в результате компиляции этой программы файл перевода:
<strings>
    <ID_0>
        <en-US>a={0} x = {1}</en-US>
    </ID_0>
    <ID_1>
        <en-US>F(3)={0}</en-US>
    </ID_1>
</strings>

его можно изменить следующим образом:
<strings>
    <ID_0>
        <en-US>a={0} x = {1}</en-US>
    </ID_0>
    <ID_1>
        <en-US>F(3)={0}</en-US>
    <ru-RU>Функция F(3) вернуло значение {0}.</ru-RU>
    </ID_1>
</strings>

а вот как выглядит макрос:
using System;
using System.Console;
using Nemerle.Compiler;
using Nemerle.Collections;
using Nemerle.Macros;
using PT = Nemerle.Compiler.Parsetree;
using System.Text;
using System.IO;
using System.Xml.XPath;

namespace Localization
{
  
  // Meta-attribut which call when assembly loading.
  // It's receive name of localization file nale.
  // The LocalizationString macro write into this file 
  // localization information. Папа мама я.
  [Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeInheritance,
    Nemerle.MacroTargets.Assembly)
  ]
  macro LocalizationFile(fileName : string)
  {
    Helper._fileName = fileName;
    _ = Helper._builder.AppendLine("<strings>");
    // _holder save _builder content to a file when ncc closing.
    Helper._holder = Helper.Holder();
  }

  macro LocalizationString(str : string)
  syntax ("%%", str)
  {
    def exprs = Helper.make_splice_distribution (
      str, ImplicitCTX().Env);

    // Формируем строку формата "str" и список аргуменов (выражений в них подсавляемых).
    def (str, args, _) = exprs.FoldRight(("", [], 0), fun(expr, accumulator)
    {
      // Выделяем из кортежа отдельные значения
      // str - формируемая строка форамата.
      def (str, args, i) = accumulator;
      def x = expr.ToString(); // Преобразуем текущее выражение в строку.
      // Функция Unquot(s) убирает обрамляющие ковычки из строки.
      def Unquot(s) { s.Substring(1).Substring(0, s.Length - 2) }
      // AddTwiceBraces(s) удваиват знаки "{" и "}".
      def AddTwiceBraces(s) { s.Replace("{", "{{").Replace("}", "}}") }
      
      if (x.Length > 0)
      {
        // Если стока начинается с ", то это просто подстрока которую нужно 
        // обработать и добавить в строку формата.
        if (x[0] == '"')
          (str + AddTwiceBraces(Unquot(x)), args, i)
        // иначе это "встроеное" подвыражение выделенное из строки.
        // Для каждого такого подвыражения нужно добавить с форматную строку
        // тег вида {x} где x - это номер подвыражения, а так же добавить выражение 
        // в список выражений которые в посделствии будут формировать параметры.
        else
          (str + "{" + i.ToString() + "}", expr :: args, i + 1)
      }
      else // Если строка пуста, то ничего не делаем.
        accumulator
    });

    // Добавляем в начала списока параметров парамер содержащий строку формата.
    // сам список параметров при этом разворачиваем, так как формировался он в обратном порядке.
    def args = <[ $(Helper.GenerateId() : string) ]> :: args.Reverse();

    // Добавляем тег в файл локализации.
    Helper.AddString(str);
    
    // Формируем выражение форматированного вывода и возвращаем его как результат работы макроса.
    // Этот код заместит вызов макроса. Консрукция ( .. $args) сформирует кортэж с параметрами.
    // В Nemerle кортежи и списки параметров функций равнозначны. Так что можно считать, что 
    // сформирован список парамтеров!
    <[ Localiser._instace.Format( .. $args) ]>
  }

  internal module Helper
  {
    public mutable _cointer : int = 0;
    public mutable _fileName : string;
    public _builder : StringBuilder = StringBuilder();
    public  mutable _holder : Holder;
    
    public GenerateId() : string
    {
      "ID_" + _cointer.ToString()
    }
    
    public AddString(str : string) : void
    {
      _ = _builder.AppendFormat("    <ID_{0}>", _cointer);
      _ = _builder.AppendLine();
      _ = _builder.AppendLine(  "        <en-US>" + str + "</en-US>");
      _ = _builder.AppendFormat("    </ID_{0}>", _cointer);
      _cointer++;
      _ = _builder.AppendLine();
    }

    // Holder save the _builder content to file (with name contain in _fileName) 
    // when ncc closing.
    [Record]
    internal class Holder
    {
      protected override Finalize() : void
      {
        _ = Helper._builder.AppendLine("</strings>");
        File.WriteAllText(Helper._fileName, Helper._builder.ToString());
      }
    }
    
      /** for $(..) expressions:
        - first evaluate expressions
        - store intermediate results in variables
        - return list of evaluators and reference variables in reverse order
     */
    public make_splice_distribution (str : string, _env : GlobalEnv) 
      : list [PT.PExpr]
    {
      mutable seen_non_alnum = false;
      
      def find_end (balance, idx) {
        when (idx >= str.Length)
          Message.FatalError ("runaway $(...) in format string");

        def ch = str[idx];
        seen_non_alnum = seen_non_alnum || !(System.Char.IsLetterOrDigit (ch) || ch == '_');
        match (ch) {
          | ')' when balance == 1 => idx
          | ')' => find_end (balance - 1, idx + 1)
          | '(' => find_end (balance + 1, idx + 1)
          | _ => find_end (balance, idx + 1)
        }
      }

      def find_end_normal (idx) {
        if (idx >= str.Length) idx
        else
          match (str[idx]) {
            | '_' 
            | ch when System.Char.IsLetterOrDigit (ch) => find_end_normal (idx + 1)
            | _ => idx
          }
      }

      def loop (res, idx) {
        if (idx < 0 || idx >= str.Length)
          res
        else if (str[idx] == '$') {
          when (idx + 1 >= str.Length)
            Message.FatalError ("lone `$' at the end of the format string");
          if (str[idx + 1] == '(') {
            def end = find_end (1, idx + 2);
            def expr = str.Substring (idx + 2, end - idx - 2);
            def expr =
              if (expr == "" || expr == "_" || 
                  seen_non_alnum || 
                  System.Char.IsDigit (expr [0])) {
                MacroColorizer.PushUseSiteColor ();
                def expr = MainParser.ParseExpr (_env, expr);
                MacroColorizer.PopColor ();
                expr
              } else if (expr == "this")
                <[ this ]>
              else
                <[ $(expr : usesite) ]>;
            loop (expr :: res, end + 1)
          }
          else if (str[idx + 1] == '$')
            loop (<[$("$" : string)]> :: res, idx + 2)
          else {
            def end = find_end_normal (idx + 1);
            def variable_name = str.Substring (idx + 1, end - idx - 1);
            
            if (variable_name == "") {
              Message.Warning ("expected variable name or expression enclosed with (..) after $ in splice string");
              loop (<[$("$" : string)]> :: res, idx + 1)
            }
            else {
              def expr =
                if (variable_name == "this") <[ this ]>
                else <[ $(variable_name : usesite) ]>;
              loop (expr :: res, end)
            }
          }
        } else {
          def next_idx = str.IndexOf ('$', idx);
          def next_str =
            if (next_idx == -1) str.Substring (idx)
            else str.Substring (idx, next_idx - idx);
          loop (<[ $(next_str : string) ]> :: res, next_idx)
        }
      }

      loop ([], 0)
    } 
  }

  public class Localiser
  {
    public static _instace : Localiser = Localiser();
    
    public this()
    {
      def lang = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
      def defLang = "en-US";
      
      def doc = XPathDocument("Strings.xml");
      def iter = doc.CreateNavigator().Select("/strings/*");

      foreach (vlue :> XPathNavigator in iter)
      {
        mutable langIter = vlue.Select(lang);
        
        when (!langIter.MoveNext()) // Нет строк для этого языка!
        {
          langIter = vlue.Select(defLang);
          when (!langIter.MoveNext())
            throw ApplicationException("No string for ID={0} found.");
        }

        _msgMap.Add(vlue.Name, langIter.Current.Value);
      }
    }

    private _msgMap : Hashtable.[string, string] = Hashtable.[string, string]();

    public Format(msgId : string, params args : array[object]) : string
    {
      string.Format(_msgMap[msgId], args);
    }
  }
}


ДСЛ прост как три копйки хотя и позволяет в выражениях использовать любые конструкции Немерла. Контроль выражений осуществляется самим компилятором. А моя забота только грамотно отработать семантику.

A>Ну так покажи пример. Где он?


Пример чего? Тебе же дали ссылку на огромый ДСЛ описания физ.велечин. Что тебе еще надо? Что за дурацкая привычка делать вид, что ничего не видешь?

A> Нету, одни обещания всех шапками закидать. Я бы и рад поверить тебе, но моим аргументам ты можешь только противопоставить свои, а где факты? А факты удачного использования куда-то спешно удалились.


Есть пустопорожний треп. Но мне кажется он исходит не от меня.

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

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


A>Заканчивал курсы маркетологов? Почём брали за месяц?


Дорого. Тебе не понятуть.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Языково-ориентированное программирование: следующая п
От: adontz Грузия http://adontz.wordpress.com/
Дата: 16.04.06 23:47
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А зачем менять местами?


Чтобы добавить номер версии. вообще я просто привёл пример смены приоритетов. придумывать для такой замены смысл я не буду — это всего лишь пример.

A>>Это ты как великий теоритик говоришь или я всё таки увижу созданный тобой и используемый где либо кроме лаборатории DSL? Подмножества универсальных языков типа XML конфига или кода Designer.cs не в счёт.


VD>Хм. А почему собственно не в счет?


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

VD>Вот как выглядит программа с использованием этого макроса:

VD>[пример поцокан]

Вааа наконецто! Уже лучше! Да, признаю, некоторая ощютимая польза от макросов Nemеrle есть при сохранении условия простоты использования.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[12]: Языково-ориентированное программирование: следующая
От: adontz Грузия http://adontz.wordpress.com/
Дата: 17.04.06 00:09
Оценка: 9 (1) -1
Здравствуйте, VladD2, Вы писали:

Вот за последлнй час сочинил решение на Си++

//
//
// ПИШЕМ СУПЕР ВЕЩЬ!
//
//
#include <Math.h>
//
template <
    int length_power, int weight_power, int time_power,
    typename value_type = double,
    int length_coef_numerator = 1, int length_coef_denominator = 1,
    int weight_coef_numerator = 1, int weight_coef_denominator = 1,
    int time_coef_numerator = 1, int time_coef_denominator = 1>
class physical_value_t
{
    private:
        value_type _value;
    private:
        static const value_type length_coefficient;
        static const value_type weight_coefficient;
        static const value_type time_coefficient;
    private:
        void assign(const physical_value_t & value)
        {
            _value = value._value;
        }
        void assign(const value_type & value)
        {
            _value = value;
        }
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        void assign(const physical_value_t<length_power, weight_power, time_power, vt, lcn, lcd, wcn, wcd, tcn, tcd> & value)
        {
            _value = value.dangerous_dimensionless() *
                pow((((value_type)lcn)/((value_type)lcd))/length_coefficient, length_power) *
                pow((((value_type)wcn)/((value_type)wcd))/weight_coefficient, weight_power) *
                pow((((value_type)tcn)/((value_type)tcd))/time_coefficient, time_power);
        }
    public:
        physical_value_t() : _value(0)
        {
        }
        physical_value_t(const physical_value_t & value)
        {
            assign(value);
        }
        physical_value_t(const value_type & value)
        {
            assign(value);
        }
        
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t(const physical_value_t<length_power, weight_power, time_power, vt, lcn, lcd, wcn, wcd, tcn, tcd> & value)
        {
            assign<vt, lcn, lcd, wcn, wcd, tcn, tcd>(value);
        }

        physical_value_t & operator = (const physical_value_t & value)
        {
            assign(value);
            return *this;
        }
        physical_value_t & operator = (const value_type & value)
        {
            assign(value);
            return *this;
        }
        
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t & operator = (const physical_value_t<length_power, weight_power, time_power, vt, lcn, lcd, wcn, wcd, tcn, tcd> & value)
        {
            assign<vt, lcn, lcd, wcn, wcd, tcn, tcd>(value);
            return *this;
        }

        value_type dangerous_dimensionless() const
        {
            return _value;
        }
        
        physical_value_t operator + (const physical_value_t & right)
        {
            return physical_value_t (_value + right._value);
        }
        
        physical_value_t operator - (const physical_value_t & right)
        {
            return physical_value_t (_value - right._value);
        }
        
        physical_value_t operator * (const value_type & right)
        {
            return physical_value_t(_value * right);
        }
        
        physical_value_t<
            2*length_power, 2*weight_power, 2*time_power,
            value_type,
            length_coef_numerator*length_coef_numerator, length_coef_denominator*length_coef_denominator,
            weight_coef_numerator*weight_coef_numerator, weight_coef_denominator*weight_coef_denominator,
            time_coef_numerator*time_coef_numerator, time_coef_denominator*time_coef_denominator>
                operator * (const physical_value_t & right)
        {
            return physical_value_t<
                2*length_power, 2*weight_power, 2*time_power,
                value_type,
                length_coef_numerator*length_coef_numerator, length_coef_denominator*length_coef_denominator,
                weight_coef_numerator*weight_coef_numerator, weight_coef_denominator*weight_coef_denominator,
                time_coef_numerator*time_coef_numerator, time_coef_denominator*time_coef_denominator>(
                _value * right._value);
        }
        
        physical_value_t operator / (const value_type & right)
        {
            return physical_value_t(_value / right);
        }
        
        physical_value_t<
            0, 0, 0,
            value_type,
            1, 1,
            1, 1,
            1, 1>
                operator / (const physical_value_t & right)
        {
            return physical_value_t<
                0, 0, 0,
                value_type,
                1, 1,
                1, 1,
                1, 1>(
                    _value / right._value);
        }
        
        physical_value_t & operator += (const physical_value_t & right)
        {
            _value += right._value;
            return *this;
        }
        
        physical_value_t & operator -= (const physical_value_t & right)
        {
            _value -= right._value;
            return *this;
        }
        
        physical_value_t & operator *= (const value_type & right)
        {
            _value += right;
            return *this;
        }
        
        physical_value_t & operator /= (const value_type & right)
        {
            _value -= right;
            return *this;
        }
        
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t operator + (const physical_value_t & right)
        {
            return physical_value_t(_value + physical_value_t(right).dangerous_dimensionless());
        }
        
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t operator - (const physical_value_t & right)
        {
            return physical_value_t(_value - physical_value_t(right).dangerous_dimensionless());
        }
        
        template <
            int lp, int wp, int tp,
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t<
            length_power + lp,
            weight_power + wp,
            time_power + tp,
            value_type,
            length_coef_numerator, length_coef_denominator,
            weight_coef_numerator, weight_coef_denominator,
            time_coef_numerator, time_coef_denominator>
                operator * (const physical_value_t<lp, wp, tp, vt, lcn, lcd, wcn, wcd, tcn, tcd> & right)
        {
            return physical_value_t<
                length_power + lp,
                weight_power + wp,
                time_power + tp,
                value_type,
                length_coef_numerator, length_coef_denominator,
                weight_coef_numerator, weight_coef_denominator,
                time_coef_numerator, time_coef_denominator>(
                    _value * right.dangerous_dimensionless() *
                    pow((((value_type)lcn)/((value_type)lcd))/length_coefficient, lp) *
                    pow((((value_type)wcn)/((value_type)wcd))/weight_coefficient, wp) *
                    pow((((value_type)tcn)/((value_type)tcd))/time_coefficient, tp));
        }
        
        template <
            int lp, int wp, int tp,
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t<
            length_power - lp,
            weight_power - wp,
            time_power - tp,
            value_type,
            length_coef_numerator, length_coef_denominator,
            weight_coef_numerator, weight_coef_denominator,
            time_coef_numerator, time_coef_denominator>
                operator / (const physical_value_t<lp, wp, tp, vt, lcn, lcd, wcn, wcd, tcn, tcd> & right)
        {
            return physical_value_t<
                length_power - lp,
                weight_power - wp,
                time_power - tp,
                value_type,
                length_coef_numerator, length_coef_denominator,
                weight_coef_numerator, weight_coef_denominator,
                time_coef_numerator, time_coef_denominator>(
                    (_value / right.dangerous_dimensionless()) *
                    pow((((value_type)lcn)/((value_type)lcd))/length_coefficient, -lp) *
                    pow((((value_type)wcn)/((value_type)wcd))/weight_coefficient, -wp) *
                    pow((((value_type)tcn)/((value_type)tcd))/time_coefficient, -tp));
        }
        
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t & operator += (const physical_value_t & right)
        {
            _value += physical_value_t(right).dangerous_dimensionless();
            return *this;
        }
        
        template <
            typename vt,
            int lcn, int lcd,
            int wcn, int wcd,
            int tcn, int tcd>
        physical_value_t & operator -= (const physical_value_t & right)
        {
            _value -= physical_value_t(right).dangerous_dimensionless();
            return *this;
        }
};
//
template <
    int length_power, int weight_power, int time_power,
    typename value_type,
    int length_coef_numerator, int length_coef_denominator,
    int weight_coef_numerator, int weight_coef_denominator,
    int time_coef_numerator, int time_coef_denominator>
const value_type physical_value_t<
    length_power, weight_power, time_power,
    value_type,
    length_coef_numerator, length_coef_denominator,
    weight_coef_numerator, weight_coef_denominator,
    time_coef_numerator, time_coef_denominator>::length_coefficient = ((value_type)length_coef_numerator)/((value_type)length_coef_denominator);
//
template <
    int length_power, int weight_power, int time_power,
    typename value_type,
    int length_coef_numerator, int length_coef_denominator,
    int weight_coef_numerator, int weight_coef_denominator,
    int time_coef_numerator, int time_coef_denominator>
const value_type physical_value_t<
    length_power, weight_power, time_power,
    value_type,
    length_coef_numerator, length_coef_denominator,
    weight_coef_numerator, weight_coef_denominator,
    time_coef_numerator, time_coef_denominator>::weight_coefficient = ((value_type)weight_coef_numerator)/((value_type)weight_coef_denominator);
//
template <
    int length_power, int weight_power, int time_power,
    typename value_type,
    int length_coef_numerator, int length_coef_denominator,
    int weight_coef_numerator, int weight_coef_denominator,
    int time_coef_numerator, int time_coef_denominator>
const value_type physical_value_t<
    length_power, weight_power, time_power,
    value_type,
    length_coef_numerator, length_coef_denominator,
    weight_coef_numerator, weight_coef_denominator,
    time_coef_numerator, time_coef_denominator>::time_coefficient = ((value_type)time_coef_numerator)/((value_type)time_coef_denominator);
//
//
// УСЁ, ТЕПЕРЬ ИСПОЛЬЗУЕМ
//
//
typedef physical_value_t<1, 0, 0> phys_meter_t;
typedef physical_value_t<0, 1, 0> phys_kilogramm_t;
typedef physical_value_t<0, 0, 1> phys_second_t;
//
typedef physical_value_t<1, 0, 0, double, 1, 100, 1, 1, 1, 1> phys_centimeter_t;
typedef physical_value_t<0, 1, 0, double, 1, 1, 1, 1000, 1, 1> phys_gramm_t;
typedef physical_value_t<0, 0, 1, double, 1, 1, 1, 1, 60, 1> phys_minute_t;
typedef physical_value_t<1, 0, -1> phys_mps_t;
typedef physical_value_t<2, 0, 0> phys_m2_t;
//
int _tmain(int argc, _TCHAR* argv[])
{
    // some tests
    
    phys_meter_t m = 2;
    phys_centimeter_t cm = m;//must be 200
    phys_kilogramm_t kg = 3;
    phys_gramm_t g = kg;// must be 3000
    phys_second_t s = 5;
    phys_minute_t min = s;// must be 0.8333
    phys_mps_t mps = m / s;// must be 0.4
    mps = m / min;//must be still 0.4
    phys_m2_t m2 = m * m;//must be 4
    m2 = m * cm;//must be still 4
    m += cm * 5;// must be 12
    return 0;
}
//
//
// КОНЧАЕМ ИСПОЛЬЗОВАТЬ - ПЕРЕКУР. И ВООБЩЕ ПОРА ЖРАТЬ.
//
//


Я был бы очень признателен если бы ты привёл объективные недостатки использования данного решения и преимущества использования решения на Nemerle.
Заметь, что мой код гораздо меньше при приблизительно одинаковой функциональности — контроль размерностей.
Правда суффиксов нет . Хотя, так на вскидку.
#define kg() * phys_kilogramm_t(1)

Наверное не лучший вариант, просто первое, что в голову пришло. Без operator value_type нормально работать вряд ли будет, но я его специально не сделал.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[7]: Языково-ориентированное программирование: следующая п
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 17.04.06 00:11
Оценка:
Здравствуйте, VladD2, Вы писали:

A>>Влад, создаётся впечатление, что DSL это панацея от всех бед. Я не видел ещё ни одного простого и в тоже время эффективного промышленного языка, даже в пределах предметной области.

A>>А наколеночные поделки не интересны — их и так плодят пачками.

VD>Нда. И где я уже видил эту аргументацию? А, у АВК. Когда аргументы по делу кончаются, то почему-то сразу начинаются "аргументы" вроде "Это что серебрянная пуля? Их не быват... Не пудрите мне мозги...".

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

Вот сказать по-нормальному: "создание DSL в ряде случае вопозволяет решить задачу быстрее и проще" и никакой революции не нужно. Все и так давно об этом знали и не кипятились. Иначе бы не было языков управления пакетной обработкой.

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

VD>Как ООП, ФП и другие парадигмы эта позволяет увеличить сложность решаемых задач впихнув их в довольно скудные возможности мозга человека.


О! Ссылка на "парадигму", как некую самостоятельную сущность.

PS.: В одном ты прав. Действительно, когда мы пишем библиотеку, то по сути, создаём свой DSL.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[12]: Языково-ориентированное программирование: следующая
От: adontz Грузия http://adontz.wordpress.com/
Дата: 17.04.06 01:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если интересен язык, то могу на этих условиях прислать предварительные версии статей.


О! Класс! mailto:adontz@caucasus.net в твоём распоряжении. Что-то, а ругать статьи — моё
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[13]: Языково-ориентированное программирование: следующая
От: Vermicious Knid  
Дата: 17.04.06 01:30
Оценка:
Здравствуйте, adontz, Вы писали:

A>Я был бы очень признателен если бы ты привёл объективные недостатки использования данного решения и преимущества использования решения на Nemerle.


Давай хотя бы сравним вот эту строку из твоего примера:
typedef physical_value_t<1, 0, 0, double, 1, 100, 1, 1, 1, 1> phys_centimeter_t;

С этой строкой из решения Oyster'а:
Length[ cm ] - 1.0 / 100.0,

Мне понадобилось секунды три чтобы понять, что происходит в первом случае(да, я настолько тупой ). И ~0.0 секунд чтобы разобраться во втором.

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


Очень смешно. Во-первых не увидел одинаковой функциональности. У тебя предусмотрены только три вида базовых единиц — масса, длина и время. В решении на Nemerle произвольное количество и причем любых(хоть сам придумывай). Обрати внимание в примере описания вот на это:

    basisUnits (Si)
    (
        Mass,
        Length,
        Time,
        Temperature,
        CurrentStrength,
        LightIntensity,
        QuantityOfSubstance
    )

В решении на Nemerle практически нет хардкодинга и в этом его главное преимущество. Мне честно-говоря даже страшно представить во что превратится твое решение на C++ если скажем понадобится десятка два таких базовых единиц.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.