LINUX.ORG.RU

Расширяемые ЯП


0

0

доброго времени суток

"если в языке нет какого-то механизма, то его всегда можно реализовать возможностями самого языка" - почти по Луговскому про LISP. вопрос в следующем: а сколько таких языков вообще есть? интересуют неэзотерические и неэкспериментальные (т.е. доказавшие свою применимость хотя бы в одном завершённом проекте). расширяемость на уровне именно языковых конструкций, не промежуточного представления виртуальной машины, т.е. положительный пример - Tcl/Snit, отрицательный - C#/LINQ

и в дополнение ещё вопрос, просто подумалось. какой языковой конструкции/выразительной мощности/механизма вам не хватает в своём основном ЯП?

заранее спасибо

★★★★★

> вопрос в следующем: а сколько таких языков вообще есть

А любой язык, вообще. Поскольку внешний препроцессор к любому языку можно написать на этом самом языке (сишный препроцессор написан на Си, M4 написан на Си, CamlP4 написан на OCaml, ...).

> и в дополнение ещё вопрос, просто подумалось. какой языковой конструкции/выразительной мощности/механизма вам не хватает в своём основном ЯП?

Всего хватает, спасибочки, не надо нам больше расширений.

anonymous
()

Самый расширяемый - это Форт :) Теоретически на нём можно реализовать любой синтаксис и использовать разные синтаксические реализации в рамках одного и того же исходного файла.

Думаю, на втором месте идёт LISP. В принципе, в нём тоже можно реализовать подобное, хотя, ИМХО, не так гибко и удобно (придётся напрямую работать с исходным текстом программы). Но тут не спец, т.к. о Лиспе - только общие представления :)

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

KRoN73 ★★★★★
()

>какой языковой конструкции/выразительной мощности/механизма вам не хватает в своём основном ЯП?

В Java не хватает развитой рефлексии, расширения классов на лету. В PHP не хватает строгой типизации :)

KRoN73 ★★★★★
()

> и в дополнение ещё вопрос, просто подумалось. какой языковой конструкции/выразительной мощности/механизма вам не хватает в своём основном ЯП?

: CREATE ... DOES> ... ;

anonymous
()
Ответ на: комментарий от anonymous

>А любой язык, вообще. Поскольку внешний препроцессор к любому языку можно написать на этом самом языке (сишный препроцессор написан на Си, M4 написан на Си, CamlP4 написан на OCaml, ...).

есть примеры OSS-проектов, выполненных с применением подобного подхода (именно использование препроцессора для добавления языковых механизмов)? я навскидку могу вспомнить только CLAM (http://www.clam.iua.upf.edu/) со связкой препроцессор/C++

>Всего хватает, спасибочки, не надо нам больше расширений.

что за язык-то? :)

jtootf ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

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

вот этот момент вызывает большие сомнения. или под транслятором понимается интерпретатор/компилятор, отрабатывающий в runtime? если да, то это неинтересно :) в противном же случае для большинства ЯП общего назначения придётся лезьть во внутреннее представление, т.е. в исходники компилятора/интерпретатора хостового языка

jtootf ★★★★★
() автор топика
Ответ на: комментарий от nikolayd

>Прикрути к ней эрланг и расширяй на лету.

ИМХО, проще выкроить пару дней и дописать-таки JBForth2 с кодогенерацией :)

KRoN73 ★★★★★
()
Ответ на: комментарий от jtootf

>вот этот момент вызывает большие сомнения. или под транслятором понимается интерпретатор/компилятор, отрабатывающий в runtime? если да, то это неинтересно :)

Транслятор - это любая среда, позволяющая исполнять программу. Т.е. любой интерпретатор/компилятор.

Поэтому и пишу, что неинтересно :)

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

Поэтому тут и интересно смотреть на Форт, на котором можно сменять языковой синтаксис в рамках одной программы :)

." Hello, world!"
[basic]
10 PRINT "Hello, world!"
[end-basic]
[c]
printf("%s", "Hello, world");
[end-c]
." And Forth again"

И всё - в одном файле.

:)

Почти реальные примеры. Реализация примитивного Бейсика - это пара килобайт пространных сорцов, где-то. Сишный компилятор видел, но урезанный, полный вариант товарищ, писавший его, свободно не отдаёт.

Ну а гораздо проще реализуются просто чужие языковые концепции в рамках Форта. Lisp-овые списки, Prolog'овые утверждения и т.п... Но это уже не так спортивно :)

...

А, да, возвращаясь к «чего не хватает». В классическом Форте не хватает типизации переменных. В JBForth1 - типизации по их выводу и кодогенерации. В JBForth2 не хватает того, что он пока не написан. Во многом - из-за отсутствия реальной задачи :)

KRoN73 ★★★★★
()
Ответ на: комментарий от jtootf

>>: CREATE ... DOES> ... ;

> это что?

Это на Форте. Прямых аналогов в других языках не знаю. В общем, это генерация генерирующих определений :)

KRoN73 ★★★★★
()
Ответ на: комментарий от Valeriy_Onuchin

>этож ых гордость! ;)

Да ладно, мир полон языками, лишёнными строгой типизации :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Это на Форте. Прямых аналогов в других языках не знаю. В общем, это генерация генерирующих определений :)

реквестирую учебник Форта :) кстати, не приходилось ли смотреть на REBOL? насколько я его понял, идеологически это помесь Forth'а и LISP'а, правда, узкоспециализированная

jtootf ★★★★★
() автор топика

Nemerle? Хотя как оно живет под unix-like большой вопрос...

> положительный пример - Tcl

Закопайте. Конструкции вроде

switch $x \ "$z" {set y1 [expr $y+1]; puts "СОВПАДЕНИЕ \$z. $y + $z is $y1" } \ "ОДИН" {set y1 [expr $y+1]; puts "СОВПАДЕНИЕ ОДИН. $y + один это $y1"} \ "ДВА" {set y1 [expr $y+2]; puts "СОВПАДЕНИЕ ДВА. $y + два это $y1" } \ "ТРИ" {set y1 [expr $y+3]; puts "СОВПАДЕНИЕ ТРИ. $y + три это $y1" } \ "default" {puts "$x не совпало ни с одним вариантом";}

иначе как у.бищными не назовешь.

anonymous
()

Nemerle? Хотя как оно живет под unix-like большой вопрос...

> положительный пример - Tcl

Закопайте. Конструкции вроде

switch $x \
  "$z"		{set y1 [expr $y+1]; puts "СОВПАДЕНИЕ \$z. $y + $z is $y1" } \
  "ОДИН"	{set y1 [expr $y+1]; puts "СОВПАДЕНИЕ ОДИН. $y + один это $y1"} \
  "ДВА"		{set y1 [expr $y+2]; puts "СОВПАДЕНИЕ ДВА. $y + два это $y1" } \
  "ТРИ"		{set y1 [expr $y+3]; puts "СОВПАДЕНИЕ ТРИ. $y + три это $y1" } \
  "default"	{puts "$x не совпало ни с одним вариантом";}


иначе как у.бищными не назовешь.

anonymous
()
Ответ на: комментарий от anonymous

>Закопайте

может ещё по теме что-то скажешь? в смысле про Snit, который я упоминал как кпример

>Конструкции вроде

...писал человек, который не умеет писать на Tcl, не знает что такое подстановка, и не умеет пользоваться тиклевским switch'ом. и что? если это твой код - я бы на твоём месте постыдился бы его показывать

jtootf ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>Leo Brodie или как-то так

нашёл, спасибо

jtootf ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>Nemerle

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

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

>реквестирую учебник Форта :)

Как обычно, Лео Броуди. Сперва Starting Forth, потом - Thinking Forth. Оба есть в хороших русских переводах.

По CREATE ... DOES> - если в двух словах, то работает так. Создаём новое слово («слово» на Форте - любой активный код. Переменные, процедуры, функции, команды транслятора, конструкции языка...), при выполнении которого будет исполняться некий заданный после DOES> код.

Например,

CREATE autoinc 0 , DOES> DUP @ 1+ TUCK SWAP ! ;

Теперь у нас есть слово autoinc, создающее переменные с особым поведением - при каждом вызове они возвращают на единицу большее значение:

autoinc xxx \ создали нового вида переменную xxx.
autoinc yyy \ и ещё одну
xxx . \ напечатает "1"
xxx . \ теперь напечатает "2"
yyy . \ 1
xxx . \ 3
yyy . \ 2
и т.д.

Понятно, что пример очень простой и непрактический :)

>кстати, не приходилось ли смотреть на REBOL?

Не-а, надобности не было и достаточного уровня интереса :) Хотя слышал, конечно.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Как обычно, Лео Броуди. Сперва Starting Forth, потом - Thinking Forth. Оба есть в хороших русских переводах

ок, прочитаю первую - вернусь с новыми вопросами

>По CREATE ... DOES> - если в двух словах, то работает так

занятно...а какие ограничения на объявление слова есть? что может идти в DOES? любые слова, определённые ранее?..

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

> писал человек, который не умеет писать на Tcl, не знает что такое подстановка, и не умеет пользоваться тиклевским switch'ом. и что? если это твой код - я бы на твоём месте постыдился бы его показывать

Это из какого-то туториала по Tcl, после этого примера мне поплохело...

anonymous
()
Ответ на: комментарий от KRoN73

> В Java не хватает развитой рефлексии
Ой. А можно развить мысль?

ЗЫ Про расширение на лету спорить не буду - его нет, хотя не ощущал реальной нехватки.

svu ★★★★★
()
Ответ на: комментарий от KRoN73

> Теоретически на нём можно реализовать любой синтаксис и использовать разные синтаксические реализации в рамках одного и того же исходного файла.

А на практике - ни хорошего GC, ни приличной type system. :)

anonymous
()
Ответ на: комментарий от jtootf

>занятно...а какие ограничения на объявление слова есть?

Да нет. Ну, кроме стандартного Фортовского, что в имени слова недопустимы пробелы :)

>что может идти в DOES? любые слова, определённые ранее?..

Да, произвольный Форт-код.

...

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

Т.е. правильно будет:

CREATE xxx 0 , DOES> ... - дальше по тексту.

Генерирующее - это уже надо в сторону DOER/MAKE смотреть. Ну, или заюзать EVALUATE :)

: autoinc "CREATE 0 , DOES> ...;" EVALUATE ;

KRoN73 ★★★★★
()

> "если в языке нет какого-то механизма, то его всегда можно реализовать возможностями самого языка" - почти по Луговскому про LISP. вопрос в следующем: а сколько таких языков вообще есть? интересуют неэзотерические и неэкспериментальные

на bash, наверно, тоже можно новые конструкции сочинять.

> и в дополнение ещё вопрос, просто подумалось. какой языковой конструкции/выразительной мощности/механизма вам не хватает в своём основном ЯП?


если считать основныйм tcl: лёгкой операции создания списка ([ list ... ] уж очень долго писать). Ещё тянет на статическую типизацию, но я сильно не уверен, а не будет ли от неё хуже

gaa ★★
()
Ответ на: комментарий от jtootf

> реквестирую учебник Форта :)

google: "Thinking in Forth", бесплатно раздают.

anonymous
()
Ответ на: комментарий от anonymous

>Это из какого-то туториала по Tcl, после этого примера мне поплохело...

сожги этот туториал и прочитай "Практическое программирование на Tcl и Tk" Уэлша и Джонса, первую часть (вторая по Tk, менее интересная). жаловаться на конструкции в Tcl вообще абстрактная глупость: Tcl - метаязык, в нём с полпинка можно реализовать любой синтаксис. почитать об этом можно тут:

http://wiki.tcl.tk/495

jtootf ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Nemerle? Хотя как оно живет под unix-like большой вопрос...

Хорошо живёт, лучше чем под родным .NET.

anonymous
()
Ответ на: комментарий от jtootf

> но примеров использования в вышеуказанной цели не встречал

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

anonymous
()
Ответ на: комментарий от anonymous

>Qt, например

да, согласен, вижу что примеров хватает

jtootf ★★★★★
() автор топика
Ответ на: комментарий от gaa

>лёгкой операции создания списка ([ list ... ] уж очень долго писать)

занятно...а какой вариант ты бы предложил? :)

>Ещё тянет на статическую типизацию, но я сильно не уверен, а не будет ли от неё хуже

как подстановку со статической типизацией реализовывать, учитывая специфику работы интерпретатора (многократный проход по исходникам)? по-моему это не то что "хуже", а просто невозможно

jtootf ★★★★★
() автор топика
Ответ на: комментарий от jtootf

> сожги этот туториал и прочитай "Практическое программирование на Tcl и Tk" Уэлша и Джонса

Ладно, посмотрю еше раз.

anonymous
()
Ответ на: комментарий от svu

>Ой. А можно развить мысль?

Ну, я и имел в виду связку рефлексии и расширяемости на лету.

Скажем, на PHP (равно, как и на Perl, Ruby) я описал в классе только
поля БД и в какие поля классов их грузить. И ORM при загрузке объекта
мне создаст соответствующий класс. Типа, реальный пример:

<?php

class aviaport_mail_irregular extends base_object_db
{
// ...
    function main_table_fields()
    {
        return array(
            'id',
            'title', 
            'create_time', 
            'modify_time', 
            'send_time', 
            'source_text', 
            'source_html',
        );
    }
// ...
}

Всё. Потом - 

$mail = object_load('aviaport_mail_irregular', $id);

echo "Title=" $mail->title();

В Java мне придётся заводить переменную _title, описывать методы
getTitle(), setTitle()...

В итоге одна упомянутая выше строчка (ну, в несколько строк для наглядности развёрнутую) превращается в 3*7=21 строк.

private Integer _id;
Integer getId() { return this._id; }
Integer setId(Integer value, boolean db_update)
{
    this._id = value;
    return checkDBUpdate(...);
}

private String _title;
String getTitle...
...

В общем, геморрой страшный :) Представь, что надо описать объект
в два десятка полей...
Собственно, это основная причина, по которой я хочу писать JBForth.
Тогда хотя бы подобные вещи на нём можно будет описывать, не менее
гибко. Но пока мой проект на Java стоит уже больше года, так что и
стимула нет.

KRoN73 ★★★★★
()
Ответ на: комментарий от anonymous

>> В классическом Форте не хватает типизации переменных

> Посмотри на Cat.

В _классическом_ Форте. А так - у меня и в первом JBForth строгие Java-типы :)

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

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

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

svu ★★★★★
()
Ответ на: комментарий от jtootf

Re^2: Расширяемые ЯП

>>лёгкой операции создания списка ([ list ... ] уж очень долго писать)

> занятно...а какой вариант ты бы предложил? :)


Ну что-то типа <elem1 elem2 elem3>. Вроде как {...}, но с подстановкой, но в то же время не "...". Ну или уж сразу скобки по-лисповски :)

>>Ещё тянет на статическую типизацию, но я сильно не уверен, а не будет ли от неё хуже


> как подстановку со статической типизацией реализовывать, учитывая специфику работы интерпретатора (многократный проход по исходникам)? по-моему это не то что "хуже", а просто невозможно


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

gaa ★★
()
Ответ на: Re^2: Расширяемые ЯП от gaa

>Ну что-то типа <elem1 elem2 elem3>. Вроде как {...}, но с подстановкой, но в то же время не "...". Ну или уж сразу скобки по-лисповски :)

можно предложить TIP на укороченную запись, вроде $ для подстановки. а для начала можно такой синтаксис сделать самостоятельно. кстати, что в jabber'е не отвечаешь?

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

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

jtootf ★★★★★
() автор топика
Ответ на: Re^2: Расширяемые ЯП от gaa

>Ну что-то типа <elem1 elem2 elem3>. Вроде как {...}, но с подстановкой, но в то же время не "...". Ну или уж сразу скобки по-лисповски :)

На JBForth я, не мудурствуя лукаво сделал:

{ item1 item2 item3 ... } value my_list

Где item - любые слова, не обязательно константы, можно даже вложенные списки или ещё как-то. Скажем, расширяя предыдущий код:

{ my_list { 1 2 3 } } value my_list2

Ну и потом, скажем, нужно распечатать:

my_list [[ type ]] do-list

В данном случае [[ .. ]] - это уже лямбда :) Ну, или замыкание. В рамках Форт-синтаксиса между ними, вроде, нет разницы.

KRoN73 ★★★★★
()
Ответ на: комментарий от jtootf

>ну подумай, когда должна выполнятся статическая проверка типов при наличии eval

В рантайме, конечно :)

Так и в Java той же, не смотря на статическую проверку и отсутствие eval, есть исключительно рантаймовые проверки типов - тот же боксинг.

Integer var = 1;

Object ptr = var;

String s = (String) ptr; // oops. Вылезет только в рантайме.

KRoN73 ★★★★★
()

В Питоне не хватает pattern matching и статической типизации. В Си - исключений, параметризуемых типов и опять pattern matching. Ну а Си++ просто слишком сложен, чтобы его еще расширять.

Ну и везде хочется вывод типов.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> В Питоне не хватает pattern matching и статической типизации.

Он тогда OCaml-ом станет.

> В Си - исключений, параметризуемых типов и опять pattern matching.

PM поверх чего? Tagged unions в язык вводить на низком уровне, что ли? RTTI ведь никакой нет.

> Ну а Си++ просто слишком сложен, чтобы его еще расширять

Он и так расширяемый.

> Ну и везде хочется вывод типов.

Не везде он возможен. Там, где полиморфизм в стиле Java/.NET, ничего хорошего из вывода типов не получится.

anonymous
()
Ответ на: комментарий от KRoN73

Чем это отличается от хеш-таблицы? Генерировать классы, кстати, в Java можно, хоть и достаточно низкоуровнево. Тот же Hibernate прокси-классы генерирует.

Legioner ★★★★★
()
Ответ на: комментарий от KRoN73

$ java -cp commons-lang.jar -jar jbforth.jar 
{ 1 2 3 } dup .
[1, 2, 3]
value l1
l1 .
[1, 2, 3]
{ 4 5 6 } value l2
l2 .
[4, 5, 6]
{ l1 l2 { 7 8 9 } } value  ll         
ll .
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
ll 2 list@ .
[7, 8, 9]

ll 2 list@ 1 list@ .
8

ИМХО, вполне логично и компактно :) Разве что для list@ можно алиас l@ ввести.

KRoN73 ★★★★★
()
Ответ на: комментарий от svu

> я не вижу недостатков в имеющейся рефлексии...

generics. Конечно type erasure ничего не позволит сделать, но хотелось бы.

Legioner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.