条件函数

通过定义我们的fun函数,我们已经展示了我们的语言在定义看起来像新语法的函数方面的强大功能。接下来,在我们尝试模拟 C 的switchcase语句时可以找到另一个例子。在C中,这些内置于语言中,但对于我们的语言,我们可以将它们定义为库的一部分。

我们可以定义一个函数select ,它接受零个或多个双元素列表作为输入。对于参数中的每双元素列表,它首先评估该元素对的第一个元素。如果这是真的,那么它会计算并返回第二个元素,否则它会在列表的其余部分再次执行相同的操作。

  1. (fun {select & cs} {
  2. if (== cs nil)
  3. {error "No Selection Found"}
  4. {if (fst (fst cs)) {snd (fst cs)} {unpack select (tail cs)}}
  5. })

我们还可以定义一个始终计算为trueotherwise函数。这有点像 C 中的关键字default

  1. ; Default Case
  2. (def {otherwise} true)
  3. ; Print Day of Month suffix
  4. (fun {month-day-suffix i} {
  5. select
  6. {(== i 0) "st"}
  7. {(== i 1) "nd"}
  8. {(== i 3) "rd"}
  9. {otherwise "th"}
  10. })

这实际上比 C 中的switch语句更强大。在 C 而不是条件传递语句中,输入值仅与条件的常数进行比较。我们也可以在 Lisp 中定义这个函数,我们将一个值与一些候选者进行比较。在这个函数中,我们再取一些值,x后跟零个或多个两元素列表。如果双元素列表中的第一个元素等于x,则评估第二个元素,否则该过程继续沿着列表继续。

  1. (fun {case x & cs} {
  2. if (== cs nil)
  3. {error "No Case Found"}
  4. {if (== x (fst (fst cs))) {snd (fst cs)} {
  5. unpack case (join (list x) (tail cs))}}
  6. })

这个函数的语法将会变得非常简单。试着看看你是否可以考虑使用这些方法实现任何其他控制结构或有用函数。

  1. (fun {day-name x} {
  2. case x
  3. {0 "Monday"}
  4. {1 "Tuesday"}
  5. {2 "Wednesday"}
  6. {3 "Thursday"}
  7. {4 "Friday"}
  8. {5 "Saturday"}
  9. {6 "Sunday"}
  10. })