sorry for my poor english:)
I have a problem with lisp. i type code here http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html to sbcl
* (define a 3)
; in: DEFINE A
; (DEFINE A 3)
;
; caught WARNING:
; undefined variable: A
;
; caught STYLE-WARNING:
; undefined function: DEFINE
;
; compilation unit finished
; Undefined function:
; DEFINE
; Undefined variable:
; A
; caught 1 WARNING condition
; caught 1 STYLE-WARNING condition
debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD
"initial thread" RUNNING
{10029211E1}>:
The variable A is unbound.
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT] Exit debugger, returning to top level.
some one give me a help?
You define a function with DEFUN:
(defun a () 3)
In your case you're trying to call the function DEFINE with an argument A... which is of course undefined.
More generally, you supply the parameters to a function like this:
(defun param-taking-fun (a b)
(+ a b))
Note that Scheme is a 1-lisp (same namespace for functions and variables) while SBCL, like all Common Lisp implementations, is a 2-lisp (different namespaces for functions and variables).
Thus in Scheme (define foo 3) defines a constant while (define foo (lambda () 3)) defines a constant function. In Common Lisp one way to define a constant is
(defconstant foo 3)
Related
I would like to try extending some Lisp (Scheme, Racket, Clojure, any) to run external commands as follows:
; having
(define foo ...)
(define bar ...)
; on command
(ls (foo bar) baz)
; this lisp should evaluate (foo bar) as usual, with result "foobar", then
(ls foobar baz)
; here "ls" is not defined
; instead of rising "undefined identifier" exception
; it must look for "ls" command in the directories
; in the "PATH" environment variable
; and launch the first found "ls" command
; with strings "foobar" and "baz" on input
I just want to run it anyhow, without carrying about correct conversion from lisp's data structures to strings or handling the exit code and the output of the command in stdout/stderr.
I think there is no way to extend it within normal environment (like catching the "undefined" exception all the time). The eval procedure of the interpreter itself must be changed.
Which Lisp is the best to extend it like this and how is it done? Maybe there already exists a project performing something similar?
Common Lisp has a standard error system which may be used to implement that.
In Common Lisp implementations which provide a use-value or store-value restart for errors of type undefined-function.
Example
CL-USER 69 > (flet ((call-use-value-restart (c)
(use-value (lambda (arg)
(format t "~%dummy function with arg ~a~%" arg))
c)))
(handler-bind ((undefined-function #'call-use-value-restart))
(this-function-does-not-exist "foo")))
dummy function with arg foo
NIL
In the above example the function this-function-does-not-exist does not exist. As you can see, the error is handled and another function is called instead, which then does some output.
If we call the undefined function on its own, we get an error:
CL-USER 70 > (this-function-does-not-exist "foo")
Error: Undefined operator THIS-FUNCTION-DOES-NOT-EXIST in form (THIS-FUNCTION-DOES-NOT-EXIST "foo").
1 (continue) Try invoking THIS-FUNCTION-DOES-NOT-EXIST again.
2 Return some values from the form (THIS-FUNCTION-DOES-NOT-EXIST "foo").
3 Try invoking something other than THIS-FUNCTION-DOES-NOT-EXIST with the same arguments.
4 Set the symbol-function of THIS-FUNCTION-DOES-NOT-EXIST to another function.
5 Set the macro-function of THIS-FUNCTION-DOES-NOT-EXIST to another function.
6 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
CL-USER 71 : 1 >
Our example basically calls the restart number 3 programmatically:
It binds a handler which calls the function call-use-value-restart when an error of type undefined-function happens.
The function call-use-value-restart then calls the use-value restart with a function it provides. Here you could provide a function which calls an external program of the name given by (cell-error-name c). The use-value restart then just calls the provided function and keeps on executing the program as usual.
Hint for a solution
Typically one would write a small top-level loop where such a handler is provided.
Another way to call the restart
In this example we use a hook to add a handler in case an error happens. Here we use the global variable *debugger-hook*. This should be a function and in our case it calls a new function when the condition c is of type undefined-function.
* (defun provide-a-function-hook (c hook)
(declare (ignore hook))
(typecase c
(undefined-function (use-value (lambda (arg)
(format t "~%dummy function with arg ~a~%" arg))
c))))
PROVIDE-A-FUNCTION-HOOK
* (setf *debugger-hook* #'provide-a-function-hook)
#<FUNCTION PROVIDE-A-FUNCTION-HOOK>
* (this-function-does-not-exist "foo")
; in: THIS-FUNCTION-DOES-NOT-EXIST "foo"
; (THIS-FUNCTION-DOES-NOT-EXIST "foo")
;
; caught STYLE-WARNING:
; undefined function: THIS-FUNCTION-DOES-NOT-EXIST
;
; compilation unit finished
; Undefined function:
; THIS-FUNCTION-DOES-NOT-EXIST
; caught 1 STYLE-WARNING condition
dummy function with arg foo
NIL
In racket you may override #%top:
#lang racket
(provide
(combine-out
(except-out (all-from-out racket) #%top)
(rename-out [shell-curry #%top])))
(require racket/system)
(define (stringify a)
(~a (if (cmd? a) (cmd-name a) a)))
(struct cmd (name proc)
#:property prop:procedure
(struct-field-index proc)
#:transparent
#:methods gen:custom-write
[(define (write-proc x port mode)
(display (string-append "#<cmd:" (stringify x) ">") port))])
(define (shell name)
(define (cmd-proxy . args)
(define cmd
(string-join (map stringify (cons name args))
" "))
(system cmd))
cmd-proxy)
(define-syntax shell-curry
(syntax-rules ()
((_ . id)
(cmd 'id (shell 'id)))))
Save this as shell.rkt and make this runner.rkt in the same directory:
#lang s-exp "shell.rkt"
(define test (list /bin/ls /usr/bin/file))
(second test) ; ==> #<cmd:/usr/bin/file>
(first test) ; ==> #<cmd:/bin/ls>
((second test) (first test))
; ==> t (prints that /bin/ls is an executable on my system)
Now from here to make it a #lang myshell or something like that is pretty easy.
Coming from a C++ background, I'm trying to figure out how arguments are passed into methods in Elisp. While I acknowledge that maybe the wording could be different, I'm wondering if it is closer to the C++ idea of passing by reference or passing by value? If I alter the parameter in the method itself, will it alter the parameter that was passed in in the function call?
All Lisps (Emacs Lisp, Common Lisp) pass parameters by value, always:
(defparameter x 42) ; defconst in Emacs Lisp
(defun test (x)
(setq x 10))
(test x)
==> 10
x
==> 42
Note, however, that some values are actually pointers (or, rather, objects with components), so a function can modify their content by side effects:
(defparameter x (list 1 2))
(defun test (x)
(setf (first x) 42
(second x) 24
x 17))
(test x)
==> 17
x
==> (42 24)
PS1. Cf. When to use ' (or quote) in Lisp? -- "quoted arguments" are evaluated too: the evaluation strips the quote.
PS2. Cf. add-to-list - it accepts a symbol (variable name) and modifies its value. This only works for global dynamic variables, not for lexical variables. Not a very good idea.
Actually, in Emacs Lisp, there is no such thing like passing a argument by value or by reference, not to mention pointer. But all arguments passed to function will be evaluated in advance except those have a ' prefix. Always remember When you set a variable, you always just create symbol with a value.[1]
So if you want to modify a variable's value in a function, all you need to do is modifying the value of that variable's symbol in that function.
Check my code bellow.
(defvar my-val 1)
(defun my-func-value (val)
(setq val 2))
(defun my-func-symbol (sym)
;; NOTE! using set instead of setq,
;; casue we want symbol "my-val" be evaluated from "sym" here
(set sym 2))
(my-func-value my-val) ; evaluate my-val before passed into function
(message "my-val: %s" my-val) ; my-val: 1
(my-func-symbol 'my-val) ; pass my-val symbol directly into function
(message "my-val: %s" my-val) ; my-val: 2
Note! If the variable is a lexically-bound variable[2], it's still true that you can modified the symbol's value but not the value in the lexical environment.
Here is the code:
(let ((my-lexical-var 1))
(my-func-symbol 'my-lexical-var)
;; evaluate from lexical environment
(message "my-lexical-var: %s" my-lexical-var) ; my-lexical-var: 1
;; evaluate from the symbol
(message "symbol my-lexical-var: %s" (symbol-value 'my-lexical-var))
; symbol my-lexical-var: 2
My question is rather simple (perhaps misleadingly so).
In Common Lisp, when I run the following command, I get the corresponding results:
(eval '''boo) => 'boo
If, on the other hand, I run the following command I get something slightly different.
(eval (eval '''boo)) => boo
My question is this: if the first command's eval "shaves off" two quotation marks from the variable-symbol and leaves it with one mark at the output, how is it possible that the two nested eval functions take off a total of three quotation marks?
This is particularly confusing because the following results in an error:
(eval 'boing) => ERROR. BOING is unbound.
'boo is an abbreviation for (quote boo). In code, quote is a special form that evaluates to whatever it's argument it and nothing more. Thus boo. When this value is passed around it's data and no longer code but in order to create the symbol foo you need quote.
'''boo is an abbreviation for (quote (quote (quote boo))). When evaluating it it does exactly as before and it becomes (quote (quote boo)), a list with two elements where the second element is a list of two elements.
Since eval is a function it first evaluates the argument, then it evaluates the result as the function is supposed to do. Thus (quote (quote foo)) becomes (quote foo) after the first evaluation and eval takes off the second leaving the symbol foo.
If eval gets a symbol foo it means it's supposed to get the value bound by the variable foo in the global namespace. Thus:
(defparameter *test* 5)
(eval '*test*)
; ==> 5
Since the argument is (quote *test*) which after evaluation becomes *test*. eval sees the symbol and fetches the value, 5, which is the result. If *test* is not bound you get the error you got.
(defparameter *test-symbol* '*test)
(eval *test-symbol*)
Same here. Since it's a function *test-symbol* is evaluated to the symbol *test*, this is what eval sees and it fetches the value 5.
(defparameter *result* (eval '''foo))
*result*
; ==> (quote foo) but often the REPL shows 'foo
(consp *result*)
; ==> t
(length *result*)
; ==> 2
(car *result*)
; ==> quote
(cadr *result*)
; ==> foo
Sometimes I see beginners do something like '('(a) '(b)). This is a mistake as when evaluated you end up with the list ((quote (a)) (quote (b))) as the data and it is seldom the intention. When using a function like list the arguments gets evaluated and you need to quote appropriately:
(list '(a) *result* '(b))
; ==> ((a) (quote foo) (b))
eval is a function. Its argument is evaluated before eval is applied to it. That's why it appears that eval "shaves off" two quotation marks. One is removed by the implicit evaluation of function application, the other by the eval application itself.
But when you evoke (eval (eval '''boo)) the outer eval is applied to the value 'boo that is returned from the inner eval. The equivalent is (eval ''boo).
When you try (eval 'boing) the argument is evaluated before eval is applied to it, so eval tries to evaluate boing and goes wrong.
Contrast this with a macro version of eval that doesn't evaluate its argument before applying eval...
? (defmacro meval (form) `(eval ',form))
MEVAL
? (meval 'foo)
FOO
? (meval '''foo)
''FOO
First question:
Evaluating (eval '''boo)
Evaluating '''boo
Result: ''boo
Calling Function EVAL with ''boo
Function EVAL returns 'boo
Result: 'boo
Second question:
Evaluating (eval (eval '''boo))
Evaluating (eval '''boo)
Evaluating '''boo
Result: ''boo
Calling EVAL with ''boo
Function EVAL returns 'boo
Calling Function EVAL with 'boo
Function EVAL returns boo
Result: boo
This function compiles with warnings, fn is defined and never used in the first line, and that fn is an undefined function in the second line:
(defun test-function (fn)
(funcall #'fn))
Why? A general explanation or a link to it would be great.
PD: Complete log:
test.lisp:9:1:
style-warning:
The variable FN is defined but never used.
--> PROGN SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA
==>
#'(SB-INT:NAMED-LAMBDA TEST-FUNCTION
(FN)
(BLOCK TEST-FUNCTION (FUNCALL #'FN)))
test.lisp:10:3:
style-warning:
undefined function: FN
==>
(SB-C::%FUNCALL #'FN)
If you want to call a function passed as parameter, or assigned to a variable, simply use the variable or parameter as first argument to funcall:
(defun test-function(fn)
(funcall fn))
(test-function #'+)
;; => 0
The notation #'X is an abbreviation for (function X), (see the manual), where X must be the name of a function, for instance defined with a defun or labels or flet, or a lambda expression. So, #'fn does not work since fn is not the name of a function, but a variable (in this case, a parameter).
Common-Lisp is a Lisp-2, that is the namespace of functions is different from that of other variables. So the names of the functions are specials in the sense that you can call them directly in a form, while, if a function is assigned to a variable, it must be called with (funcall name-of-the-variable arguments).
This function compiles with warnings
Note that these are only a warnings:
CL-USER> (defun test-function (fn)
(funcall #'fn))
the variable FN is not used.
the function FN is undefined.
Let's look at the function:
(defun test-function (fn) ; this introduces a variable FN
(funcall #'fn)) ; here you use a function FN
Since there is no local function FN in scope, you are using a global function FN. In your case it is not defined.
You can define a global function FN later:
CL-USER> (defun fn ()
'foobar)
FN
This would already work, since Common Lisp usually also uses late binding for undefined functions and would look up the function at runtime.
If we compile your original function again, then you can see that only one warning remains:
CL-USER> (defun test-function (fn) ; the variable FN is defined
(funcall #'fn)) ; the function FN is used
; The variable FN is defined but never used.
This is because we now have a global function FN defined.
But: calling a global function is probably not what you wanted, because that could be written easier as:
(defun test-function (fn)
(fn)) ; calling the function `FN`.
FUNCALL is for calling function objects with arguments:
Typical use cases of FUNCALL are calling function objects with arguments:
(funcall foo 1 2 3)
Where FOO is a variable bound to a function.
In your case this is probably intended:
CL-USER> (defun test-function (fn) ; a variable FN gets introduced
(funcall fn)) ; a variable FN gets used
Remember: (funcall #'foo ...) looks wrong.
If you have something like (funcall #'foo 1 2 3) in your code, then you are probably doing something wrong, since it can be easier written as (foo 1 2 3).
Thus it is a code smell to use (funcall #'foo 1 2 3), indicating that you probably wanted to call a function object, but you actually are calling a function via its name.
I'm writing some code in SBCL, and the ordering of my functions keeps causing warnings of the following type to appear when I load files into the REPL:
;caught STYLE-WARNING:
undefined function: FOO
Where FOO is the symbol for the function. This is purely due to how they are ordered in my file, as the function FOO is defined, just not before the part of the code that throws that warning.
Now, in Clojure, which is the Lisp I'm familiar with, I have the declare form, which lets me make forward declarations to avoid this kind of issue. Is there something similar for SBCL/Common Lisp in general?
We can use the '(declaim (ftype ...))' for that:
(declaim (ftype (function (integer list) t) ith))
(defun foo (xs)
(ith 0 xs))
(defun ith (n xs)
(nth n xs))
Both the function 'foo' and 'ith' works fine and there is not any style warning about that.
http://www.lispworks.com/documentation/HyperSpec/Body/d_ftype.htm
Here's what I found in the manual, section 4.1.1:
CL-USER> (defun foo (x) (bar x))
; in: DEFUN FOO
; (BAR X)
;
; caught STYLE-WARNING:
; undefined function: BAR
;
; compilation unit finished
; Undefined function:
; BAR
; caught 1 STYLE-WARNING condition
FOO
CL-USER> (declaim (sb-ext:muffle-conditions style-warning))
; No value
CL-USER> (defun baz (y) (quux y))
BAZ
So you can at least silence the style warnings.
I also thought about how SBCL is handling the evaluation step in the REPL: it compiles the code. So I restarted the inferior lisp process and ran "compile region" on the following two lines:
(defun foo (x) (bar x))
(defun bar (y) (baz y))
and SBCL only complained about baz, but not about bar. Are you giving single functions to SBCL or larger chunks?