Common lisp 运行试图输出Javascript代码的公共lisp宏时键入错误。为什么?

Common lisp 运行试图输出Javascript代码的公共lisp宏时键入错误。为什么?,common-lisp,Common Lisp,我刚开始学习CommonLisp,我正在尝试以一种让我的日常工作更轻松的方式来练习它。特别是,我正在尝试创建一组函数和宏,这些函数和宏采用最少的语法,并输出一些我经常使用的JavaScript 这是我写的代码: ;;;; This program is aimed at creating a very high level language that writes ;;;; complex and formally correct Javascript with minimal code. (

我刚开始学习CommonLisp,我正在尝试以一种让我的日常工作更轻松的方式来练习它。特别是,我正在尝试创建一组函数和宏,这些函数和宏采用最少的语法,并输出一些我经常使用的JavaScript

这是我写的代码:

;;;; This program is aimed at creating a very high level language that writes
;;;; complex and formally correct Javascript with minimal code.

(defvar *namespace* nil)

(defmacro conc (var &body body)
  `(setf ,var (concatenate 'string output ,@body)))

(defun public-var (name value)
  (let ((output ""))
    (conc output *namespace* "." name " = " value ";")
    output))

(defmacro namespace (ns &rest contents)
  `(let ((*namespace* (concatenate 'string "window." ,ns)) (output ""))
     (conc output "(function(ns){")
     (let ((*namespace* "ns"))
       ,(loop for e in contents collect `(conc output (apply ,(first e) (list ,@(rest e))))))
     (conc output "}(" *namespace* " = " *namespace* " || {}));")
     output))
我们的想法是能够编写如下代码:

(namespace "namespace"
  (#'public-var "hello" "world")
  (#'public-var "something" "else"))
并获得以下输出:

(function(ns){
  ns.hello = world;
  ns.something = else;
}(window.namespace = window.namespace || {}));
".ciao = mondo;"
我知道我仍然需要处理输出的缩进和换行符,但这还不是重点(这些应该是抽象出更复杂逻辑的第一个构建块)。问题是我犯了这个错误,我不知道为什么(说真的,我已经花了好几个小时研究和尝试不同的东西):

工作并获得以下输出:

(function(ns){
  ns.hello = world;
  ns.something = else;
}(window.namespace = window.namespace || {}));
".ciao = mondo;"
知道我做错了什么吗

,(loop for e in contents collect `(conc output …))
这将返回一个列表:

((conc output …)
 (conc output …)
 …)
通过将运算符(列表的第一个元素)应用于参数来计算列表

有效运算符仅为符号或lambda形式。
conc
表单作为运算符无效。很可能您想要的是:

(progn
  (conc output …)
  …)
顺便说一句,我不知道JavaScript输出到底应该做什么。它忽略
ns
参数并设置两个新的全局变量。这似乎没有用

这将返回一个列表:

((conc output …)
 (conc output …)
 …)
通过将运算符(列表的第一个元素)应用于参数来计算列表

有效运算符仅为符号或lambda形式。
conc
表单作为运算符无效。很可能您想要的是:

(progn
  (conc output …)
  …)

顺便说一句,我不知道JavaScript输出到底应该做什么。它忽略
ns
参数并设置两个新的全局变量。这似乎没有用。

使用
macroexpand-1
pprint
查看
(名称空间…
示例)的宏扩展。然后您可以很容易地看到错误。使用
macroexpand-1
pprint
查看
(名称空间…
示例的宏扩展。这样您就可以很容易地看到错误。非常感谢您的解释。事实上,作为一个新手,我很难注意到这一点。关于Javascript,我一到计算机前就会纠正它,以备将来参考。我忘了加N。在示例输出中的每个变量之前。非常感谢您的解释。事实上,作为一个新手,我很难注意到这一点。关于Javascript,我一到计算机前就会纠正它,以备将来参考。我忘了加N。在示例输出中的每个变量之前。