Что вы подразумеваете под выразительностью языка программирования?
Я часто вижу слово "выразительность", когда люди хотят подчеркнуть, что один язык лучше другого. Но я не понимаю, что именно они имеют в виду.
- Это многословие / краткость? Я имею в виду, если один язык может записать что-то более короткое, чем другой, означает ли это выразительность? Пожалуйста, обратитесь к моему другому вопросу - статья о плотности кода как мера мощности языка программирования
- Это сила языка? Пол Грэм говорит, что один язык является более мощным, чем другой язык, в том смысле, что один язык может делать то, что другой язык не может сделать (например, LISP может делать что-то с макросом, что другой язык не может делать).
- Это просто то, что облегчает жизнь? Регулярное выражение может быть одним из примеров.
- Это другой способ решения той же проблемы: что-то вроде SQL для решения проблемы поиска?
Что вы думаете о выразительности языка программирования? Можете ли вы показать выразительность, используя некоторый код?
Какая связь с выразительностью и DSL? Люди придумывают DSL, чтобы получить выразительность?
11 ответов
Лично я чувствую, что "выразительность" языка действительно сводится к тому, насколько четко языковые конструкции могут "выражать" намерения разработчика.
Например, я чувствую, что C# (особенно LINQ через C# 3+) становится намного более выразительным. Это заявление LINQ является отличным примером:
var results = collection.Where(item => item > 5);
Не зная деталей языка или используемой реализации, намерение разработчика (на мой взгляд) очень ясно в приведенном выше утверждении.
Я не думаю, что многословность языка равна его выразительности, однако существует определенная взаимосвязь. Если языку требуется много кода для выражения абстракции, он менее выразителен. Это две взаимосвязанные, но разные концепции.
То же самое относится и к силе - хотя здесь особенности языка (то есть: власть) должны быть достаточно полными, чтобы ясно выразить абстракцию. Без этого выразительность будет страдать. При этом язык может быть очень "мощным" с точки зрения возможностей, но не обязательно быть выразительным, если набор функций труден для понимания.
"Выразительность" означает способность говорить только то, что вы хотите сделать:
bad_event = events.find(&:bad)
а не как вы хотите это сделать:
i = 0
bad_event = nil
while i < events.size && bad_event.nil?
event = events[i]
if event.bad?
bad_event = event
end
i += 1
end
Среди вещей, которые способствуют выразительности:
- Отсутствие необходимого синтаксического сахара
- Первоклассные функции
- Вывоз мусора
- Либо динамическая типизация, либо вывод типа
- Языковое ядро не является рабски минималистичным
- Хороший функционал в стандартной библиотеке
В некоторой степени выразительность любого языка может быть увеличена путем добавления как можно большего количества "как это сделать" в подпрограммы / объекты, чтобы большая часть оставшегося кода была "что делать". Количество кода "как это сделать", необходимого в самом абстрактном коде, является одной мерой выразительности языка: чем больше код выглядит как псевдокод, тем более выразительным он является намерением программиста.
Можно также подумать о "метаэкспрессивности" языка: насколько выразителен язык при создании предметно-ориентированных языков?
Мне нравится понятие Матиаса Феллайзена о выразительной силе, которое сравнительно:
Язык A является строго более выразительным, чем язык B, если выполняются оба следующих условия:
- Любую программу, написанную на языке B, можно переписать на языке A, сохранив при этом существенную структуру программы.
- Некоторые программы, написанные на языке A, должны быть подвергнуты насильственной реструктуризации, чтобы быть написанными на языке B.
Обычно мы хотим сделать эти сравнения, посмотрев на какое-то "основное ядро" языка - например, может быть, мы хотим рассмотреть диалект C только с while
и не также for
а также do...while
, Или, может быть, мы хотим рассмотреть диалект Perl только с префиксом if
форма и нет unless
форма. Но иногда эти поверхностные синтаксические различия являются именно тем, что мы подразумеваем под "выразительной силой"; некоторым программистам важно сказать
die ("found no solutions") unless length(solutions) > 0;
вместо
if (length(solutions) == 0) { die("found no solutions"); }
Таким образом, вы должны установить, спрашиваете ли вы о выразительной силе поверхностного синтаксиса или более глубокой структуре.
Еще одна вещь, которая мне нравится в идее Феллайзена, заключается в том, что она допускает понятие двух языков, которые определенно отличаются, но ни один не является более выразительным, чем другой.
Вы можете прочитать более подробную экспозицию на первых двух страницах его статьи " О выразительной силе языков программирования". После этого приходит много теории с острыми головами:-)
Если вам нужен ответ, который несколько теоретический, но более строгий, чем у большинства, возможно, вы захотите взглянуть на книгу Матиаса Феллайзена " О выразительной силе языков программирования". Я уверен, что если немного осмотреться в сети, получится как минимум несколько копий.
Если вы хотите получить более практичный ответ о том, что на самом деле имеет в виду большинство людей, когда говорят это, то, честно говоря, это совсем другое. Обычно, по моему опыту, "выразительный" язык означает: "Мне нравится язык, но я не могу привести какую-либо объективную поддержку для этого". И наоборот, такие вещи, как "менее выразительный" или "не выразительный", обычно означают: "Мне не нравится язык [также], но я не могу сослаться на какую-либо объективную поддержку для этого".
"Не выразительный" часто похож на политика, обвиняющего другого в том, что он "фашист" - явно уничижительный, но без какого-либо значимого определения того, что предположительно неправильно.
Одна из больших проблем связана с фундаментальным расхождением во мнениях. Есть, по крайней мере, две принципиально разные общие идеи, которые люди, похоже, имеют относительно выразительности:
- способность выражать самые разные идеи.
- способность выражать некоторые конкретные идеи четко (и часто кратко).
Чтобы рассмотреть некоторые крайние примеры, язык ассемблера будет квалифицирован как очень выразительный по первым критериям - вы можете делать практически все на языке ассемблера, что вы можете делать на языке более высокого уровня, и вы можете делать некоторые вещи на языке ассемблера, которые вы не можете по сути, любой язык более высокого уровня.
Очевидно, что на втором языке ассемблер выглядит не очень хорошо - обычно требуется довольно много непрозрачного кода для выполнения многих задач. Эта мера будет иметь тенденцию отдавать предпочтение таким языкам, как Haskell или APL, чтобы привести только пару примеров.
Эти два понятия о том, что означает "выразительный", часто близки к диаметрально противоположным. Первый, как правило, предпочитает языки "самого низкого" уровня, а второй - "самый высокий" уровень. Комбинируя эти два, довольно тривиально выбрать определение, которое "доказывает", что язык по вашему выбору является наиболее выразительным.
Для меня это способность языка четко выражать мою логику и идеи с помощью кода таким образом, чтобы кто-то еще, читая написанный мной код, мог легко понять, о чем я думал, когда делал это.
В Википедии есть немного о концепции. Я сам понимаю, что язык может достичь большего с меньшими затратами (так называемое "неформальное использование" в статье Википедии).
Я считаю JavaScript выразительным (хотя это может быть из-за того, что Дуглас Крокфорд разработал эту идею в моем приложении), потому что он может сделать так много всего с помощью нескольких ключевых слов. Например, function
Ключевое слово - это функция, а также метод, класс и лямбда-выражение.
Некоторая иллюстрация кода (опуская некоторые детали для краткости) в JavaScript. Это класс событий, который я написал:
SJJS.util.Event = (function() {
var _listeners = [];
var _listenerReturns = [];
return {
addDomListener: function(element, eventName, listener) {
},
trigger: function(element, eventName) {
},
removeListener: function(eventlistener) {
}
}
})();
С просто function
, var
и некоторые фигурные скобки и скобки я сделал статический класс с методами и закрытыми переменными.
Возьмите для примера LINQ. Это позволяет использовать функциональное программирование.
Функциональное программирование подчеркивает применение функций, в отличие от императивного стиля программирования, который подчеркивает изменения в состоянии.
LINQ позволяет вам выразить то, что вы хотите сделать, а не как это сделать. Это яркий пример выразительности.
Из Википедии: В информатике выразительная сила (также называемая выразительностью или выразительностью) языка - это широта идей, которые могут быть представлены и переданы на этом языке. Чем выразительнее язык, тем больше разнообразия и количества идей, которые он может использовать для представления.
Итак, я согласен. "Как легко, полно и сочиняемо язык для вас, чтобы выразить свои намерения". Я считаю, что это мера выразительности.
ВОПРОС: Это многословие / краткость? Я имею в виду, если один язык может записать что-то более короткое, чем другой, означает ли это выразительность?
Нет. Например, является ли язык Brainfuck выразительным? Я так не думаю. Посмотрите на пример Hello World в Brainfuck:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Или: язык hq9plus. Код Hello World:
H
ВОПРОС: Это сила языка? Пол Грэм говорит, что один язык является более мощным, чем другой язык, в том смысле, что один язык может делать то, что другой язык не может сделать (например, LISP может делать что-то с макросом, что другой язык не может делать).
Я не согласен с Полом. Как видно из приведенных выше примеров, язык hq9plus делает Hello World
с одной буквы: H
, Принимая во внимание, что большинство других языков будут делать это с гораздо большим количеством букв. Но вы можете создавать составной и легко читаемый код на других языках. Если hq9plus делает Hello World
с H
это значит, что это мощно? Я верю нет.
ВОПРОС: Это просто то, что облегчает жизнь? Регулярное выражение может быть одним из примеров.
Регексы великолепны, но иногда они теряют свою выразительную силу. Иногда это зависит от программиста.
ВОПРОС: Это другой способ решения той же проблемы: что-то вроде SQL для решения проблемы поиска?
Половина Да. SQL является декларативным и очень выразительным языком. Потому что базовые механизмы и технологии могут развиваться и изменяться без вас, чтобы изменить ваши запросы SQL. Это делает это очень выразительным. Есть много запросов, которые работали в течение десятилетий, и основная технология баз данных изменилась. Но ваши запросы не должны. Я думаю, что это связано с силой его выразительности.
Я также считаю, что функциональные языки очень выразительны. Потому что вы описываете только свое намерение, а не свои практические рекомендации, и базовые технологии всегда могут измениться и оптимизировать, но это не повредит вашему выразительному коду.
Пример:
// top 10 products with rating higher than 5
return products
.sort(p => p.rating)
.filter(p => p.rating > 5)
.map(p => p.title)
.take(10)
Выше программа выразительна, она передает ваши намерения. И, скорее всего, он не изменится, когда изменятся основные механизмы.
Я всегда считал, что это примерно эквивалентно высокому уровню языка. Если вы хотите попытаться выразить выразительность количественно, единицы измерения будут что-то вроде "инструкции машинного кода на утверждение языка"
Более выразительный язык может быть очень хорош при выполнении довольно большой работы без написания большого количества кода. Тем не менее, он, вероятно, будет более специфичным для домена и немного медленнее для некоторых задач, чем менее выразительным.
Вообще говоря, с языком программирования, который завершается по Тьюрингу, вы можете делать все, что может делать другой язык с завершением по Тьюрингу. При этом, некоторые могут сделать это намного лучше, чем другие.
Под экспрессивностью я понимаю, что вы можете сказать легко и насколько хорошо / ясно это можно сказать. Способность быть кратким является частью этого (очень мощный и лаконичный язык такой же, как J). Обычно я нахожу, что краткость - хороший признак выразительности. Если язык может выразить сложную операцию простым способом, он идет в правильном направлении.
Что касается силы, выразительность не вся сила языка. Хотя это может быть частью этого, скорость, безопасность, стабильность, все эти факторы также влияют.
пример: суммирование списка в Common lisp с использованием оператора цикла является кратким и выразительным
(loop for x in list sum x)
Точность, краткость и удобочитаемость являются основными составляющими выразительности.