Если функциональные языки действительно лаконичны, почему они не имеют лучшего ранга в языковой перестрелке? - PullRequest
23 голосов
/ 27 августа 2010

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

  1. Python, Ruby, JavaScript, Perl, Lua, PHP, Mozart / OZ
  2. OCaml,Erlang, Racket, Go, Scala, F #, Smalltalk
  3. Pascal, Clean, Haskell, Common Lisp, C #, Java, C
  4. C ++, Ada, ATS

Интересно, почему.Победителями кажутся простые старые динамические языки.Эрланг, Ракет (урожденная схема PLT) и F # все в порядке.Haskell и Common Lisp не выглядят более лаконичными, чем заявленная для многословия Java.

ОБНОВЛЕНИЕ:

Я нашел проницательный пост на эту темус диаграммами.Я также нашел аналогичное сравнение языков для более крупной программы (простой трассировщик лучей).В целом, я бы не сказал, что получил «ответ», но у меня есть пища для размышлений.

Ответы [ 8 ]

23 голосов
/ 27 августа 2010

Если функциональные языки действительно краткое ...

1 - Программирование в большом отличается от программирования в маленьком .

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

2 - Большая часть того, что вы видите на страницах с обзорами игр, относится только к самым быстрым программам, добавляемым для каждой языковой реализации (более медленные программы обычно удаляются с веб-сайта через некоторое время - когда и какие более медленные программы удаляются в основном произвольно).

{edit: Адам, так как вы не хотите поверить мне на слово, что сводные страницы относятся только к самым быстрым программам - посмотрите на сценарий, который фильтрует строки данных для «Какого программирования язык лучше? стр. Посмотрите на строку 80 и строку 82 в функции ValidRowsAndMins в lib_scorecard.php - Алиот выдает собственный сертификат безопасности, поэтому ваш браузер будет жаловаться.}

Итак, на примере Haskell вы смотрите на размер кода самых быстрых программ на Haskell, которые были добавлены.

3 - Ни одна из метеорологических программ не была удалена, а метеоритный конкурс - это программный конкурс без ограничений - самая маленькая метеоритная программа Haskell - самый медленный метеоритный конкурс Haskell программа .

18 голосов
/ 27 августа 2010
  1. Ни один язык не всегда превосходит другой (ну, есть несколько исключений ...;)), то же самое относится и к группе языков с широкими категориями.Тесты охватывают широкий спектр тем, и X может быть менее подходящим для одного, чем Y.
  2. Исходный код распакован, мы на самом деле не знаем, сколько строк какой длины были программы (да,это показатель)
  3. Значительное число функциональных языков все еще работает намного лучше, чем широко распространенные императивные, статические языки - дело не в том, что функциональные языки программирования не лаконичны, но динамические языки допускают еще больше лаконичных программ
  4. По крайней мере, в Haskell, большой потенциал для краткости исходит от абстракций, которые вы можете создать сами, но вам действительно нужно создавать их самостоятельно и включать в свое решение.Умный хакер Haskell может реализовать монаду в 20 строк, которая позволяет решить небольшую задачу в 20 строк вместо 30 - абстракция не окупается для небольшой программы, но может сохранить много строк в более крупной (например, 200 строк вместоиз 300) программы.Я думаю, то же самое относится и к Лиспу (только макрос вместо монады)
  5. Не принимайте фанатов слишком серьезно.FP - это круто и стоит того, чтобы на него взглянуть, но он не излечивает рак и волшебным образом не укорачивает код на 25%
  6. Они все еще могут побеждать динамические языки для некоторых областей: например, древовидные структуры данныхи их обработка чрезвычайно естественно выражена во многих функциональных языках благодаря алгебраическим типам данных и сопоставлению с образцом.
9 голосов
/ 28 августа 2010

Это похоже на возможность выкрутиться:

Существуют ли статистические исследования, которые указывают на то, что Python "более продуктивен"?

Дело в том, что оригиналВопрос в том, чтобы попытаться использовать некоторые (ничтожные, неуместные) данные для обобщения сравнений между языками программирования.Но на самом деле, практически невозможно использовать какие-либо данные для проведения каких-либо разумных общих количественных сравнений языков программирования.

Однако есть некоторая пища для размышлений:

  • Все вещиБудучи равными, языки с динамической типизацией, вероятно, будут более краткими, поскольку им не нужно тратить время на описание типов данных
  • При прочих равных среди языков со статической типизацией языки с выводом типа могутЯ бы сказал более кратко, поскольку им не нужно объявлять типы повсеместно
  • При прочих равных среди статически типизированных языков те, у которых есть шаблоны / шаблоны, с большей вероятностью будут краткими, поскольку языки без нихтребуется повторный код или приведение и косвенное указание
  • При прочих равных, языки с кратким лямбда-синтаксисом, вероятно, будут более краткими, поскольку лямбда, пожалуй, самая важная абстракция в программировании для избежания повторений и шаблонов

Тем не менее, все вещине равны, не длинным выстрелом.

2 голосов
/ 10 марта 2015

Недавно я перенес относительно короткую Java-программу на OCaml.В прошлом я баловался с SML и Haskell, а также большим опытом работы с C.

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

По моему опыту, чисто функциональное программирование (PFP) элегантно, но не более кратко, чем императивно.В PFP меньше «деклараций», но больше «конверсии»;например, распаковка из кортежей, хвостовых рекурсивных вспомогательных функций и т. д. Таким образом, ни одна парадигма не позволяет использовать неизолированное выражение чистого «мяса» программы.

PFP требует меньших затрат на запуск чего-либо и написание программычтобы продемонстрировать, что данный алгоритм в принципе работает хорошо в PFP.Но, расширяя его, чтобы сделать его «реальным», имея дело с условиями ошибок и недопустимым вводом и диагностикой печати, вы добавляете много раздувания, которое было бы легче преодолеть на императивном языке.

2 голосов
/ 28 августа 2010

Программы в игре Alioth на самом деле не представляют программы на этих языках в целом. С одной стороны, реализации там сильно оптимизированы для конкретной инфраструктуры Shootout, что может привести к менее идиоматическому и более раздутому коду на функциональном языке. Это похоже на то, как некоторые библиотеки Ruby будут писать критический для производительности код на C - если посмотреть на этот код C и объявить Ruby раздутым и низкоуровневым, то это на самом деле не даст языку шатость.

С другой стороны, большая часть того, почему функциональные языки преподносятся как настолько краткие, заключается в том, что они хороши в создании абстракций. Это имеет тенденцию помогать больше в больших программах, чем в чудесах с одной функцией, поэтому языки, специально спроектированные для краткости, выигрывают там. Python, Perl и Ruby специально предназначены для коротких программ, в то время как у большинства функциональных языков есть другие цели (хотя нельзя сказать, что они просто игнорируют размер кода).

1 голос
/ 27 августа 2010

Вам следует учитывать тот факт, что языки вашей группы 1 (сценарии) работают в 30-100 раз медленнее, чем C / C ++, а для функциональных языков - от 2 до 7 раз. Программы в списке оптимизированы для скорости, и измерение чего-либо еще является второстепенной проблемой, которая на самом деле не является хорошим показателем реального состояния языка.
Более интересно взглянуть на таблицу , где размер кода и время выполнения имеют вес 1. Таким образом, вы получаете сравнение соотношения скорости и удобства обслуживания, которое кажется лучшим показателем, чем просто размер кода. *

1 голос
/ 27 августа 2010

Должно быть как-то связано с обширными библиотеками ООП, доступными для большинства языков вашего уровня 1, и с простыми старыми хаки, такими как обратные ссылки для вызовов оболочки и синтаксис Perl Regex. Выходя из питона

pw = file("/etc/passwd")
for l in pw:
    print l.split(':')[0]

Печать всех имен пользователей в системе заняла бы гораздо больше кода, если бы не абстракции, которыми завалены языки ОО. Я не говорю, что это невозможно сделать в других парадигмах, но тенденция такова, что у каждого типа есть много функций-членов, которые делают утомительные задачи простыми. Лично я считаю чисто функциональные языки полезными только для академических целей (но опять же, что я знаю).

0 голосов
/ 05 сентября 2010

Победителями кажутся простые старые динамические языки.

Лисп - это очевидный контрпример, простой старый динамический язык, который чрезвычайно многословен.С другой стороны, APL / J / K, вероятно, будет гораздо более кратким, чем любой из других языков, и они динамичны.Кроме того, Mathematica ...

Haskell и Common Lisp не выглядят более лаконичными, чем заявленная для многословия Java.

Ваши данные предназначены для крошечных программ, которыебыли оптимизированы для производительности, и мера - это размер кода после сжатия с использованием алгоритма GZIP для конкретного параметра , поэтому вы не можете сделать общие выводы из них в одиночку.Возможно, более обоснованным выводом будет то, что вы наблюдаете раздувание, возникающее в результате оптимизации производительности, поэтому наиболее краткими языками ваших данных являются те, которые не могут быть оптимизированы из-за их фундаментальной неэффективности (Python, Ruby, Javascript, Perl, Lua, PHP).И наоборот, Haskell может быть оптимизирован с достаточными усилиями для создания быстрых, но многословных программ.Это действительно недостаток Haskell против Python?Другим не менее верным выводом является то, что Python, Ruby, Perl, Lua и PHP лучше сжимают, используя алгоритм GZIP для этой настройки.Возможно, если вы повторите эксперимент с использованием кодирования по длине прогона или арифметического кодирования или LZ77 / 8, возможно, с предварительным обработкой BWT или другим алгоритмом, вы получите совершенно другие результаты?

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

(* This module is a workaround for a bug in the Str library from the Ocaml
 * distribution used in the Computer Language Benchmarks Game. It can be removed
 * altogether when using OCaml 3.11 *)
module Str =
struct
  include Str

  let substitute_first expr repl_fun text =
    try
      let pos = Str.search_forward expr text 0 in
      String.concat "" [Str.string_before text pos;
                        repl_fun text;
                        Str.string_after text (Str.match_end())]
    with Not_found ->
      text

  let opt_search_forward re s pos =
    try Some(Str.search_forward re s pos) with Not_found -> None

  let global_substitute expr repl_fun text =
    let rec replace accu start last_was_empty =
      let startpos = if last_was_empty then start + 1 else start in
      if startpos > String.length text then
        Str.string_after text start :: accu
      else
        match opt_search_forward expr text startpos with
        | None ->
            Str.string_after text start :: accu
        | Some pos ->
            let end_pos = Str.match_end() in
            let repl_text = repl_fun text in
            replace (repl_text :: String.sub text start (pos-start) :: accu)
                    end_pos (end_pos = pos)
    in
      String.concat "" (List.rev (replace [] 0 false))

  let global_replace expr repl text =
    global_substitute expr (Str.replace_matched repl) text
  and replace_first expr repl text =
    substitute_first expr (Str.replace_matched repl) text
end

Одноядерные версии часто содержат много кода для параллелизма, например, regex-dnaв OCaml .Посмотрите на чудовище, которое fasta в OCaml : вся программа дублируется дважды и включает размер слова!У меня есть старая версия fasta на диске OCaml, которая меньше, чем пятая часть этого размера ...

Наконец, я должен отметить, что я добавил код на этот сайт только для того, чтобы он был отклонен, потому чтоэто было слишком хорошоПомимо политики, двоичные деревья OCaml раньше содержали выражение «де-оптимизирован Исааком Гуи» (хотя комментарий был удален, деоптимизация все еще там, что делает код OCaml более длинным и медленным), так что вы можете предположить, что всерезультаты были субъективно подправлены, чтобы внести предвзятость.

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

...