letは最後の式の値を返す
letブロックは最後に書かれた式の結果を戻り値として返します。
1. 基本的な戻り値の例
;; 最後の式 (+ x y) の結果が返される
(let [x 10
y 20]
(println "計算中...") ; これは副作用(画面出力)
(+ x y)) ; これが戻り値になる
;; 出力: 計算中...
;; => 30
;; 最後の式が文字列なので文字列が返される
(let [name "田中"
age 25]
(println "処理開始")
(str name "さんは" age "歳です"))
;; 出力: 処理開始
;; => "田中さんは25歳です"
2. 複数の処理がある場合
(defn process-data [numbers]
(let [sorted-nums (sort numbers)
sum (reduce + sorted-nums)
average (/ sum (count sorted-nums))
max-val (apply max sorted-nums)]
;; 以下の処理は副作用(画面出力)
(println "ソート済み:" sorted-nums)
(println "合計:" sum)
(println "平均:" average)
(println "最大値:" max-val)
;; 最後の式の値が戻り値になる
{:ソート済み sorted-nums
:合計 sum
:平均 average
:最大値 max-val}))
(process-data [5 2 8 1 9])
;; 出力:
;; ソート済み: (1 2 5 8 9)
;; 合計: 25
;; 平均: 5
;; 最大値: 9
;; => {:ソート済み (1 2 5 8 9), :合計 25, :平均 5, :最大値 9}
3. 条件分岐での戻り値
(defn check-age [age]
(let [status (cond
(< age 13) "子供"
(< age 20) "中高生"
(< age 65) "大人"
:else "シニア")
message (str age "歳は" status "です")]
(println "判定中...")
(if (>= age 20)
{:年齢 age :区分 status :成人 true :メッセージ message} ; 大人の場合
{:年齢 age :区分 status :成人 false :メッセージ message}))) ; 未成年の場合
(check-age 25)
;; 出力: 判定中...
;; => {:年齢 25, :区分 "大人", :成人 true, :メッセージ "25歳は大人です"}
(check-age 15)
;; 出力: 判定中...
;; => {:年齢 15, :区分 "中高生", :成人 false, :メッセージ "15歳は中高生です"}
4. letの中でletを使った場合
(defn calculate-tax [price]
(let [base-price price
consumption-tax-rate 0.10]
(println "基本価格:" base-price)
;; 内側のletも最後の式を返す
(let [tax-amount (* base-price consumption-tax-rate)
total-price (+ base-price tax-amount)]
(println "消費税額:" tax-amount)
(println "合計金額:" total-price)
;; 内側のletの戻り値(これが外側のletの最後の式でもある)
{:基本価格 base-price
:税率 consumption-tax-rate
:税額 tax-amount
:合計 total-price})))
(calculate-tax 1000)
;; 出力:
;; 基本価格: 1000
;; 消費税額: 100.0
;; 合計金額: 1100.0
;; => {:基本価格 1000, :税率 0.1, :税額 100.0, :合計 1100.0}
5. 戻り値の視覚的理解
(let [変数1 値1
変数2 値2]
式1 ; 副作用のみ(戻り値は無視される)
式2 ; 副作用のみ(戻り値は無視される)
式3) ; ← この式の結果がletの戻り値になる
↑
この値がletブロック全体の戻り値
まとめ
-
letは最後の式の値を戻り値として返す - 途中の式は副作用(画面出力など)のために実行されるが、戻り値は無視される
-
letの中にletがある場合も、内側のletの最後の式が内側の戻り値になる - 条件分岐(
if、condなど)を使って、状況に応じて異なる値を返すことができる