This question already has an answer here:
Lisp SYMBOL-PACKAGE-LOCKED-ERROR
(1 answer)
Closed 7 years ago.
I am learning the Lisp programming language. I have written a simple program:
(defun abs(x)
(cond ((> x 0) x)
((= x 0) 0)
((< x 0) (- x))))
(print (abs 5))
when I compile and run this code, i get the following warning:
WARNING: DEFUN/DEFMACRO(ABS): #<PACKAGE COMMON-LISP> is locked
Ignore the lock and proceed
WARNING: DEFUN/DEFMACRO: redefining function ABS in /home/lisp/file.lisp, was defined in C
I didn't understand why is this warning given, what does it mean?
can anybody explain it?
You are trying to redefine an ANSI Common Lisp function
abs
and the system is warning you about it.
Please see "package locking"
in the manual.
(You now owe me 1 zorkmid).
Related
This question already has answers here:
What is the difference between Lisp-1 and Lisp-2?
(2 answers)
Closed 3 years ago.
While studying elisp I tried something which I know works in Scheme and discovered to my surprise that I couldn't replicate it in Elisp.
;; works in Scheme. result: 5
((if 1 + -) 3 2)
;; doesn't work in Elisp. result: error
((if 1 '+ '-) 3 2)
I would expect that the Elisp line evaluates to
(+ 3 2)
and that the evaluation of this list result in 5. However I get:
(invalid-function (if t '+ '-))
What am I missing here? Does Elisp not allow for such actions? Is this possibly related to the fact that Scheme is a lisp-1 language and Elisp a lisp-2?
Yes, the error is due to the fact that Emacs Lisp is a Lisp-2. This should work:
(funcall (if 1 '+ '-) 3 2)
I'm a noob in scheme ... I am trying to make an exercise so that it will check if a number is a palindrome or not ( I know how to do it in c, c++ and java). But I keep getting this error "c: unbound identifier in module in: c". I searched wide and far for the error, and yes there are tens of topics on it, but all on complicated stuff that have nothing to do with my punny code. My question is, can somebody please explain to me what does the error actually mean and how can I avoid it ? My code so far :
#lang racket
(define (palindrome n)
(if (> 10 n) #t
(check n)
)
)
(define (check n)
(if (> n 0)
((= c (modulo n 10))
(= x (+ (* x 10) c))
(= n (/ n 10)))
(checkp )
)
)
(define (checkp k)
(if (= k n) #t
#f)
)
The error reported occurs in the check procedure. All those references to the variables called c and x will fail, what are those variables supposed to be? where do they come from? Remember: in Scheme = is used for comparing two numbers, not for assignment.
There are other problems. The last line of check is calling checkp, but you forgot to pass the parameter. Also the syntax in the if expression is wrong, you can't write more than two conditions in it (the "consequent" and the "alternative"), if you need more than two conditions you should use cond.
Please be careful with those parentheses, you must not use them to group expressions (they're not like curly braces!). In Scheme, if you surround an expression with () it means function application, and that's not what you want to do in check.
And in the checkp procedure we have the same problem: the variable n is unbound. It's just like in any other programming language: you have to make sure that the variables come from somewhere (a parameter, a local variable, a global definition, etc.), they can't simply appear out of thin air.
UPDATE
After the update, now it's clear what you wanted to do. I'm sorry to say this, but you don't have a good grasp of even the most basic concepts of the language. All along you needed to do an iteration (typically implemented via recursion), but this is reflected nowhere in your code - you'll have to grab a good book or tutorial on Sceheme, to get the basics right. This is how the code in Java or C would look like in Scheme:
(define (check k)
(let loop ((x 0) (n k))
(if (zero? n)
(= k x)
(loop (+ (* 10 x) (remainder n 10)) (quotient n 10)))))
(define (palindrome)
(display "Enter the number: ")
(if (check (read))
(display "The number is a palindrome")
(display "The number is not a palindrome")))
Use it like this:
(palindrome)
Enter the number: 12321
The number is a palindrome
When I had asked how to Get numbers for the lottery I was given the hint to create a function that shuffles a list. So I tried to do so, and I even got it working.
My current implementation looks like this:
(defun shuffle (list)
(let ((len (length list)))
(loop repeat len
do
(rotatef
(nth (random len) list)
(nth (random len) list))
finally
return list)))
Good news is that it works:
(shuffle '(1 2 3 4 5 6))
;; => (3 1 4 2 6 5)
Bad news is that I get an error message:
WARNING: LOOP: loop keyword immediately after FINALLY: permitted by CLtL2, forbidden by ANSI CL.
Unfortunately I don't understand it. Why does it tell me that loop immediately appears after finally? And, what's wrong with the code that actually causes this?
Is there a better way to formulate this?
WARNING: LOOP: loop keyword immediately after FINALLY: permitted by CLtL2, forbidden by ANSI CL.
This means that RETURN is a loop keyword, which is not allowed after finally, according to the ANSI CL standard.
If we want to return from the LOOP, we need to use the return macro:
(loop ...
finally (return list))
It's actually a common mistake. finally return <expr> is no longer allowed since the ANSI CL standard. That's also a reason not to use CLtL2 (Common Lisp the Language, 2nd Edition) as a reference. The CL Hyperspec is the better reference.
I'm watching these tutorials on Lisp and I've been following along so far. However, when I try to evaluate this function,
(defun tailfact (n &optional (intermediate 1))
(if (= n 1)
(return-from tailfact intermediate))
(tailfact (1 - n) (* n intermediate)))
(tailfact 5)
I get an Invalid function warning (I'm running this in Emacs). Not sure what to make of it, or how to fix it.
You accidentally wrote a space within the 1- (which is a function for subtracting 1 from the given number). Remove that space (that is, use (1- n) instead of (1 - n)) and try again.
Also, Emacs Lisp doesn't have return-from. Just say intermediate instead of (return-from tailfact intermediate). You do have to move the tailfact call within the if expression though, as the else clause.
Oh, in my testing, I found another point of difference between Common Lisp and Emacs Lisp: the latter doesn't support a default value for optional arguments, and it always uses nil. So here's one way to port your code to elisp:
(defun tailfact (n &optional intermediate)
(let ((intermediate (or intermediate 1)))
(if (= n 1)
intermediate
(tailfact (1- n) (* n intermediate)))))
However, let me be the first to agree with Rainer's comment. If you're learning from Common Lisp resources, you really should be using a Common Lisp implementation. I've heard that SLIME is an awesome Emacs mode for integrating with major CL implementations, including SBCL (which is probably one of the most commonly-used CL implementations).
This question already has answers here:
Why use #' with lambda?
(2 answers)
Closed 9 years ago.
Why do some use #'(lambda instead of just (lambda in Common Lisp? Are there performance benefits or something?
Because, as Peter Siebel and others explain, in CL, "the following LAMBDA expression: (lambda () 42) expands into the following when it occurs in a context where it evaluated: (function (lambda () 42))".
There is not performance benefits except few milliseconds of compile time vs few millisecods of read time :)
I think real reason is consistency. If one writes (mapcar #'myfunc ...) (not just (mapcar myfunc ...)), it is natural to write (mapcar #'(lambda ...) ...) too.