Автор |
Сообщение |
|
|
Заголовок сообщения: |
|
|
|
Язык и его реализация достигли стадии 0.5.
Как я и говорил, в виду введения макросов наши старые, добрые DUP, SWAP мы больше не увидим.
Также было полностью переписано описание языка, тем более что и сам язык довольно сильно перелицован уже к этой половинной версии, если смотреть от самого начала.
Пара выдержок из описания:
Цитата: Enchilada -- это полностью фукнциональный язык программирования, напоминающий конкатенативный язык Joy. Но, в отличии от Joy, Enchilada прежде всего нацелен на паралельные и распределённые вычисления.
Каждая часть Enchilada -- будь то программа, вычисление или данные -- immutable (?). И так как ничего нельзя изменить (а из этого следует что можно и безопасно разделять), использование языка сулит исключительную надёжность и расширяемость.
Для наибольшей поддержки прямолинейной (?) обработки, Enchilada разработана с принципом: "как можно меньше сюрпризов": программа во время исполнения никогда не вызовет исключения. Программирование без исключений достигнуто тем, что каждый операнд в Enchilada принадлежит только одному типу: списку. Эта особенность делает язык одним из немногих языков, имеющих и строгую типизацию, и один-единственный тип данных.
Язык и его реализация [url=http://my.opera.com/rapido/blog/new-releasev0-5]достигли стадии 0.5[/url].
Как я и говорил, в виду введения макросов наши старые, добрые DUP, SWAP мы больше не увидим.
Также было полностью переписано [url=http://enchilada.javaforge.com/enchilada.html]описание языка[/url], тем более что и сам язык довольно сильно перелицован уже к этой половинной версии, если смотреть от самого начала.
Пара выдержок из описания:
[quote]Enchilada -- это полностью фукнциональный язык программирования, напоминающий конкатенативный язык Joy. Но, в отличии от Joy, Enchilada прежде всего нацелен на паралельные и распределённые вычисления.
Каждая часть Enchilada -- будь то программа, вычисление или данные -- immutable (?). И так как ничего нельзя изменить (а из этого следует что можно и безопасно разделять), использование языка сулит исключительную надёжность и расширяемость.
Для наибольшей поддержки прямолинейной (?) обработки, Enchilada разработана с принципом: "как можно меньше сюрпризов": программа во время исполнения никогда не вызовет исключения. Программирование без исключений достигнуто тем, что каждый операнд в Enchilada принадлежит только одному типу: списку. Эта особенность делает язык одним из немногих языков, имеющих и строгую типизацию, и один-единственный тип данных.[/quote]
|
|
|
|
Добавлено: Пт дек 22, 2006 17:16 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Ну вот, опять математиков вовремя не согнали с клавиатуры
Ну вот, опять математиков вовремя не согнали с клавиатуры :)
|
|
|
|
Добавлено: Сб ноя 25, 2006 13:09 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Интересно, но самую главную особенность Enchilada замечаешь не сразу. Но постепенно до тебя доходит что:
-- Несмотря на то что язык стековый, стек как таковой в реализации Enchilada не нужен.
-- Операции языка могут выполнятся в произвольном порядке и/или паралельно.
-- Выполнение команд языка представляет собой не последовательное выполнение операций (алгоритм, программа), а что-то вроде упрощения алгебраической формулы (не зря там есть операция выведения за скобки), и последовательность команд Enchilada можно например, "объедать" с обоих концов как сосиску.
Это хорошо иллюстрирует уже применённый нами режим трассировки:
Код: > \ost 2 3 + 1 -+ 0: 2 3 + 1 - + 1: 5 1 - + 2: 5 _1 + 3: 4
Вычисления 2 3 + и 1 - можно делать паралельно.
Интересно, но самую главную особенность Enchilada замечаешь не сразу. Но постепенно до тебя доходит что:
-- Несмотря на то что язык стековый, стек как таковой в реализации Enchilada не нужен.
-- Операции языка могут выполнятся в произвольном порядке и/или паралельно.
-- Выполнение команд языка представляет собой не последовательное выполнение операций (алгоритм, программа), а что-то вроде упрощения алгебраической формулы (не зря там есть операция выведения за скобки), и последовательность команд Enchilada можно например, "объедать" с обоих концов как сосиску.
Это хорошо иллюстрирует уже применённый нами режим трассировки:
[code]> \ost 2 3 + 1 -+ 0: 2 3 + 1 - + 1: 5 1 - + 2: 5 _1 + 3: 4[/code]
Вычисления 2 3 + и 1 - можно делать паралельно.
|
|
|
|
Добавлено: Пт ноя 24, 2006 14:33 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Дальше, как уже всегда, начинаем писать факториал на языке. Вслед за автором замечу что для определения факториала не были использованы ни циклы, ни рекурсия.
Как и в случае с K или с бэкФортом нам понадобится операция генерирующая ряд натуральных чисел от 1 до n, где n -- аргумент.
В определении этой функции используется то что числа в Enchilada также являются списками, пусть их элементы и пусты. Помним?
Код: > 3 [1] *| [1;1;1] Или, если посмотреть с другой стороны: Код: > [1] 3 *` [1;1;1] Аналогично: Код: > [1] [1] + [1] + [1;1;1] А теперь что называется, "следи за рукой" (с): Код: > 4 ["1+] *:` [" 1 +;" 1 +;" 1 +;" 1 +] Здесь у нас в скобках по сути тело цикла, которое мы "умножаем", чтобы получить его нужное количество раз. Но циклу нужно начальное значение (чтобы самому первому " -- DUP'у было чего дублировать), поэтому добавляем единичку: Код: > 4 1:["1+] *:` 1 [" 1 +;" 1 +;" 1 +;" 1 +] Потом просто выводим "раскрученный" цикл за скобки операцией ! . Этот пример я покажу в режиме отладки: Код: > \ost 4 1:["1+] *:`! 0: 4 1 : [" 1 +] * : ` ! 1: 1 4 [" 1 +] * : ` ! 2: 1 4 [" 1 +;" 1 +;" 1 +;" 1 +] : ` ! 3: 1 [" 1 +;" 1 +;" 1 +;" 1 +] 4 ` ! 4: 1 [" 1 +;" 1 +;" 1 +;" 1 +] ! 5: 1 " 1 + " 1 + " 1 + " 1 + 6: 1 1 1 + " 1 + " 1 + " 1 + 7: 1 2 " 1 + " 1 + " 1 + 8: 1 2 2 1 + " 1 + " 1 + 9: 1 2 3 " 1 + " 1 + 10: 1 2 3 3 1 + " 1 + 11: 1 2 3 4 " 1 + 12: 1 2 3 4 4 1 + 13: 1 2 3 4 5 Последнее число нам не нужно, поэтому его надо убирать, добавляем ещё один ` -- DROP. То есть функция готова: Код: iotaN == 1:["1+] *:`!` (вот только определение функций у меня не получаются, ошибки какие-то) Заметьте, что результат функции -- ряд чисел мы получаем на стеке, а не в списке-элемента стека. Теперь нужно перемножить полученный натуральный ряд, чтобы получить факториал. Принцип такой же: Код: mulN == 1:[*`] :* ! ! Обратите внимание, mulN берёт со стека одно значение -- нужное кол-во умножений. А полностью факториал из учебника выглядит так: Код: facN == ^ [iotN; mulN] * | ! Сходу что делает facN не особо понять... Первая операция берёт значение с вершины стека и заключает его в скобки, превращая в список. Уже знакомая нам комбинация *|! делает map, но как бы наоборот... Так как у "данных" один элемент, а "функций" две, то Декартово произведение их даст последовательное выполнение обеих функций с одним и тем же аргументом: Код: 12 ^ [iotN; mulN] * | [12] [iotN; mulN] * | [12 iotN;12 mulN] Затем ! выполняет всё остальное, сначала выполняет 12 iotN , он оставляет на стеке ряд чисел, потом выполняется 12 mulN , который делает 12 нужных нам умножений на стеке, сводя всё к одному значению -- факториалу. Вот так он считается в режиме трассировки: Код: 0: 3 ^ [1 : [" 1 +] * : ` ! `;1 : [* `] : * ! !] * | ! 1: [3] [1 : [" 1 +] * : ` ! `;1 : [* `] : * ! !] * | ! 2: [3;3] [1 : [" 1 +] * : ` ! `;1 : [* `] : * ! !] | ! 3: [3 1 : [" 1 +] * : ` ! `;3 1 : [* `] : * ! !] ! 4: 3 1 : [" 1 +] * : ` ! ` 3 1 : [* `] : * ! ! 5: 1 3 [" 1 +] * : ` ! ` 3 1 : [* `] : * ! ! 6: 1 3 [" 1 +] * : ` ! ` 1 3 [* `] : * ! ! 7: 1 3 [" 1 +] * : ` ! ` 1 [* `] 3 * ! ! 8: 1 3 [" 1 +] * : ` ! ` 1 [* `;* `;* `] 3 ! ! 9: 1 3 [" 1 +;" 1 +;" 1 +] : ` ! ` 1 [* `;* `;* `] 3 ! ! 10: 1 [" 1 +;" 1 +;" 1 +] 3 ` ! ` 1 [* `;* `;* `] 3 ! ! 11: 1 [" 1 +;" 1 +;" 1 +] ! ` 1 [* `;* `;* `] 3 ! ! 12: 1 " 1 + " 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 13: 1 1 1 + " 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 14: 1 2 " 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 15: 1 2 2 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 16: 1 2 3 " 1 + ` 1 [* `;* `;* `] 3 ! ! 17: 1 2 3 3 1 + ` 1 [* `;* `;* `] 3 ! ! 18: 1 2 3 4 ` 1 [* `;* `;* `] 3 ! ! 19: 1 2 3 1 [* `;* `;* `] 3 ! ! 20: 1 2 3 1 [* `;* `;* `] ! 21: 1 2 3 1 * ` * ` * ` 22: 1 2 3 3 ` * ` * ` 23: 1 2 3 * ` * ` 24: 1 6 6 ` * ` 25: 1 6 * ` 26: 6 6 ` 27: 6
Хм.. Я бы сделал как-нибудь иначе, но хояин -- барин...
Дальше, как уже всегда, начинаем писать факториал на языке. Вслед за автором замечу что для определения факториала не были использованы ни циклы, ни рекурсия.
Как и в случае с [url=http://fforum.winglion.ru//viewtopic.php?p=3982#3982]K[/url] или с [url=http://fforum.winglion.ru//viewtopic.php?p=3922#3922]бэкФортом[/url] нам понадобится операция генерирующая ряд натуральных чисел от 1 до n, где n -- аргумент.
В определении этой функции используется то что числа в Enchilada также являются списками, пусть их элементы и пусты. Помним?
[code]> 3 [1] *| [1;1;1][/code]
Или, если посмотреть с другой стороны:
[code]> [1] 3 *` [1;1;1][/code]
Аналогично:
[code]> [1] [1] + [1] + [1;1;1][/code]
А теперь что называется, "следи за рукой" (с):
[code]> 4 ["1+] *:` [" 1 +;" 1 +;" 1 +;" 1 +][/code]
Здесь у нас в скобках по сути тело цикла, которое мы "умножаем", чтобы получить его нужное количество раз.
Но циклу нужно начальное значение (чтобы самому первому " -- DUP'у было чего дублировать), поэтому добавляем единичку:
[code]> 4 1:["1+] *:` 1 [" 1 +;" 1 +;" 1 +;" 1 +][/code]
Потом просто выводим "раскрученный" цикл за скобки операцией ! . Этот пример я покажу в режиме отладки:
[code]> \ost 4 1:["1+] *:`! 0: 4 1 : [" 1 +] * : ` ! 1: 1 4 [" 1 +] * : ` ! 2: 1 4 [" 1 +;" 1 +;" 1 +;" 1 +] : ` ! 3: 1 [" 1 +;" 1 +;" 1 +;" 1 +] 4 ` ! 4: 1 [" 1 +;" 1 +;" 1 +;" 1 +] ! 5: 1 " 1 + " 1 + " 1 + " 1 + 6: 1 1 1 + " 1 + " 1 + " 1 + 7: 1 2 " 1 + " 1 + " 1 + 8: 1 2 2 1 + " 1 + " 1 + 9: 1 2 3 " 1 + " 1 + 10: 1 2 3 3 1 + " 1 + 11: 1 2 3 4 " 1 + 12: 1 2 3 4 4 1 + 13: 1 2 3 4 5[/code]
Последнее число нам не нужно, поэтому его надо убирать, добавляем ещё один ` -- DROP. То есть функция готова:
[code]iotaN == 1:["1+] *:`!`[/code]
(вот только определение функций у меня не получаются, ошибки какие-то)
Заметьте, что результат функции -- ряд чисел мы получаем на стеке, а не в списке-элемента стека.
Теперь нужно перемножить полученный натуральный ряд, чтобы получить факториал. Принцип такой же:
[code]mulN == 1:[*`] :* ! ![/code]
Обратите внимание, mulN берёт со стека одно значение -- нужное кол-во умножений.
А полностью факториал из учебника выглядит так:
[code]facN == ^ [iotN; mulN] * | ![/code]
Сходу что делает facN не особо понять... Первая операция берёт значение с вершины стека и заключает его в скобки, превращая в список. Уже знакомая нам комбинация *|! делает map, но как бы наоборот... Так как у "данных" один элемент, а "функций" две, то Декартово произведение их даст последовательное выполнение обеих функций с одним и тем же аргументом:
[code]12 ^ [iotN; mulN] * | [12] [iotN; mulN] * | [12 iotN;12 mulN][/code]
Затем ! выполняет всё остальное, сначала выполняет 12 iotN , он оставляет на стеке ряд чисел, потом выполняется 12 mulN , который делает 12 нужных нам умножений на стеке, сводя всё к одному значению -- факториалу.
Вот так он считается в режиме трассировки:
[code]0: 3 ^ [1 : [" 1 +] * : ` ! `;1 : [* `] : * ! !] * | ! 1: [3] [1 : [" 1 +] * : ` ! `;1 : [* `] : * ! !] * | ! 2: [3;3] [1 : [" 1 +] * : ` ! `;1 : [* `] : * ! !] | ! 3: [3 1 : [" 1 +] * : ` ! `;3 1 : [* `] : * ! !] ! 4: 3 1 : [" 1 +] * : ` ! ` 3 1 : [* `] : * ! ! 5: 1 3 [" 1 +] * : ` ! ` 3 1 : [* `] : * ! ! 6: 1 3 [" 1 +] * : ` ! ` 1 3 [* `] : * ! ! 7: 1 3 [" 1 +] * : ` ! ` 1 [* `] 3 * ! ! 8: 1 3 [" 1 +] * : ` ! ` 1 [* `;* `;* `] 3 ! ! 9: 1 3 [" 1 +;" 1 +;" 1 +] : ` ! ` 1 [* `;* `;* `] 3 ! ! 10: 1 [" 1 +;" 1 +;" 1 +] 3 ` ! ` 1 [* `;* `;* `] 3 ! ! 11: 1 [" 1 +;" 1 +;" 1 +] ! ` 1 [* `;* `;* `] 3 ! ! 12: 1 " 1 + " 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 13: 1 1 1 + " 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 14: 1 2 " 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 15: 1 2 2 1 + " 1 + ` 1 [* `;* `;* `] 3 ! ! 16: 1 2 3 " 1 + ` 1 [* `;* `;* `] 3 ! ! 17: 1 2 3 3 1 + ` 1 [* `;* `;* `] 3 ! ! 18: 1 2 3 4 ` 1 [* `;* `;* `] 3 ! ! 19: 1 2 3 1 [* `;* `;* `] 3 ! ! 20: 1 2 3 1 [* `;* `;* `] ! 21: 1 2 3 1 * ` * ` * ` 22: 1 2 3 3 ` * ` * ` 23: 1 2 3 * ` * ` 24: 1 6 6 ` * ` 25: 1 6 * ` 26: 6 6 ` 27: 6[/code]
Хм.. Я бы сделал как-нибудь иначе, но хояин -- барин...
|
|
|
|
Добавлено: Пт ноя 24, 2006 14:33 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Это не язык, это скрипт какой-то...
Это не язык, это скрипт какой-то... :D
|
|
|
|
Добавлено: Пт ноя 24, 2006 11:44 |
|
|
|
|
|
Заголовок сообщения: |
Язык программирования Enchilada |
|
|
Пособие по языку от автора.
Дневник, посвящённый этому делу.
Инструкции для скачки и запуска версии 0.4.1 интерпретатора (требует Java).
Нет типов. Нет чисел. Нет строк. Только списки. Ничего, кроме списков (есть ещё выражения, но об этом как-нибудь потом, если до самого дойдёт).
Если вы видите в тексте на Enchilada число 3, не обманывайте себя -- это не число, это список [() () ()].
Поэтому привычные нам операции + и * пусть и работают в Enchilada точно так же:
Код: > 2 1 + 3 Но имеют иную внутренную логику: Код: > [ () () ] [ () ] + [() () ()] Таким образом + является не сложением, а конкатенацией списков: Код: > [1;2] [3;4] + [1;2;3;4] (надо ли говорить, что строки с > в начале -- это команды пользователя, а строки после команд -- вывод интерпретатором значения стека после выполнения команды?) Вы уже заметили что язык постфиксный. Через это имеем и операции возвращающие несколько результатов, и верную троицу DUP, DROP, SWAP в виде: Код: > 1 2 : 2 1
> 1 " 1 1
> 1 2 ` 1
(совсем недавно, с версии 0.4.1, автор переименовал DROP из ~ в `) (а в версии 0.4.2 вообще все стековые операции сломаны, теперь там .swap , .drop , .dup ну и плюс возможности по прямому заданию стековой нотации). - здесь унарный, является аналогом NEGATE. При этом отрицательные числа во избежания путаницы отображаются со знаком подчёркивания: Код: > 2 - _2 То есть фортовский минус мы получим комбинацией -+ : Код: > 10 2 -+ 8 Операция приведения (!): Код: > [2;4]! 2 4
> [1 2 +]! 3
> [1 2 +;3 4 +]! 3 7 То есть она выводит содержимое списка за скобки и упрощает (вычисляет) его, оставляя значения на стеке. С умножением много интереснее. Оно хоть и выдаёт для чисел понятные результаты, но выдаёт их парами: Код: > 1 2 * 2 2 Почему так -- в следующем абзаце, а пока примем как данное, что для чисел умножение логичнее комбинировать с DROP'ом: Код: > 10 2 *` 20 Произведение (*) в Enchilada является производным от Декартового произведения списков. Декартово произведение выдаёт набор всех возможных сочетаний пар составленных из элементов множеств. * выдает в первом результате левые половинки этих пар, во втором -- правые (я там сам не до конца понял...). Код: > [1;2;3] [4;5] * [1;1;2;2;3;3] [4;5;4;5;4;5]
А само Декартово произведение получаем комбинированием * (умножения) и | (максимума): Код: > [1;2;3] [4;5] *| [1 4;1 5;2 4;2 5;3 4;3 5]
Не спрашивайте почему именно максимум -- сам не пойму. А вообще таких отдельных непонятных мне моментов многовато.. А хотел с ними разобраться до конца, но ладно уж, пускай пока так... Через такое мы имеем что можно делать map через то же умножение, комбинируя список, который потом приводится к результату: Код: > [1 2;3 4] [*` 2+] * [1 2;3 4] [* ` 2 +;* ` 2 +]
> [1 2;3 4] [*` 2+] *| [1 2 * ` 2 +;3 4 * ` 2 +]
> [1 2;3 4] [*` 2+] *|! 4 14
А, каково?..
[url=http://enchilada.javaforge.com/]Пособие по языку от автора[/url].
[url=http://my.opera.com/rapido/blog]Дневник[/url], посвящённый этому делу.
[url=http://my.opera.com/rapido/blog/dual-lists-and-permutations]Инструкции для скачки и запуска версии 0.4.1 интерпретатора[/url] (требует Java).
Нет типов. Нет чисел. Нет строк. Только списки. Ничего, кроме списков (есть ещё [i]выражения[/i], но об этом как-нибудь потом, если до самого дойдёт).
Если вы видите в тексте на Enchilada число 3, не обманывайте себя -- это не число, это список [() () ()].
Поэтому привычные нам операции + и * пусть и работают в Enchilada точно так же:
[code]> 2 1 + 3[/code]
Но имеют иную внутренную логику:
[code]> [ () () ] [ () ] + [() () ()][/code]
Таким образом + является не сложением, а конкатенацией списков:
[code]> [1;2] [3;4] + [1;2;3;4][/code]
(надо ли говорить, что строки с > в начале -- это команды пользователя, а строки после команд -- вывод интерпретатором значения стека после выполнения команды?)
Вы уже заметили что язык постфиксный. Через это имеем и операции возвращающие несколько результатов, и верную троицу DUP, DROP, SWAP в виде:
[code]> 1 2 : 2 1
> 1 " 1 1
> 1 2 ` 1 [/code]
(совсем недавно, с [url=http://my.opera.com/rapido/blog/dual-lists-and-permutations]версии 0.4.1[/url], автор переименовал DROP из ~ в `)
(а в [url=http://my.opera.com/rapido/blog/show.dml/573874]версии 0.4.2[/url] вообще все стековые операции сломаны, теперь там .swap , .drop , .dup ну и плюс возможности по прямому заданию стековой нотации).
- здесь унарный, является аналогом NEGATE. При этом отрицательные числа во избежания путаницы отображаются со знаком подчёркивания:
[code]> 2 - _2[/code]
То есть фортовский минус мы получим комбинацией -+ :
[code]> 10 2 -+ 8[/code]
Операция приведения (!):
[code]> [2;4]! 2 4
> [1 2 +]! 3
> [1 2 +;3 4 +]! 3 7[/code]
То есть она выводит содержимое списка за скобки и упрощает (вычисляет) его, оставляя значения на стеке.
С умножением много интереснее. Оно хоть и выдаёт для чисел понятные результаты, но выдаёт их парами:
[code]> 1 2 * 2 2[/code]
Почему так -- в следующем абзаце, а пока примем как данное, что для чисел умножение логичнее комбинировать с DROP'ом:
[code]> 10 2 *` 20 [/code]
Произведение (*) в Enchilada является производным от Декартового произведения списков. Декартово произведение выдаёт набор всех возможных сочетаний пар составленных из элементов множеств. * выдает в первом результате левые половинки этих пар, во втором -- правые (я там сам не до конца понял...).
[code] > [1;2;3] [4;5] * [1;1;2;2;3;3] [4;5;4;5;4;5] [/code]
А само Декартово произведение получаем комбинированием * (умножения) и | (максимума):
[code] > [1;2;3] [4;5] *| [1 4;1 5;2 4;2 5;3 4;3 5] [/code]
Не спрашивайте почему именно максимум -- сам не пойму. А вообще таких отдельных непонятных мне моментов многовато.. А хотел с ними разобраться до конца, но ладно уж, пускай пока так...
Через такое мы имеем что можно делать map через то же умножение, комбинируя список, который потом приводится к результату:
[code]> [1 2;3 4] [*` 2+] * [1 2;3 4] [* ` 2 +;* ` 2 +]
> [1 2;3 4] [*` 2+] *| [1 2 * ` 2 +;3 4 * ` 2 +]
> [1 2;3 4] [*` 2+] *|! 4 14[/code]
А, каково?..
|
|
|
|
Добавлено: Пт ноя 24, 2006 10:09 |
|
|
|
|