Type error when running a common lisp macro that tries to output Javascript code. Why?
up vote
0
down vote
favorite
I just started learning common lisp and I'm trying to exercise it in a way that makes my daily work easier. In particular, I'm trying to create a set of functions and macros that takes a minimal syntax and outputs some JavaScript that I'm using often.
This is the code that I have written:
;;;; 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))
The idea is to be able to write code like this:
(namespace "namespace"
(#'public-var "hello" "world")
(#'public-var "something" "else"))
and get this output:
(function(ns){
ns.hello = world;
ns.something = else;
}(window.namespace = window.namespace || {}));
I know that I still need to work on the indentation of the output and on the line breaks, but that's not the point yet (these should be the first building blocks to abstract away more complex logics). The problem is that I'm getting this error and I can't figure out why (seriously, I already spent hours researching and trying different things):
Illegal function object:
(CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))).
[Condition of type TYPE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort entirely from this (lisp) process.
Backtrace:
0: (IDE.BASE::IDE-INVOKE-DEBUGGER-FROM-NON-CG-PROCESS "Error" #<TYPE-ERROR @ #x22de54b2> T NIL NIL)
1: (ERROR TYPE-ERROR :DATUM (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))) :EXPECTED-TYPE (OR SYMBOL FUNCTION) ...)
2: ((CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
3: (LET ((*NAMESPACE* "ns")) ((CONC OUTPUT (APPLY #'PUBLIC-VAR #))))
4: (LET ((*NAMESPACE* (CONCATENATE 'STRING "window." "webtrekk_dl")) (OUTPUT "")) ..)
5: (EVAL (NAMESPACE "webtrekk_dl" (#'PUBLIC-VAR "ciao" "mondo")))
--more--
I also tried the individual pieces. For example this:
(let ((output "")) (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
works and gets me this output:
".ciao = mondo;"
Any idea what I'm doing wrong?
common-lisp
add a comment |
up vote
0
down vote
favorite
I just started learning common lisp and I'm trying to exercise it in a way that makes my daily work easier. In particular, I'm trying to create a set of functions and macros that takes a minimal syntax and outputs some JavaScript that I'm using often.
This is the code that I have written:
;;;; 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))
The idea is to be able to write code like this:
(namespace "namespace"
(#'public-var "hello" "world")
(#'public-var "something" "else"))
and get this output:
(function(ns){
ns.hello = world;
ns.something = else;
}(window.namespace = window.namespace || {}));
I know that I still need to work on the indentation of the output and on the line breaks, but that's not the point yet (these should be the first building blocks to abstract away more complex logics). The problem is that I'm getting this error and I can't figure out why (seriously, I already spent hours researching and trying different things):
Illegal function object:
(CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))).
[Condition of type TYPE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort entirely from this (lisp) process.
Backtrace:
0: (IDE.BASE::IDE-INVOKE-DEBUGGER-FROM-NON-CG-PROCESS "Error" #<TYPE-ERROR @ #x22de54b2> T NIL NIL)
1: (ERROR TYPE-ERROR :DATUM (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))) :EXPECTED-TYPE (OR SYMBOL FUNCTION) ...)
2: ((CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
3: (LET ((*NAMESPACE* "ns")) ((CONC OUTPUT (APPLY #'PUBLIC-VAR #))))
4: (LET ((*NAMESPACE* (CONCATENATE 'STRING "window." "webtrekk_dl")) (OUTPUT "")) ..)
5: (EVAL (NAMESPACE "webtrekk_dl" (#'PUBLIC-VAR "ciao" "mondo")))
--more--
I also tried the individual pieces. For example this:
(let ((output "")) (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
works and gets me this output:
".ciao = mondo;"
Any idea what I'm doing wrong?
common-lisp
1
Usemacroexpand-1
andpprint
to look at the macroexpansion of your(namespace ...)
example. Then you can see the error easily.
– Rainer Joswig
Nov 5 at 20:28
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I just started learning common lisp and I'm trying to exercise it in a way that makes my daily work easier. In particular, I'm trying to create a set of functions and macros that takes a minimal syntax and outputs some JavaScript that I'm using often.
This is the code that I have written:
;;;; 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))
The idea is to be able to write code like this:
(namespace "namespace"
(#'public-var "hello" "world")
(#'public-var "something" "else"))
and get this output:
(function(ns){
ns.hello = world;
ns.something = else;
}(window.namespace = window.namespace || {}));
I know that I still need to work on the indentation of the output and on the line breaks, but that's not the point yet (these should be the first building blocks to abstract away more complex logics). The problem is that I'm getting this error and I can't figure out why (seriously, I already spent hours researching and trying different things):
Illegal function object:
(CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))).
[Condition of type TYPE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort entirely from this (lisp) process.
Backtrace:
0: (IDE.BASE::IDE-INVOKE-DEBUGGER-FROM-NON-CG-PROCESS "Error" #<TYPE-ERROR @ #x22de54b2> T NIL NIL)
1: (ERROR TYPE-ERROR :DATUM (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))) :EXPECTED-TYPE (OR SYMBOL FUNCTION) ...)
2: ((CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
3: (LET ((*NAMESPACE* "ns")) ((CONC OUTPUT (APPLY #'PUBLIC-VAR #))))
4: (LET ((*NAMESPACE* (CONCATENATE 'STRING "window." "webtrekk_dl")) (OUTPUT "")) ..)
5: (EVAL (NAMESPACE "webtrekk_dl" (#'PUBLIC-VAR "ciao" "mondo")))
--more--
I also tried the individual pieces. For example this:
(let ((output "")) (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
works and gets me this output:
".ciao = mondo;"
Any idea what I'm doing wrong?
common-lisp
I just started learning common lisp and I'm trying to exercise it in a way that makes my daily work easier. In particular, I'm trying to create a set of functions and macros that takes a minimal syntax and outputs some JavaScript that I'm using often.
This is the code that I have written:
;;;; 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))
The idea is to be able to write code like this:
(namespace "namespace"
(#'public-var "hello" "world")
(#'public-var "something" "else"))
and get this output:
(function(ns){
ns.hello = world;
ns.something = else;
}(window.namespace = window.namespace || {}));
I know that I still need to work on the indentation of the output and on the line breaks, but that's not the point yet (these should be the first building blocks to abstract away more complex logics). The problem is that I'm getting this error and I can't figure out why (seriously, I already spent hours researching and trying different things):
Illegal function object:
(CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))).
[Condition of type TYPE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] Abort entirely from this (lisp) process.
Backtrace:
0: (IDE.BASE::IDE-INVOKE-DEBUGGER-FROM-NON-CG-PROCESS "Error" #<TYPE-ERROR @ #x22de54b2> T NIL NIL)
1: (ERROR TYPE-ERROR :DATUM (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))) :EXPECTED-TYPE (OR SYMBOL FUNCTION) ...)
2: ((CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
3: (LET ((*NAMESPACE* "ns")) ((CONC OUTPUT (APPLY #'PUBLIC-VAR #))))
4: (LET ((*NAMESPACE* (CONCATENATE 'STRING "window." "webtrekk_dl")) (OUTPUT "")) ..)
5: (EVAL (NAMESPACE "webtrekk_dl" (#'PUBLIC-VAR "ciao" "mondo")))
--more--
I also tried the individual pieces. For example this:
(let ((output "")) (CONC OUTPUT (APPLY #'PUBLIC-VAR (LIST "ciao" "mondo"))))
works and gets me this output:
".ciao = mondo;"
Any idea what I'm doing wrong?
common-lisp
common-lisp
edited Nov 6 at 8:16
asked Nov 5 at 18:04
roccobarbi
748
748
1
Usemacroexpand-1
andpprint
to look at the macroexpansion of your(namespace ...)
example. Then you can see the error easily.
– Rainer Joswig
Nov 5 at 20:28
add a comment |
1
Usemacroexpand-1
andpprint
to look at the macroexpansion of your(namespace ...)
example. Then you can see the error easily.
– Rainer Joswig
Nov 5 at 20:28
1
1
Use
macroexpand-1
and pprint
to look at the macroexpansion of your (namespace ...)
example. Then you can see the error easily.– Rainer Joswig
Nov 5 at 20:28
Use
macroexpand-1
and pprint
to look at the macroexpansion of your (namespace ...)
example. Then you can see the error easily.– Rainer Joswig
Nov 5 at 20:28
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
,(loop for e in contents collect `(conc output …))
This returns a list:
((conc output …)
(conc output …)
…)
A list is evaluated by applying the operator, which is the first element of the list, to the arguments.
Valid operators are only symbols or lambda forms. A conc
form is invalid as an operator. Most likely you wanted something like:
(progn
(conc output …)
…)
As a side note, I don't know what your JavaScript output is really supposed to do. It ignores the ns
parameter and sets two new global vars. This does not seem useful.
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
,(loop for e in contents collect `(conc output …))
This returns a list:
((conc output …)
(conc output …)
…)
A list is evaluated by applying the operator, which is the first element of the list, to the arguments.
Valid operators are only symbols or lambda forms. A conc
form is invalid as an operator. Most likely you wanted something like:
(progn
(conc output …)
…)
As a side note, I don't know what your JavaScript output is really supposed to do. It ignores the ns
parameter and sets two new global vars. This does not seem useful.
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
add a comment |
up vote
2
down vote
accepted
,(loop for e in contents collect `(conc output …))
This returns a list:
((conc output …)
(conc output …)
…)
A list is evaluated by applying the operator, which is the first element of the list, to the arguments.
Valid operators are only symbols or lambda forms. A conc
form is invalid as an operator. Most likely you wanted something like:
(progn
(conc output …)
…)
As a side note, I don't know what your JavaScript output is really supposed to do. It ignores the ns
parameter and sets two new global vars. This does not seem useful.
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
,(loop for e in contents collect `(conc output …))
This returns a list:
((conc output …)
(conc output …)
…)
A list is evaluated by applying the operator, which is the first element of the list, to the arguments.
Valid operators are only symbols or lambda forms. A conc
form is invalid as an operator. Most likely you wanted something like:
(progn
(conc output …)
…)
As a side note, I don't know what your JavaScript output is really supposed to do. It ignores the ns
parameter and sets two new global vars. This does not seem useful.
,(loop for e in contents collect `(conc output …))
This returns a list:
((conc output …)
(conc output …)
…)
A list is evaluated by applying the operator, which is the first element of the list, to the arguments.
Valid operators are only symbols or lambda forms. A conc
form is invalid as an operator. Most likely you wanted something like:
(progn
(conc output …)
…)
As a side note, I don't know what your JavaScript output is really supposed to do. It ignores the ns
parameter and sets two new global vars. This does not seem useful.
answered Nov 6 at 0:06
Svante
38.8k662109
38.8k662109
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
add a comment |
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
Thanks a lot for explaining it. In fact, as a newbie, I would have had a hard time noticing it. About the Javascript, I'll correct it as soon as I'm in front of a computer for future reference. I forgot to add ns. before each variable in the example output.
– roccobarbi
Nov 6 at 5:55
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53159826%2ftype-error-when-running-a-common-lisp-macro-that-tries-to-output-javascript-code%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Use
macroexpand-1
andpprint
to look at the macroexpansion of your(namespace ...)
example. Then you can see the error easily.– Rainer Joswig
Nov 5 at 20:28