将我自己的`in`版本编写为Arc宏

时间:2014-03-04 02:27:59

标签: macros lisp arc-lisp

在Arc中有一个名为in

的宏
> (let x 1
    (in x 4 5 6))
nil
> (let x 1
    (in x 1 5 6))
t

检查其第一个参数是否等于其余参数。我想要一个带有参数和列表的版本(在语义上与Python的in相同),所以我写道:

(assign weak-tens* '(11 12))

(mac in? (elt lst)
  (cons 'in (cons elt lst)))

(def transform-deck (deck)
     (map [if (in? _ weak-tens*) #\T _] deck))

输出:

arc> (load "main.arc")
*** redefining in?
map: contract violation
  expected: list?
  given: '(_ . weak-tens*)
  argument position: 2nd
  other arguments...:
   #<procedure:ac-niltree>

1 个答案:

答案 0 :(得分:1)

要回答您的直接问题,您可以使用mem,如下所示:

arc> (let x 3
    (mem x '(1 2 3 4)))
(3 4)

此外,没有理由认为这应该是一个宏。它没有做任何需要宏的事情。

但是,让我们来看看为什么宏不起作用:

arc> (macex1 '(in? 1 '(1 2 3)))
(in 1 quote (1 2 3))

啊,我们正在重视价值&#34;引用&#34;。

以下是我们希望代码扩展的方式:

(in? 1 '(1 2 3))

应扩展为:

(in 1 1 2 3)

但如上所述,我们甚至不希望这首先成为一个宏。忽略mem,可以写成如下:

(def in? (elt lst)
     (if (no lst)
         nil
       (is elt ;;if we've found the element
           (car lst))
       t
       (in? elt (cdr lst)))) ;;otherwise recurse