После прочтения топика "Следующий язык программирования" мне тут подумалось. Новый язык может быть создан двумя путями. Первый — из новой идеологии программирования (которая была бы ортогональна ООП, функциональному, или же являлась надмножеством их); но вряд ли мы тут сможем слуайно эту идеологию придумать или угадать, а если сможем, то новый язык будет уже на 75% готов Второй путь — добавить к возможностям существующих языков новые, которые окажутся настолько важными, что те задачи, которые сейчас решаются долго или не решаются, будут решаться очень красиво и элегантно. Так вот параллельно основному топику, где происходит непонятно что ближе к первому пути, чем ко второму, я предлагаю пойти по второму пути здесь.
Т.е. пойти от проблем. Если каждый вспомнит случай из практики, когда он упирался в ограниченность своего языка (т.е. чувствовал, что возможно более красивое решение, если бы язык позволял его сделать). Из чего станет ясно, какие фичи новый язык должен уметь,
Предлагаю принимать чисто практические задачи, с которыми вы сталкивались в практике.
Мои мысли по этому поводу. Будущее — за DSL!
Язык, который предоставит возможность создавать DSL просто, удобно и эффективно — он и станет "прорывом"
ИМХО, базовый язык должен предоставлять минимальное количество конструкций, фактически на уровне ассмеблера (только независимого от платформы — CIL, например). Однако, там должна быть возможность создавать и расширять свои языковые конструкции, а также группировать эти конструкции в библиотеки, которые можно подключать по мере необходимости.
Хотите прямой доступ к памяти? Подключайте и пользуйтесь. Хотите сборщик мусора? Аналогично. Функциональный стиль — аналогично.
При этом, что очень важно, необходимы средства управлять зависимостями между такими библиотеками DSL, а также правами доступа к ним. Например, необходимо иметь возможность установить, что кодерам запрещено использовать Dsl.RawMemoryAccess
Здравствуйте, Дарней, Вы писали:
Кё>>Я имел ввиду не это, а отсутствие необходимой выразительности в языке.
Д>Я думаю, намного лучше, когда есть возможность добавлять необходимую выразительность самому
По-моему это из разрада фантастики. Либо это Лисп, что уже неудовлетворительно из-за трудного для восприятия синтаксиса.
Здравствуйте, Дарней, Вы писали:
Д>Мои мысли по этому поводу. Будущее — за DSL! Д>Язык, который предоставит возможность создавать DSL просто, удобно и эффективно — он и станет "прорывом"
Боюсь только, что динамическая природа Ruby не позволит ему стать мейнстримом. Все же глобальный отказ от статической типизации даже для меня пока выглядит экстремизмом (хотя я все больше и больше попадаю под влияние Duck Typing-а).
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Кодёнок, Вы писали:
Кё>>>Я имел ввиду не это, а отсутствие необходимой выразительности в языке.
Д>>Я думаю, намного лучше, когда есть возможность добавлять необходимую выразительность самому
Кё>По-моему это из разрада фантастики.
Ты думаешь?
dir.each { |filename| block } => dir
Calls the block once for each entry in this directory, passing the filename of each entry as a parameter to the block.
d = Dir.new("testdir")
d.each {|x| puts "Got #{x}" }
Здравствуйте, Кодёнок, Вы писали:
Кё>По-моему это из разрада фантастики. Либо это Лисп, что уже неудовлетворительно из-за трудного для восприятия синтаксиса.
Я конечно знаю, что ничего подобного сейчас нет. Но хочется
Что касается синтаксиса, то возможность его кастомизации — это тоже очень важный аспект. Имея полностью настраиваемый язык, можно будет навсегда забыть про споры типа "= vs :=" и "begin vs {"
Правда, сам код в таком случае надо будет хранить не в виде текста, а в виде предварительного распарсенного промежуточного представления. В этом случае, кстати, намного упрощается создание средств рефакторинга и визуализации, контроль изменений и просмотр истории, и т.д.
В общем, plain text must die
ИМХО следующим будет, действительно, не язык, а некая "безъязыковая" технология, кторая позволит без ощутимых накладных расходов испольщовать наиболее удобный для каждого конкретного случая синтаксис. Т.е. да, DSL.
Здравствуйте, mihoshi, Вы писали:
M>ИМХО следующим будет, действительно, не язык, а некая "безъязыковая" технология, кторая позволит без ощутимых накладных расходов испольщовать наиболее удобный для каждого конкретного случая синтаксис. Т.е. да, DSL.
Да какая разница В С++ если создать набор типов и переопределить их операции, то тоже получиться некий DSL. Например, для операций над матрицами. Теоретически, расширяя набор перегружаемых операций и даже позволяя вводить свои постфиксные, инфиксные и префиксные операции, можно получить язык, в котором можно создать любой удобный DSL.
Я не против, чтобы мы сейчас его придумали; но по-моему ничего не выйдет с нуля сейчас что-то путнее сделать. Для начала может просто попытаться преодолеть конкретные ограничения конкретные языков? А там уже сможем обобщить и тогда оно станет более реально.
Т.е. просто сказать "безъязыковая технология" мало, надо же конкретно уточнить все её детали, прежде чем она станет возможной. Вот лучше каждую деталь продумать, и тогда хотя бы станет ясно, что в новом языке точно должно быть и чего точно не должно.
Здравствуйте, eao197, Вы писали:
Д>>>Я думаю, намного лучше, когда есть возможность добавлять необходимую выразительность самому
E>Ты думаешь? E>dir.each { |filename| block } => dir E>Calls the block once for each entry in this directory, passing the filename of each entry as a parameter to the block.
Я не совсем это имел ввиду в примере про FindFirst/FindNext, но это приемлемая альтернатива. Я имел ввиду автоматическую генерацию объектов-генераторов (термин из Питона 2.4). Т.е. ты пишешь обычный код, но он компилируется по-особому, сохраняя состояние не в стеке (как это делает обычный код), а в некоторой структуре данных.
Очень удобно. В С++ я могу написать объект-итератор для FindFirstFile/FindNextFile, но это требует много нудной работы, тогда как всего лишь дополнительная фича в языке позволила бы сделать это _обычным_, естественным кодом (циклом while).
А из разряда фантастики — это язык, где можно добавить необходимую выразительность самому. Как например в Руби добавить возможность одной инструкцией вставить во все функции модуля одинаковый код проглога/эпилога, или определить DSL на Руби, абсолютно эквивалетный по синтаксису Лиспу. Это возможно? По-моему, в общем случае это невозможно вообще.
Здравствуйте, Кодёнок, Вы писали:
Кё>Я не совсем это имел ввиду в примере про FindFirst/FindNext, но это приемлемая альтернатива. Я имел ввиду автоматическую генерацию объектов-генераторов (термин из Питона 2.4). Т.е. ты пишешь обычный код, но он компилируется по-особому, сохраняя состояние не в стеке (как это делает обычный код), а в некоторой структуре данных.
Кё>Очень удобно. В С++ я могу написать объект-итератор для FindFirstFile/FindNextFile, но это требует много нудной работы, тогда как всего лишь дополнительная фича в языке позволила бы сделать это _обычным_, естественным кодом (циклом while).
В C++ это действительно так, в Ruby на несколько порядков проще.
Кё>А из разряда фантастики — это язык, где можно добавить необходимую выразительность самому. Как например в Руби добавить возможность одной инструкцией вставить во все функции модуля одинаковый код проглога/эпилога,
Одной инструкцией вряд-ли, а вот несколькими -- возможно.
module Kernel
alias :intercepted_require :requiredef require( a_module )
puts "starting requiring #{a_module}"
intercepted_require a_module
puts "finishing requiring #{a_module}"
end
end
require "rubygems"
require "optparse"
puts "Done!"
Здесь просто переопределяется стандартный метод Kernel#require, с помощью которого осуществляется подгрузка модулей в Ruby.
Кё> или определить DSL на Руби, абсолютно эквивалетный по синтаксису Лиспу. Это возможно? По-моему, в общем случае это невозможно вообще.
По-моему, это и не нужно. Хочется программировать на Лиспе, программируй на Лиспе. А попытки притянуть Лисп в C++ вот к чему приводят: Lisp на C++
Имхо, DSL должен не менять синтаксис основного языка, а позволять писать на том же языке, но на более высоком уровне абстракции.
Например:
directory "testdata"
file "testdata" => ["otherdata"]
file "testdata" do
cp Dir["standard_data/*.data"], "testdata"
end
это одновременно и текст DSL Rake, и, в тоже самое время, абсолютно родной Ruby код. И если на более высоком уровне абстракции мне нужно выполнить какую-то низкоуровневую операцию, то я могу это сделать:
file "prog" => ["a.o", "b.o"] do |t|
sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
end
(здесь t.prerequisites.join -- это обращение к методу Array#join, т.е. мы опускаемся с уровня DSL на уровень обычного Ruby кода, но делаем это совершенно естественным образом).
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, Дарней, Вы писали:
Кё>>>Я имел ввиду не это, а отсутствие необходимой выразительности в языке.
Д>>Я думаю, намного лучше, когда есть возможность добавлять необходимую выразительность самому
Кё>По-моему это из разрада фантастики. Либо это Лисп, что уже неудовлетворительно из-за трудного для восприятия синтаксиса.
Здравствуйте, Кодёнок, Вы писали:
Кё>И компилятор автоматически сделает код, сохраняющий своё состояние между "yield-ами".
Ну, вот и подумай, что лучше, если ты будешь иметь возможность расширить язык этим yield и соовтевтующей генерацией кода, или когда ты будешь вынужден ждать когда в твой любимый ХХ добавят такую фичу?
Вот в C# 2.0 такую фичу добавили, но я бы был в сто раз более рад если в него добавили нечто что позволяло бы мне самому описывать синтаксические конструкции которые я могу бы во время компиляции превращать в некую реализацию паттерна.
Ведь компилятор C# 2.0 просто создает класс в котором находится реализация ДКА соотвествющая коду из итератора. Так дайте мне возможность сделать это сомому!
И главно, наплевать на Вирта и растереть. Путь он кому угодно объясняет, что "синтаксис должен быть простым и не изменяемым". Я уверен, что синтаксис должен быть игбким и удобным. Я уверен, что чем проще описывается решение, тем проще его будет развивать и поддерживать. И ДСЛ на базе некого механизма описания синтаксиса + метапрограммирование позволило бы свернуть горы.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
Кё>>И компилятор автоматически сделает код, сохраняющий своё состояние между "yield-ами".
VD>Ну, вот и подумай, что лучше, если ты будешь иметь возможность расширить язык этим yield и соовтевтующей генерацией кода, или когда ты будешь вынужден ждать когда в твой любимый ХХ добавят такую фичу?
Я тоже за это, но пусть хоть кто-нибудь хоть какой-нибудь реальный пример приведёт, чтобы убедиться, что это возможно Ну например? Что надо добавить в C#, чтобы он научился делать объекты-генераторы из обычного кода, при условии, что это специально не предусмотрено? Т.е. возможности расширения настолько общие, что позволяют сделать yield, но не созданные специально для него?
Ну разумеется, это C++ после очередного релиза стандарта (это ответ на тему топика)
Кё>Т.е. пойти от проблем. Если каждый вспомнит случай из практики, когда он упирался в ограниченность своего языка (т.е. чувствовал, что возможно более красивое решение, если бы язык позволял его сделать). Из чего станет ясно, какие фичи новый язык должен уметь,
Ни разу не упирался в ограниченность своего языка
И вообще, зачем выбрасывать то, что реально работает?
Здравствуйте, LeeMouse, Вы писали:
LM>Ни разу не упирался в ограниченность своего языка LM>И вообще, зачем выбрасывать то, что реально работает?
Что работает? Работают только люди, а инструменты не работают. Инструмент "ассемблер x86" тоже реально "работает" и позволяет написать 100% программ, которые пишутся на высокоуровневых языках, но реально сделать с его помощью удаётся многократно меньше.
Здравствуйте, Кодёнок, Вы писали:
Кё>Я тоже за это, но пусть хоть кто-нибудь хоть какой-нибудь реальный пример приведёт, чтобы убедиться, что это возможно Ну например? Что надо добавить в C#, чтобы он научился делать объекты-генераторы из обычного кода, при условии, что это специально не предусмотрено? Т.е. возможности расширения настолько общие, что позволяют сделать yield, но не созданные специально для него?
Нужно добавить некий макрос который встретив например:
yield_return(x);
поймет, что нужно преобразовать это дел в конечный автомат.
Если появится возмжность еще и новые ключевые слова добавлять, так это вообще будет здорово. Но я и так буду счаслив.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.