Почему синтаксис функционального языка не ближе к человеческому языку?

14

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

Есть ли причина, почему он не более выразительный , более близкий к человеческому языку?

Я понимаю, что FP хорош в моделировании математических понятий и заимствовал некоторые из его кратких средств выражения, но все же это не математика ... это язык.

JohnDoDo
источник
4
@ rachet freak: :) так есть ли кто-то, разработанный парнем, который ненавидит польскую нотацию?
JohnDoDo
10
@ratchetfreak Каким образом синтаксис Haskell напоминает польскую нотацию? Операторы Haskell являются инфиксными, как и операторы большинства других языков (а вызовы функций являются префиксами - также как и вызовы функций большинства других языков).
sepp2k
9
Это довольно большое предположение / скачок, который вы делаете, что «ближе к человеческому языку» приравнивается к «более выразительному».
Мэтт Болл
7
Вы когда-нибудь слышали о Коболе и Фортране?
ot--
7
По той же причине, по которой математики заменили длинные латинские фразы алгебраическими выражениями. С небольшой практикой более компактная запись становится намного более продуктивной.
Кевин Клайн

Ответы:

14

Функциональные языки, такие как Хаскелл и его предшественница Миранда, выросли из математической концепции лямбда-исчисления . Со страницы Википедии:

Лямбда-исчисление (также написанное как λ-исчисление или называемое «лямбда-исчисление») - это формальная система математической логики для выражения вычислений посредством связывания и подстановки переменных.

...

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

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

Точность, с которой математические записи и компьютерные языки могут описывать требования, и точность, с которой компьютеры требуют написания своих инструкций, хорошо коррелируют друг с другом. Неточность естественного языка, однако, создает огромный барьер для его использования для программирования компьютеров. Даже (возможно) наиболее успешные среды программирования на естественном языке, такие как Wolfram Alpha, нуждаются в значительном опыте в предметной области для эффективного использования.

Марк Бут
источник
29

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

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

С другой стороны, вы можете показать любому математику или логику фрагмент кода, подобный следующему:

x = x + 1

и он будет совершенно сбит с толку, говоря: «Это не имеет смысла, нет xтакого, что xравно xплюс 1».

Независимо от того, является ли какое-то конкретное обозначение «загадочным» или нет, это вопрос мнения и знакомства.

Йорг Миттаг
источник
8
Есть только одна проблема с этим ответом: я не математик.
JohnDoDo
6
@ sepp2k: я бы не согласился. Для большинства людей без предварительного ознакомления с языками программирования и некоторым базовым математическим фоном синтаксис на Haskell будет гораздо проще понять, чем типичный процедурный код со всеми его побочными эффектами и сложными операторами сред, в которых выполняются операторы. Синтаксис, подобный, whereпозволяет сконцентрировать сущность функция в одной строке.
Бенджамин Банье
17
-1: этот ответ кажется в значительной степени педантичным. Я вполне уверен, что ОП означало разговорный язык.
Стивен Эверс
6
На самом деле, я уверен, что x = infinityэто действительно решает уравнение.
DeadMG
6
Ну, языки программирования также разрабатываются людьми ... Таким образом, по вашему определению, они являются человеческими языками.
Marco-Fiset
13

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

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

Например, я мог бы написать обязательно:

for each (Person person in people)
    print(person.name)

который полностью читается как английский.

Версия Haskell может быть (и это не допустимый Haskell, но только для синтаксического сравнения):

map (print . name) people

который требует меньше кода и меньше детализации - мне не нужно разбивать элементы на циклы и их переменную (и) ( for each (...)), mapфункция позаботится об этом за меня.

Работа на этом уровне может занять некоторое привыкание. Если это поможет, Haskell был, вероятно, самым сложным временем, когда я изучал новый язык с тех пор, как начал программировать, и я знаю> 10 языков (включая Lisp). Это стоило изучения, хотя.

Павел
источник
8

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

Я думаю, что здесь есть несколько сил:

  • Разработчики функциональных языков обязательно имеют сильный математический фон, поэтому они используют математические обозначения, которые для них естественны.

  • Большая выразительность (т.е. сила высказываний, а не близость к английскому) любого языка (IMO) имеет соответствующую цену в крутизне кривой обучения. Terseness - высоко ценимое качество в Scala, причем многие вещи являются необязательными.

  • Функциональные языки просто делают вещи совсем по-другому, поэтому основные операции не отображаются на императивные конструкции.

Ричард Клоуз
источник
3
Я также добавил бы, что часто функциональные языки могут выражать понятия более высокого порядка, поскольку они являются более абстрактными, их сложнее осмысленно назвать
jk.
1
@jk, да, согласился! В то же время, именно поэтому у них есть крутая кривая обучения для программистов с обязательным опытом и небольшой математикой (как у меня), и почему они того стоят.
Ричард Клоуз
3

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

Что касается ключевых слов, одним из ответов будет то, что ключевые слова не позволяют использовать определенные слова в качестве имен переменных. Например, меня всегда раздражает, когда я хочу вызывать свои переменные fromи toв языках, где одним из них является ключевое слово - как в Python.

Еще одна причина для символических операторов в целом - краткость. Это на самом деле не применимо в ваших конкретных примерах понимания списка ( <-не короче in), но во многих случаях это так.

Еще одна причина - удобочитаемость. Это может показаться нелогичным, потому что символические операторы часто сложнее выучить, поскольку их «имена» на самом деле ничего не говорят вам о том, что они делают (в то время как имя функции обычно будет), но как только вы узнаете, что делает данный оператор, выражения с инфиксными символическими операторами часто легче проанализировать для человека, чем с множеством вызовов буквенно-цифровых префиксных функций, поскольку операторы легче визуально отличить от операндов таким образом. Например, большинство людей согласятся с тем, что 2 * 3 + 4их легче прочитать, чем add (mult 2 3) 4или add(mult(2, 3), 4).

sepp2k
источник
@PeterTaylor Нет, только я глупый ;-) Исправлено.
sepp2k
3

Императивные языки программирования в большинстве своем не ближе к естественным, чем, скажем, Haskell.

Тем не менее, некоторые из них предназначены для более близкого к английскому языку: например, Cobol и Hypercard. Уроки, которые я извлек бы из этих примеров:

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

Сообщается, что компьютерный язык Perl был разработан с учетом некоторых более тонких аспектов естественного языка . Я бы сказал, что Perl работает лучше, чем Cobol или Hypercard, но в целом люди по-разному относятся к Perl.

comingstorm
источник
3

Я думаю, что Haskell становится настолько похожим на человеческий язык, насколько это возможно без введения сумасшедшего синтаксиса. Это действительно идет вразрез с этим, например, с whereпредложением отложить определение и с синтаксисом понимания списка, который я и написал на доске. Это также позволяет избежать посторонних символов, таких как фигурные скобки, и имеет свободное использование отступов. Типичный пример - быстрая сортировка:

qsort [] = []
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
               where lesser = [x | x <- xs, x <= p] 
                     greater = [x | x <- xs, x > p]

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

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

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

Andrea
источник
3
Я вряд ли назвал бы это читаемым человеком. Я знаю быструю сортировку. Я знаком с тем, как настроить его на нескольких разных языках, я знаю, что он должен делать, и я до сих пор не могу сделать голову или хвост из нижней половины этого фрагмента кода.
Мейсон Уилер
Я думаю, это действительно зависит от вашего фона. Это так же ясно, как и для меня ...
Андреа
2
В любом случае, это должно напоминать эту запись: purplemath.com/modules/setnotn.htm
Andrea
4
Ты уверен, что не должно быть ++ [p] ++?
Питер Тейлор
1
@Mason: Это кажется довольно ясно мне, и я никогда не писал линию Haskell
Кевин Клайн
2

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

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

GlenPeterson
источник
Я думаю, что это лучший ответ - единственный, который четко разграничивает процесс и утверждения.
Milind R