17

Lispの初心者である私は、Lisp構文を「修正」できるかどうか疑問に思っていますか?

一部の人々は、Lispの構文がその最大の強みの1つであると言います。私はこれをよく理解していません。

「明白な」括弧を空白、新しい線、インデントの組み合わせに置き換えることはできませんか?Pythonのように?

Lispコードで最もよく使われる文字は括弧のように見えます。それが本当かどうか疑問に思っていますが、本当なら、これは構文に冗長性があるという提案ではありませんか?

質問に対する簡単な答えはありますか?なぜこれほど多くの括弧がありますか?

例えば:

(defun factorial (x)
    (if (= x 0)
        1
        (* x 
           (factorial (- x 1)))))

なぜだめですか:

defun factorial (x)
  if (= x 0)
    1
    * x
      factorial
        - x 1

たとえば、行末の括弧を閉じ、常に新しい行で開きます。1だけがあいまいになります-それは1または(1)です-しかし、例外を導入することができます-単一のトークンは「リスト化」されません。

これはうまくいくでしょうか?

編集:

皆さん、ありがとうございました!lispinサイトにいくつかのリンクがあります。

4

16 に答える 16

31

いくつかのマクロを作成すると、考えが変わるでしょう。

于 2009-03-13T22:10:27.097 に答える
28

これは何度も行われてきました (20 行未満のプリプロセッサは驚異的です)。しかし、それらを明確にすることにも利点があります。コードとデータの並列性を実感させ、ある意味で、それらを煩わしく思うような考え方から抜け出させてくれます。

(類似の例として) オブジェクト指向言語を使用して、クラスへのメソッドのすべての構文グループ化を削除することができます (したがって、それらは実質的にオーバーロードされた関数になりました)。これにより、命令型言語と同じように見ることができますが、何かが失われることもあります。

Lispを見ると、「すべてがリストだ。うーん」と思うはずです。

(まあ、「Ommm」はオプションです)。

于 2009-03-13T18:17:52.633 に答える
20

「おそらく、このプロセスは、Lispハッカーの通過儀礼と見なされるべきです。」

--Steele and Gabriel、「The Evolution of Lisp」、1993年

于 2009-03-14T03:55:12.527 に答える
12

あなたが提案するものはLispinで実装されているようです

編集: sindikatは、リンクが無効になっていることを以下のコメントで指摘しています。Web アーカイブからのサイトの最新の有効なバージョンは次のとおりです: http://wayback.archive.org/web/20080517144846id_/http://www.lispin.org/

于 2009-03-13T18:10:12.183 に答える
9

Lispコードと他の言語の同等のコードを何度か比較しました。Lispコードにはより多くの親がありますが、他の言語ですべてのグループ化文字[] {}()を数えると、Lispにはこれらすべてよりも少ない親があります。これは冗長ではありません。より一貫性があります。

この観点から見た場合、「問題」は、Lispがすべてに対して1つのタイプの構成(リスト)を使用することです。そして、これは、そのマクロ、そのオブジェクトシステム、その最も強力なループ構造のいくつかなどの基礎です。マイナーなスタイルの問題として見られるもの(ブラケットはよりクールに見えるでしょうか?おそらく)は、実際には言語力の兆候です。

そうは言っても、Lispはプログラマーに力を与えることです。必要に応じて、これを可能にする独自の方言を作成します。Lisp(私が言及できるいくつかの言語とは異なり!)はすべてプログラマーの力に関するものなので、それを使用してください。あなたがそれを機能させることができれば、多分それは離陸するでしょう。そうなるとは思いませんが、試してみるのを止めるものは何もありません。どちらの方法でも多くのことを学ぶことができます。

于 2009-03-14T04:02:21.637 に答える
6

Lispの「構文」のポイントは、その存在しないことです。s式は恒等式のツリーであり、ツリー構造は親(およびインデント)で示されます。sexpsは低レベルの表現のみを目的としていたことは注目に値しますが、人々はそれをもっと好きになり、それを使い続けました。

が実行エンジンにとって意味することは、lispで非常に柔軟であり、コンテキストにも依存します。

他の言語では、文脈依存のレベルははるかに低く、独自の抽象化を構築するために使用できるビルディングブロックのセットははるかに自由に拡張できません。したがって、いくつかの与えられた構成を示す特別な構文は、全体像に適合しています。

lispでは、文脈に敏感な方法でさえ、すべての意味を変えることができます。いくつかの事前定義された構造に特別な構文を使用するのはばかげています。なぜなら、私は自分の'if'や自分の特殊なクロージャーなどを使用する可能性があるからです。新しい'if'に4つの引数が必要な場合(たとえば、プログラムして、特定の状況で常に失敗または成功するようにいくつかのグループに指示します)?事前定義された'if'の構文をどのように拡張する必要がありますか?AST(sexps)に頼る方がはるかに簡単ですが、なぜ特別な構文に煩わされるのでしょうか。

また、emacsのようなエディターを使用すると、そのようなツリーを構造化された方法で非常に簡単に編集できることにも注意してください。たとえば、ツリー内の2つのノードを転置するキーを持つことは、変数宣言を交換したり、プログラムブロック内の2つのステートメントを交換したりする場合にも同様に役立ちます(ヒント:「余分な」親はlet、condなどで役立ちます)。

だから、それが、lispの非構文が、事前定義されたツールのセットに合うように問題を曲げるのではなく、言語を拡張するという考えに慣れた多くの人々にとって非常に魅力的である理由です...しかし、それはそれを意味するものではありません構文シュガーは、ユーザー指定の構成には使用されません。

使用するユーザー定義構文の例:

  • cl-syntax- sugar-最も注目すべき拡張機能は、[]クロージャの変数に名前を付けたくない小さなクロージャに使用される親です。
  • cl-quasi-quote-特に<xml >lispコードでxhtml生成をインライン化する構文(この構文はユーザーライブラリによって提供され、コンテキスト依存の方法で有効にできることに注意してください)
于 2009-03-14T20:06:39.097 に答える
5

Lisp ファミリー言語の熱心な支持者であるPaul Grahamでさえ、彼自身の方言Arcからいくつかの括弧を削除しました:

Lisp ハッカーへの注意: 従来の Lisp 演算子に慣れている cond場合、これは同じことになりますが、括弧が少なくなります。例えば

(cond (a b)
      (c d)
      (t e))

になる

(if a b
    c d
    e)

(アークチュートリアルより)

于 2009-03-13T22:19:44.830 に答える
5

それはうまくいくかもしれません。ディランといいます。

于 2009-03-13T18:10:28.500 に答える
3

人間には 2 種類の人間がいます™: 脳に組み込まれたスタック マシンによって情報を処理する人と、それを大きな塊またはブロックで消費する人です。これらのグループは相互に互換性がありません。彼らはさまざまな本を読み、さまざまな文体を持ち、最も重要なこととして、さまざまなプログラミング言語でコードを記述します。私は 2 番目のグループに属しています。しかし、私は最初のグループの多くの仲間のプログラマーを知っています。

最初のグループの人々にとって、ネストされた句と副次句にはまったく問題はありません。彼らは自然に再帰を把握します。彼らはコードをステートメントごと、行ごとにゆっくりと見て、潜在意識のレベルで脳内のマシンをスタックし、ブレースと括弧を数え続けます。Lisp 構文は、彼らにとって非常に自然なものです。地獄、彼らはおそらくスタック マシンと Forth 言語を発明しました。しかし、たとえば Python を見せれば (ああ、ダメだ!)、どうしようもなくコードのシートを一瞥し、これらのばかげたコード ブロックがopenのままであり、一致する終了ステートメントがない理由を理解できません。

2 番目のグループのかわいそうな私たちには、コード ステートメントをブロックにグループ化し、それらを視覚的にインデントする以外に選択肢はありません。私たちはコードで満たされた画面を見て、最初に大規模な構造に注目し、次に個別の関数またはメソッド、次にこれらのメソッド内のステートメント グループ、次に行とステートメントを上から下に見ていきます。直線的に考えることはできません。視覚的な境界と明確なインデント ポリシーが必要です。したがって、私たちは Lisp を扱うことに屈することはできません。私たちにとって、それはキーワードとばかげた括弧の不規則なごちゃごちゃです。

ほとんどのプログラミング言語は、両方の考え方と互換性があります (これらの「ブロック」は理由があります)。注目すべき例外は、最初のグループのみである Lisp と Forth、および 2 番目のグループのみである Python です。あなたが2番目のグループに属しているなら、Lispをあなたの考え方に適応させる必要はないと思います。それでも関数型言語が必要な場合は、Haskell を試してください。これは、スタックではなくブロックで考える人向けに設計された関数型言語です。

于 2009-03-13T18:34:18.333 に答える
1

これに関する私の個人的な意見は次のとおりです。改行とインデントを「暗黙の」区切り記号として使用しないでください (演算子の優先順位による暗黙のグループ化も好きではありませんが、関連するトピックではありますが、それは別です)。

例: これは有効な Python ですか? それはあなたが期待することをしますか?

if foo < 0 :
    bar
  else :
    baz
quuz

ちょっとした提案があります。プリプロセッサを使用して Python コードを自動的にインデントすることができます。それには、ステートメントの開始位置と終了位置を示す特殊文字をコードに挿入します。これの括弧はどうですか?

于 2009-03-16T01:34:29.190 に答える
1

理由の質問に答えるには:

私の知る限り、主な用途は可読性であり、コードを見る人がより簡単に解読できるようにします。

それが役に立てば幸い。

于 2009-03-13T18:15:21.843 に答える
1

リンクを読んで、これを見つけました-インデントに敏感な構文-この構文を実装するGuileモジュールもあるので、直接試すことができます。

非常に有望なLisp 方言 (Arc) がここにあります。(最初に実際のコードでどのように感じるかを確認する必要があると思います)

于 2009-03-14T00:57:44.467 に答える
1

Clojure を見てみましょう。かっこは少なくなりますが、より多くの構文を覚えることができます。

于 2009-03-21T18:11:10.673 に答える
1

このスレッドは古いですが、非常によく似たリーダー システムを作成したので、投稿することにしました。

編集:使用例:

!defun ファクト (n)
  もし (zerop n)
    1
    * n
      事実
        (1-n)
!defun 事実 !n
  if !zerop n
    1
    !* n !事実 !1- n

詳細については、プロジェクトのホームページを確認してください。

于 2012-10-05T11:25:59.853 に答える
1

インデントに依存するいくつかの構文を試して書きました。最良の結果では、構文全体がその性質を変更したため、言語は次から次へと変化しました。適切なインデント ベースの構文は、もはや Lisp にはほど遠いものです。

インデントに構文上の意味を与えるという問題は、ばかや \t 対空白の議論から生じるものではありません。改行とスペースの読み取りは他の何よりも難しくないはずなので、トークン化は問題ではありません。最も難しいのは、インデントが表示される場所で何を意味するかを決定することと、言語の複雑な構文を作成せずに意味を追加する方法を決定することです。

巧妙なプログラミングで括弧の量を最小限に抑えると、元の Lisp スタイルの構文の方が結局は優れていると考え始めています。これは、現在の Lisp 実装ではそう簡単に実行できませんが、将来の Lisp 実装ではより簡単に実行できるようになります。トークン化する必要があるルールが 2、3 しかなく、解析がほとんどない場合は、高速かつ簡単に解析できます。

于 2009-10-23T18:14:18.473 に答える