LINUX.ORG.RU

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


0

0

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

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

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

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

★★★★★

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

> Поясни для Ъ - кусок этого языка может быть встроен прямо в Lisp-сорец?

Именно так. Правда, внутри самого этого notnet своя макросистема, работающая аналогично лисповской, но использующая другой набор макроопределений (поскольку язык другой, то от стандартных макр вроде list или let там толку не будет).

> Вызовы, переменные и т.п.

Захватываемые переменные внешнего окружения надо декларировать (поскольку в лиспе они все тупо System.Object, и их надо приводить к нужному типу ещё), функции лиспа можно вызывать специальной макрой.

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

> Seaside довольно интересный web-framework для Смоллтока, на continuations

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

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

> ну вот в лиспе макра "применима" к любому элементу списка, s-выражения.

Это только в неправильном лиспе. Ну вот на фига мне раскрывать "макру" list в выражении (let ((list '(1 2 3))) ...) - здесь list - связываемое имя, а не макра. Правильный Лисп должен иметь некоторое уважение к AST и не раскрывать макры в аргументах функций, внутри quote и т.п.

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

gacutil это несколько другое - он обслуживает кэш именованных сборок. По сути аналог ldconf.

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

Там, кстати, был и пример расширения синтаксиса языка - определение макры infix, позволяющей писать что либо вроде (# fun(x,y) -> x*x+y*y) вместо (lambda (x y) (+ (* x x) (* y y)), и определение макры (<L> ...), реализующей list comprehensions в стиле Питона.

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

> В .NET это сделано немного через одно... место. Хотя есть своя концепция.

Гнилая концепция. Вот, представь, распределенная агентная система, агенты общаются друг с другом кусками кода. На tcl или java этот код исполнялся бы в контексте каждого агента, и забывался бы немедленно. В .net он будет скапливаться вечно, если только его не интерпретировать вместо кошегъной пгъавославной компиляции.

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

>> В .NET это сделано немного через одно... место. Хотя есть своя концепция.

>Гнилая концепция.

Мне и самому не нравится. Очень. Как-то столкнулся с этим в одной задаче. Было жутко неприятно. :)

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

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

>>А вот автор tkLOR'а ЕМНИП так конфиги и грузил, eval'ом

> если для этой цели он порождал новый Safe-интерпретатор, то не вижу ничего крамольного. хотя сам бы так не делал, избыточно всё-таки :)


У меня просто eval в catch-е и всё. Ибо конфиг модет сделато гораздо большее, чем порсто загрузить значения десятка переменных, и я его использование ограничивать не хочу.

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

>У меня просто eval в catch-е и всё. Ибо конфиг модет сделато гораздо большее, чем порсто загрузить значения десятка переменных, и я его использование ограничивать не хочу.

а если в конфиге будет вызов "rm -rf /"? ;) или хотя бы "rm -rf ~/"?

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

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

> Почему вообще возникает инъекция? Потому что есть один слой с переменными и есть другой слой с текстовыми запросами. Если при этом подставлять переменные просто как текст, то нарушается семантика исходной модели где не надо (расширяется семантика такой текстовой переменной -- она была просто значением, а стала любым текстом), что позволяет протащить любой запрос, или сорвать стек если строка -- не в буфере с заданным размером.

Опять же, чтобы сделать инъекцию кода из текстовых данных, не применяя eval, надо очень и очень сильно постараться. А если уж написал eval -- будь готов к тому, что он сделает.

Тикль -- это не баш с его quoting hell-ом, в тикле просто так код с данными не смешаешь. Но в тоже время, если смешать понадобится -- это делается легко и естественно.

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

А если оно будет в скриптовом враппере (а почти все жабские приложения так запускаются, например)?

Это не аргумент против исполнимых конфигов. Исполнимые конфиги рулят.

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

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

>>У меня просто eval в catch-е и всё. Ибо конфиг модет сделато гораздо большее, чем порсто загрузить значения десятка переменных, и я его использование ограничивать не хочу.

> а если в конфиге будет вызов "rm -rf /"? ;) или хотя бы "rm -rf ~/"?


То он удалит все файлы в указанном каталоге :)

Но если злоумышленник доберётся до моих конфигов, он, наверно, первым делом эту строчку впишет в .profile :)

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

>А если оно будет в скриптовом враппере (а почти все жабские приложения так запускаются, например)?

>Это не аргумент против исполнимых конфигов. Исполнимые конфиги рулят.

жду аргументации "за" :)

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

>То он удалит все файлы в указанном каталоге :)

я думаю это можно считать критической уязвимостью приложения

>Но если злоумышленник доберётся до моих конфигов, он, наверно, первым делом эту строчку впишет в .profile :)

ну, это уже вопрос вкуса ;)

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

>в тикле просто так код с данными не смешаешь...это делается легко и естественно

замечательная получилась фраза ;)

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

> жду аргументации "за" :)

1) если бяка может писать в пользовательские файлы - то это уже дыра. Насколько они там исполнимые уже не важно.

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

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

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

это ещё почему? откладываем-то мы не сознательно, за нас это делает сам Ъ-язык. а вот действия выбираем сами - с учётом того, что errare humanum est

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

Да тот же CL и большинство Схем себе такого не позволят.

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

>1) если бяка может писать в пользовательские файлы - то это уже дыра. Насколько они там исполнимые уже не важно.

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

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

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

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

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

>>То он удалит все файлы в указанном каталоге :)

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


Ну если все приложения, откуда можно исполнить однострочник считать уязвимыми, то становится даже страшно жить :)

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

>Ну если все приложения, откуда можно исполнить однострочник считать уязвимыми, то становится даже страшно жить :)

я там чуть выше уже накрывался плащ-палаткой и полз на кладбище ;) но вообще меня больше беспокоит вопрос избыточности обработчика - вместо парсера формата конфигов (который можно декларативно объявить и легко менять, подстраивая под нужны текущей версии приложения) имеем полноценный Tcl-парсер, который нам совершенно ни к чему

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

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

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

Можно посмотреть с той стороны, что это фича. А уж rm -rf / можно и в строку, описывающую команду для вызова браузера, добавить. И ничем тут неисполнимый конфиг не спасёт.

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


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


А если это фича? Т.е. в конфиге позволяется выполнять любые команды и соответствующим образом настраивать рабочее окружение?

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

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

>>Ну если все приложения, откуда можно исполнить однострочник считать уязвимыми, то становится даже страшно жить :)

> я там чуть выше уже накрывался плащ-палаткой и полз на кладбище ;) но вообще меня больше беспокоит вопрос избыточности обработчика - вместо парсера формата конфигов (который можно декларативно объявить и легко менять, подстраивая под нужны текущей версии приложения) имеем полноценный Tcl-парсер, который нам совершенно ни к чему


Учитывая необходимость могучего языка конфигурирования в моём случае, гораздо легче взять уже сразу тиклепарсер, нежели сочинять что-то своё. Но, в тоже время, использовать интерпретатор для загрузки key=value действительно глупо.

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

>Учитывая необходимость могучего языка конфигурирования в моём случае, гораздо легче взять уже сразу тиклепарсер

соглашусь только в том случае, если используется Safe Tcl с явными (и проверяемыми) запросами на небезопасные операции

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

>А если это фича? Т.е. в конфиге позволяется выполнять любые команды и соответствующим образом настраивать рабочее окружение?

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

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

> а если в конфиге будет вызов "rm -rf /"? ;) или хотя бы "rm -rf ~/"?

На этот случай в нормальных языках предусмотрены специяльные песочницы, в которох множество команд сильно ограничено, но в то же время языковые конструкциии можно пользовать невозбранно. В частности в tcl нужно вкуривать safe tcl inerpretator. Почему его не использовал gaa - хз.

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

>В частности в tcl нужно вкуривать safe tcl inerpretator

[:||~||:] выше по тексту неоднократно обсуждалось ;)

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

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

Понял. Но такая проблема вообще не лечится. Почему бы тогда не бояться, что судорутному бинарнику не подсунут в конфиге предложение писать лог в /dev/sda?

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

>Понял. Но такая проблема вообще не лечится. Почему бы тогда не бояться, что судорутному бинарнику не подсунут в конфиге предложение писать лог в /dev/sda?

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

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

>Здоровая и интересная дискуссия на LORе. Я в шоке! O_O

сам удивился :) причём поводом к ней послужил вопрос, случайно возникший в метро в процессе обдумывания формализации построения таксономии области решений. просто вспомнил про wildcards в расширяемых языках, стало интересно - насколько это существенный фактор

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

Кстати, рекомендую поинтересоваться творчетвом товарища Walid Taha, именно его слова перевирает тот ЛОРовский фрик, на которого ты ссылался.

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

>Кстати, рекомендую поинтересоваться творчетвом товарища Walid Taha, именно его слова перевирает тот ЛОРовский фрик, на которого ты ссылался.

это Луговский что ли - ЛОРовский фрик? :) а почитать - почитаю, спасибо

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

Что-то вы херату какую-то начали обсуждать. Давайте-ка по теме больше: >а сколько таких языков вообще есть? интересуют неэзотерические и неэкспериментальные (т.е. доказавшие свою применимость хотя бы в одном завершённом проекте).

Т.е. всякие notnot обсуждать НЕ НАДО. Их никто не видел, а кто видел - не пользовался.

Да и зачем может понадобиться кстати такой язык? Неужели выполнять в своей программе произвольный код, пришедший по сетке неизвестно откуда? А если нет, тогда что? Свой произвольный код? Но если он мой, тогда зачем его совать в программу в рантайме, "динамически"?

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

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

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

>>Понял. Но такая проблема вообще не лечится. Почему бы тогда не бояться, что судорутному бинарнику не подсунут в конфиге предложение писать лог в /dev/sda?

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


И при этом лишиться возможности вызывать внешние программы вообще.

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

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

> Да и зачем может понадобиться кстати такой язык? Неужели выполнять в своей программе произвольный код, пришедший по сетке неизвестно откуда? А если нет, тогда что? Свой произвольный код? Но если он мой, тогда зачем его совать в программу в рантайме, "динамически"?

Удалённая отладка, удалённое обновление кода без перезапуска, прозрачное проксирование... Мало?

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


Мы тут обсуждаем в обсновном создание новых конструкций в момент написания кода. Но в качестве побочного эффекта у большинства реализаций получается ещё и возможность "крутить" кодом и в рантайме.

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

> Если "вместо выполнения каких-то действий, откладываем их до тех пор, пока их результат нам не понадобится" -- то эти действия должны быть подобраны безошибочно :)

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

let x = 1/a in if a == 0 then 0 else x

В этом примере, если a равно 0, то x вообще не будет вычислен - поскольку не понадобится. Мы не столкнёмся с ошибкой деления на 0, несмотря на то, что, формально, написано ошибочное действие.

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

>http://ru.wikipedia.org/wiki/Прототипное_программирование

>Прототипное программирование — стиль объектно-ориентированного программирования

вообще не в ту степь. то, что где-то около того - это FAST от Bell Labs, но оно всё больше по DSL-ориентированному проектированию, а меня интересует фиксированная область решений

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

>И при этом лишиться возможности вызывать внешние программы вообще.

ничего подобного, просто комманды для данных действий надо прописать вручную. с добавлением некоторых семантических проверок ;)

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

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

>>И при этом лишиться возможности вызывать внешние программы вообще.

> ничего подобного, просто комманды для данных действий надо прописать вручную. с добавлением некоторых семантических проверок ;)


Всё равно не прокатит. Я хочу дать возможность сделать exec чего угодно. Мне что, проверять, не сугнули ли ему на вход rm -rf? :)

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

>Всё равно не прокатит. Я хочу дать возможность сделать exec чего угодно

вот тут у нас собственно и расхождения: я считаю это багом, ты - фичей :)

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

во, нафлуудили !? 
Кто-нибудь на Форте программирует? а, то я
последнего такого человека встречал этак лет 20 тому назад.
В то время Форт выглядил "феерично"! Как сейчас? 

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

>Кто-нибудь на Форте программирует?

Я :) Хотя и не постоянно. И на системном уровне программировал на нём последний раз в 1994-м.

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

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

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

> Кто-нибудь на Форте программирует? а, то я последнего такого человека встречал этак лет 20 тому назад.

Ещё раз встретишь -- заспиртуй и сдай в музей вычислительной техники :)

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