2011-01-24 5 views
18

SICPからSchemeの一部を学んだ後、私はLittle Schemer(これはかなり面白いと思います)を読み始め、約4分の1が完了しました。ラムダを使用せずに多くの(ほとんどすべての)ソリューションを書くことができるのに気付きましたが、Little Schemer は常にが使用されています。例えば、非常に最初の定義は、私が間違っていない限り、より簡単にThe Little Schemerのすべてのラムダはなぜですか?

(define (atom? x) 
    (and (not (pair? x)) (not (null? x)))) 

私はラムダレスソリューションを書く場合の基本的な何かが足りないように書くことができ、

(define atom? 
    (lambda (x) 
    (and (not (pair? x)) (not (null? x))))) 

のですか?

+5

ラムダはアルファとオメガです – eljenso

答えて

14

元は、defineは変数を値に設定する単一の構文を持っていました。それはそのような古い(そして時代を超越した)本で使われているスタイルです。その後、defineは、使用しているショートカットとは異なる構文を持っています。

あなたのスキームライブラリで楽しい検索をすると、非ラムダ形式を古いラムダ重い形式に展開するマクロが見つかるかもしれません。

+9

本当に - 新しい "定義"フォームは、1978年の最初の改訂レポート以来、この言語で使用されています。この本の明示的なラムダの使用の選択は、文体的/ 1。 –

+0

そのことは分かっていませんでしたが、初版(当初は "The Little LISPer"と呼ばれていました)をチェックするのは1974年にリリースされました – Javier

+1

ええ、Lispのバージョンは無関係です。 –

4

私はこのようなことについて議論している教授を覚えています。

私は、ラムダ溶液は二つの理由のために使用されていると思う:

最初は純粋に歴史的なものです。ある時点で、それが可能な唯一の方法でした。だから、まだ一部の人々はその方法を使用しています。

もう1つは、関数が作成されているということをより明示的に説明する人がいるように、ラムダという言葉が好きな人もいるということです。

だから私は、これまであなたが個人的に最高のものを選んだことを信じています。

1

リトル・スキーマは、擬似コード・スキームを使用します(教育目的で単純化し、実装に依存しないようにする)。今日の標準スキームには暗黙的にラムダを呼び出すdefineの定義があります(http://www.cs.cmu.edu/Groups/AI/html/r4rs/r4rs_7.html参照)。リトル・スキーマ・スキームは非常に単純で、この代替フォームは含まれていません。

22

私は教授のために重いスタイルを強く好みます。なぜなら、それは関数の作成をより明示的にするからです。

学習するとき、atom?のように始まる簡単な関数は、最上位にdefineです。これは、あなたが言及したdefun-スタイルdefineで関数を作成することが可能であり、よりコンパクトであることを意味します。

しかし、関数をファーストクラスの値として、たとえばmapの引数として使用すると、最初にlambdaが表示され、実際よりも奇妙で魔法に思えるかもしれません。

代わりに、lambdaで関数を定義していたのであれば、関数が他の値と同じように跳躍することは少なくなります。彼らはかなり頻繁にdefineの右側にあることが起こるが、ない数や引用された定数と異なっている:

もちろん
(define x 1) 
(define l '(2 3 4 5)) 
(define s (cons x ls)) 
(define f (lambda (n) (+ n 2))) 

は、言語は両方の形式をサポートしているので、最終的なスタイルに降りてきます。私にとって、ですべての関数が作られたときには、defineの使用に魅力的な一貫性があります。最初の引数は常にシンボルであり、2番目の引数は古い式です。そして、lambdaが古い表現と全く同じであるという事実は、どのような機能プログラマーにとっても最も重要なことの一つです。

+6

+1 It's変数を宣言するのと同じ方法で関数を宣言することを考えると、左に名前を、右に値を入れます。 – erjiang

+0

このアプローチの一貫性を強調していただき、ありがとうございます。他の説明を補足する。 –

+2

「ラムダは古い表現と全く同じであるという事実は、どのような機能プログラマーにとっても最も重要なことの一つです」 - あなたの説明を読むまで、これは私には分かりませんでした。 –

8

あなたは(サポートされている場合)あなたのスキームはexpandを使用してにこれらのショートカット(マクロ)を展開するかを見ることができます。

MzSchemeの4.2.4(DrScheme付き):

> (expand '(define (add1 x) (+ 1 x))) 
#<syntax (define-values (add1) (lambda...> 
(define-values 
    (add1) 
    (lambda (x) (apply + '1 x))) 

シェスキーム8.0:

> (expand '(define (add1 x) (+ 1 x))) 
(begin 
    (set! add1 
    (lambda (x) 
     (+ 1 x))) 
    (void)) 

lambdaは日に日に表示されます。

+3

マクロがSchemeにどれくらい重要であるかを示すために、 'define'もマクロです! – acfoltzer

+0

これは理解を助けるのに非常に便利です、ありがとうございます。 –

2

私はTLSを使ってラムダ計算(「機能プログラミング言語の実装」を読む、サイモン・ペイトン・ジョーンズ、フリーpdfオンライン)について少しお読みになります。そして、これはちょうど推測ですが、私はTLSの著者が実際にあなたの思考の中でラムダ重くなることを望んでいると信じています。彼らは出てこないと言いますが、ヒント(TLSの107ページを参照)があります。これは、適用されたラムダ計算の単なる運動です。だから、彼らは言うまでもなく、「ラムダの抽象化をやっているよ、私の友人!

関連する問題