web-dev-qa-db-ja.com

関数型言語の構文が人間の言語により近くないのはなぜですか?

私は関数型プログラミングに興味があり、Haskellと直接対決することにしました。頭が痛いです...しかし、最終的にはそれを取得します...私は1つの好奇心を持っています。

理由はありますかより表現力がない理由、より人間の言語に近いですか?

FPは数学的な概念のモデリングに優れており、簡潔な表現方法の一部を借用しましたが、それでも数学ではありません...それは言語です。

14
JohnDoDo

Haskell とその前例 Miranda のような関数型言語は、 lambda calculus の数学的概念から生まれました。ウィキペディアのページから:

ラムダ計算(ラムダ計算とも呼ばれる、または「ラムダ計算」と呼ばれる)は、変数のバインドと置換によって計算を表現するための数学的論理の正式なシステムです。

...

ラムダ計算は、プログラミング言語の理論の発展において重要な役割を果たしてきました。コンピュータサイエンスでラムダ計算に最もよく対応するのは、基本的に計算を実装する関数型プログラミング言語です(一部の定数とデータ型が追加されています)。プログラミング言語を超えて、ラムダ計算は証明理論にも多くのアプリケーションがあります。これの主な例は、カリーハワード対応です。これは、型付きラムダ計算の異なるシステムと形式論理のシステム間の対応を提供します。

この歴史があるため、これらの関数型言語(およびより命令的な言語の関数型要素)の構文は、ラムダ計算で使用される数学的表記法に強く影響されます。

数学的表記とコンピューター言語の両方が要件を記述できる精度と、コンピューターが命令を記述することを要求する精度は、互いによく相関しています。ただし、自然言語の不正確さは、コンピューターのプログラミングでの使用に対する大きな障壁を作り出します。 (間違いなく)最も成功している 自然言語プログラミングWolfram Alpha などの環境でも、効果的に使用するにはかなりのドメイン経験が必要です。

14
Mark Booth

Haskell構文is人間の言語に近い。これは特に、Haskellの基礎となっている概念を正確に表現するために人間が設計した言語(したがって人間の言語)である数学表記に似せるように設計されています。

Haskellのコードを数学者や論理学者に見せれば、彼はHaskellを聞いたことがなく、プログラミング、コンピュータサイエンス、さらにはコンピュータについてまったく何も知らなくても、それを理解することができます。

一方、次のようなコードを数学者や論理学者に示すことができます。

x = x + 1

そして彼は完全に混乱し、「これは意味がありません。xxと等しいx plus 1。 "

特定の表記が「不可解」であるかどうかは、見解と親しみやすさの問題です。

30
Jörg W Mittag

おそらくあなたが遭遇していることの1つは、関数型プログラミングを学ぶときに私も遭遇したことだと思います。つまり、関数型プログラミングを使用すると、命令型プログラミングよりも高いレベルで考えたり作業したりできます(ほとんど必要があります)。

あなたが表現力が低いと感じているものは、実際にはmore表現力があると思います:関数型プログラミングでは、細かいところまで詳しく説明する必要はなく、少ないコードでより多くのことを実行できます。あなたが書いたこと。

たとえば、命令的に書くことができます:

_for each (Person person in people)
    print(person.name)
_

これは英語として完全に読みやすいです。

Haskellのバージョンは次のようになる可能性があります(これは有効なHaskellではありませんが、構文を比較するためのものです)。

_map (print . name) people
_

コードと詳細なラングリングが少なくて済みます。ループとその変数(for each (...))に分解する必要はありません。map関数が処理します私のために。

そのレベルでの作業には、ある程度慣れる必要があります。それが役立つ場合は、プログラミングを始めてからHaskellが私が新しい言語を学ぶのに最も苦労したと思われ、10を超える言語(LISPを含む)を知っています。しかし、それは完全に学ぶ価値がありました。

13
paul

私は現在Scalaでグリップしているので、共感できます。少なくともScalaで、私は命令型にフォールバックできます。行くのは大変すぎる。

ここにはいくつかの力が働いていると思います:

  • 関数型言語の設計者は、必然的に数学の知識が豊富であるため、自然な数学的表記法を取り入れます。

  • どの言語の表現力(英語に近いというよりも、表現の力)が高いほど、学習曲線の急峻さには対応する価格(IMO)があります。簡潔さはScalaで非常に高く評価されている品質であり、多くのオプションはオプションです。

  • 関数型言語はまったく異なる動作をするだけなので、基本的な操作は命令型の構造にマッピングされません。

8
Richard Close

あなたの最後のコメントを正しく理解した場合、あなたの質問は、Haskellが英数字のキーワード(または関数名)を使用できる場所で記号演算子をよく使用する理由ですか?

キーワードについての1つの答えは、キーワードによって特定の単語を変数名として使用できないということです。たとえば、Pythonのように、変数の1つがキーワードである言語で変数fromtoを呼び出したいときは常にイライラします。

記号演算子の一般的なもう1つの理由は、簡潔さです。リスト内包表記の特定の例(_<-_はinよりも短くありません)では実際には当てはまりませんが、多くの場合はそうです。

さらに別の理由は読みやすさです。シンボリック演算子は「名前」は何をするのかを実際には知らないので(関数の名前は通常そうします)、シンボリック演算子はしばしば理解するのが難しいので直観に反するように見えるかもしれませんが、特定の演算子が何をするかを知ったら、インフィックスシンボリック演算子を含む式は、多くの場合、演算子がそのようにオペランドから視覚的に簡単に区別できるため、多くの英数字のプレフィックス関数呼び出しを含む式よりも、人間にとって解析が容易です。たとえば、ほとんどの人は_2 * 3 + 4_がadd (mult 2 3) 4またはadd(mult(2, 3), 4)よりも読みやすいことに同意します。

3
sepp2k

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は人間の言語により似た構文に対応するために構文の単純さを犠牲にしたと思います。スキームのような言語の構文は、人間が書くものとはかけ離れていますが、そのルールを説明するのは非常に簡単です。

3
Andrea

命令型コンピュータ言語は、ほとんどの場合、Haskellほど自然言語に近いわけではありません。

ただし、CobolやHypercardなど、一部は英語に類似するように設計されています。これらの例から得られる教訓は次のとおりです。

  • 自然言語との類似性は、ユーザビリティの直接的な改善をもたらすようには見えません
  • 自然言語を直接エミュレートすると、冗長であいまいなコンピューター言語が生成される可能性があります

Perlコンピュータ言語は 自然言語を念頭に置いて のさらに微妙な側面を考慮して設計されたと伝えられています。一般的なユーザビリティに関しては、PerlがCobolやHypercardよりも優れていると私は判断しますが、Perlについては意見が異なります。

3
comingstorm

違いは、関数型/宣言型プログラミングが問題についてステートメントを作成する方法と関係があると思います。 プロセス。ビジネスの世界では、コンピュータープログラムが物理プロセスをラップまたは置換するため、これを反映する言語がより直感的である場合があります。

関数型のスタイルは、複数のプロセッサを安全に使用するのに適しています(可変性と副作用を最小限に抑えるため)。これは、今後さらに増えるでしょう。また、ほとんどの最新の関数型言語には、関数を渡すことができるイテレーターを含むコレクションがあります。これらの方法では、ワークロードを知らなくても、複数のプロセッサにワークロードを非常に効率的に分割できます。

2
GlenPeterson