【问题标题】:Defining and acessing variables in a local environment在本地环境中定义和访问变量
【发布时间】:2019-06-26 10:41:11
【问题描述】:

在学习 CL 并在不同的小项目中作为业余爱好练习了一段时间后,我的个人 CL 图上仍有一些空白区域。最近,我有很多函数都使用相同的let 构造,我想写一个宏来让代码更简洁:

(defmacro with-context (&body body)
   `(let ((context (make-array 4 :element-type 'fixnum
                                 :initial-contents '(0 1 2 3))))
     ,@body))

以便我以后可以定义如下函数(仅作为一个最小示例):

(defun test-a ()
  (with-context
    (setf (aref context 3)
          (+ (aref context 0) (aref context 1)))
    context))

现在我想知道是否可以使用像 (context n) 这样的宏/函数来缩短 (aref context n) 表达式。

(defun context (n)
  (aref context n))

当然,变量context 在编译时是未知的。我只是不知道我在这里是否有一个基本的误解,或者我如何告诉 lisp 我真正想要什么。所以,我的问题基本上是这是否可能,是否是个好主意。

【问题讨论】:

    标签: scope macros common-lisp


    【解决方案1】:

    本地函数有什么问题?

    (defmacro with-context (&body body)
      `(let ((context (make-array 4 :initial-contents '(0 1 2 3))))
         (flet ((context (n)
                  (aref context n)))
           ,@body)))
    

    设置也是:

    (defmacro with-context (&body body)
      `(let ((context (make-array 4 :initial-contents '(0 1 2 3))))
         (flet ((context (n)
                  (aref context n))
                ((setf context) (new n)
                  (setf (aref context n) new)))
           ,@body)))
    

    【讨论】:

    • 这不是你可以setf的地方,不是吗?
    • @Svante:现在添加
    • 感谢您的澄清。仅出于我的理解:如果有一个使用with-contextmain 函数以及在main 之外定义的其他想要使用context 的函数,我最终会遇到类似于另一个question 中讨论的情况,最近应该考虑另一种策略,我猜。
    • @RainerJoswig 我会尝试 ;-)
    【解决方案2】:

    您可以将macrolet 放入宏扩展中:

    (defmacro with-context (&body body)
      (with-gensyms (i)
        `(let ((context (make-array 4 …)))
           (macrolet ((context (,i)
                        `(aref context ,,i)))
             ,@body))))
    

    一些个人笔记:

    我不喜欢照应宏,所以我通常会让用户定义上下文的名称。不过,使用context 宏会感觉很奇怪。然后我可能会得出结论,我想要的只是一个make-standard-context 函数并继续使用let。我认为这符合“传统”的一般准则。

    【讨论】:

    • 我理解您的观点,并将考虑另一种解决方案。尽管如此,我认为`(aref context ,i)之前缺少,
    猜你喜欢
    • 2023-03-15
    • 2016-05-11
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2021-12-02
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多