アプリ版:「スタンプのみでお礼する」機能のリリースについて

lambdaを使えば複数の関数を連続で実行できると思うのですが、以下のとおりにやってもうまくいきません。

(define test
(lambda (num)
(+ num num)
(* num num)))

(test 4)と打ち込んでも、アウトプットは16だけです。(+ num num)の結果が表示されないのですが、どうしてでしょうか?

A 回答 (2件)

>もう一つ質問ですが、lambdaを使った理由はなんでしょう?



それは、mjordan23さんのコーディングスタイルがそうなのかな、って思ったから、です。例示ではlambda使ってますよね?
まあ、僕だったらこう書く方が好きですが。

(define (test num)
(values
(+ num num)
(* num num)))
> (test 4)
8
16
>

>実行してみるとエラーになりましたが、理由がまだよく分かりません。

ああ、MITスタイルの構文糖衣だとそう言う書き方はしません。
次が正解ですね。

(define (test num)
(values
(+ num num)
(* num num)
(/ num num)))
> (test 4)
8
16
1
>

ですね。
どこ違うか分かります?一行目の括弧の「付け方」が違うんですよ。

この辺、まあ、例えばCommon LispとかEmacs Lisp触った事がある、ってのならたまに間違えちゃうんですけどね(笑)。
Common Lispだと確かにmjordan23さんみたいに書きますから。

(defun test (num)
(values
(+ num num)
(* num num)
(/ num num)))
TEST
CL-USER> (test 4)
8
16
1
CL-USER>

Schemeの構文糖衣では

「手続き名と引数を纏めて括弧でくくる」

のが流儀なんで、覚えておいてください。
まあ、これは実際に「手続き実行のスタイルになってる」って事ですね。
    • good
    • 0
この回答へのお礼

分かりました。ありがとうございました。

お礼日時:2009/10/06 09:54

>複数の関数を連続で実行できると思う



ええとですね。

実は内部的にはきちんと(+ num num)ってのは実行されています。

ただSchemeでは、defineによる手続き定義の場合、「全体としての返り値」になるのは「最後の式の評価結果」なんです。これが原則です。
つまり、「実行されてても」返り値になるとは限らないんで、結局、インタプリタ上で表示されるとは限りません。

両方返り値にしたい場合は、多値を返す手続きvaluesを用いて

(define test
(lambda (num)
(values
(+ num num)
(* num num))))

> (test 4)
8
16
>

とする手が一つ。
あるいは、単に「印字させたい」だけで別に返り値にしたいわけじゃない、って場合はdisplayを差し込むのも手です。

(define test
(lambda (num)
(display (+ num num))
(newline) ;改行指定
(* num num)))
> (test 4)
8
16
>

これは前者のコードの実行結果と「見た目似てます」が、前者は本当に多値で8と16を「testの実行結果として返してる」んですが、後者は「testの実行結果はあくまで16」です。単に8は「印字されているだけ」ですね(Scheme用語で言うと「副作用」ってヤツです)。

あとは、簡単に、全部リストにして返しちゃえ、ってのも当然一つの解でしょう。

(define test
(lambda (num)
(list
(+ num num)
(* num num))))
> (test 4)
(8 16)
>

これは返り値を数値とせず、リストにしちゃったパターンですよね。

この回答への補足

valuesのことは知りませんでした。ありがとうございます。

もう一つ質問ですが、lambdaを使った理由はなんでしょう?

(define test (num)
(values
(+ num num)
(* num num)
(/ num num)))

ではいけないんですか?実行してみるとエラーになりましたが、理由がまだよく分かりません。

補足日時:2009/10/06 02:16
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!