As a project I am required to make a roman numeral converter in lisp using recursion. While working on the roman numeral to English portion I am running into a problem where the compiler is telling me that that one of my variables is is an undefined function. I am very new to lisp and could use any tips or tricks possible for this program. I would like to know the changes I would have to make to stop getting that error and if anyone has tips for my recursion that would be appreciated.
I know my code is messy but I plan on learning all the proper ways to format when I have something that works. The function is supposed to take a list of roman numerals and then convert the first and second element of the list into the corresponding integers and add them. It recursively is called until it hits NIL when it will return a 0 and add all the remaining integers and display that as an atom. Hopefully that makes sense. Thank you in advance.
(defun toNatural (numerals)
"take a list of roman numerals and process them into a natural number"
(cond ((eql numerals NIL) 0)
((< (romans (first (numerals)))
(romans (second (numerals))))
(+ (- (romans (first (numerals))))
(toNatural (cdr (numerals)))))
(t
(+ (romans (first (numerals)))
(toNatural (cdr (numerals)))))))
(defun romans (numer)
"take a numeral and translate it to its integer value and return it"
(cond((eql numer '(M)) 1000)
((eql numer '(D)) 500)
((eql numer '(C)) 100)
((eql numer '(L)) 50)
((eql numer '(X)) 10)
((eql numer '(V)) 5)
((eql numer '(I)) 1)
(t 0)))
here is the error. I use emacs and clisp for this project.
The following functions were used but not defined:
NUMERALS
0 errors, 0 warnings
In Common Lisp, the form (blah) means "call the function blah" and the form (blah foobar) means "call the function foo, with the argument foobar". Thus, you are telling the compiler to call the function numerals in multiple places, when you actually want to just use the value of the variable.
Also, unless you have a lisp environment that uses "modern mode", the symbol denoted by "toNatural" is the same as the one denoted by "tonatural" or "TONATURAL", don't use case to distinguish word breaks, use "-" (so (defun to-natural ...).
Related
I am trying to do Recursive method to find max value in list.
Can anyone explain where I made the mistake on this code and how to approach it next time.
(defun f3 (i)
(setq x (cond (> (car (I)) (cdr (car (I))))
(f3 (cdr (I)))))
)
(f3 '(33 11 44 2) )
also I tried this following method and didn't work:
(defun f3 (i)
(cond ((null I )nil )
(setq x (car (i))
(f3(cdr (i)))
(return-from max x)
)
Thanks a lot for any help. I am coming from java if that helps.
If you're working in Common Lisp, then you do this:
(defun max-item (list)
(loop for item in list
maximizing item))
That's it. The maximizing item clause of loop determines the highest item value seen, and implicitly establishes that as the result value of loop when it terminates.
Note that if list is empty, then this returns nil. If you want some other behavior, you have to work that in:
(if list
(loop for item in list
maximizing item))
(... handle empty here ...))
If the number of elements in the list is known to be small, below your Lisp implementation's limit on the number of arguments that can be passed to a function, you can simply apply the list to the max function:
(defun max-item (list)
(apply #'max list))
If list is empty, then max is misused: it requires one or more arguments. An error condition will likely be signaled. If that doesn't work in your situation, you need to add code to supply the desired behavior.
If the list is expected to be large, so that this approach is to be avoided, you can use reduce, treating max as a binary function:
(defun max-item (list)
(reduce #'max list))
Same remarks regarding empty list. These expressions are so small, many programmers will avoid writing a function and just use them directly.
Regarding recursion, you wouldn't use recursion to solve this problem in production code, only as a homework exercise for learning about recursion.
You are trying to compute the maximum value of a list, so please name your function maximum and your parameter list, not f3 or i. You can't name the function max without having to consider how to avoid shadowing the standard max function, so it is best for now to ignore package issues and use a different name.
There is a corner case to consider when the list is empty, as there is no meaningful value to return. You have to decide if you return nil or signal an error, for example.
The skeleton is thus:
(defun maximum (list)
(if (null list)
...
...))
Notice how closing parentheses are never preceded by spaces (or newlines), and opening parentheses are never followed by spaces (or newlines). Please note also that indentation increases with the current depth . This is the basic rules for Lisp formatting, please try following them for other developers.
(setq x <value>)
You are assigning an unknown place x, you should instead bind a fresh variable if you want to have a temporary variable, something like:
(let ((x <value>))
<body>)
With the above expression, x is bound to <value> inside <body> (one or more expressions), and only there.
(car (i))
Unlike in Java, parentheses are not used to group expressions for readability or to force some evaluation order, in Lisp they enclose compound forms. Here above, in a normal evaluation context (not a macro or binding), (i) means call function i, and this function is unrelated to your local variable i (just like in Java, where you can write int f = f(2) with f denoting both a variable and a method).
If you want to take the car of i, write (car i).
You seem to be using cond as some kind of if:
(cond (<test> <then>) <else>) ;; WRONG
You can have an if as follows:
(if <test> <then> <else>)
For example:
(if (> u v) u v) ;; evaluates to either `u` or `v`, whichever is greater
The cond syntax is a bit more complex but you don't need it yet.
You cannot return-from a block that was undeclared, you probably renamed the function to f3 without renaming that part, or copied that from somewhere else, but in any case return-from is only needed when you have a bigger function and probably a lot more side-effects. Here the computation can be written in a more functionnal way. There is an implicit return in Lisp-like languages, unlike Java, for example below the last (but also single) expression in add evaluates to the function's return value:
(defun add-3 (x)
(+ x 3))
Start with smaller examples and test often, fix any error the compiler or interpreter prints before trying to do more complex things. Also, have a look at the available online resources to learn more about the language: https://common-lisp.net/documentation
Although the other answers are right: you definitely need to learn more CL syntax and you probably would not solve this problem recursively in idiomatic CL (whatever 'idiomatic CL' is), here's how to actually do it, because thinking about how to solve these problems recursively is useful.
First of all let's write a function max/2 which returns the maximum of two numbers. This is pretty easy:
(defun max/2 (a b)
(if (> a b) a b))
Now the trick is this: assume you have some idea of what the maximum of a list of numbers is: call this guess m. Then:
if the list is empty, the maximum is m;
otherwise the list has a first element, so pick a new m which is the maximum of the first element of the list and the current m, and recurse on the rest of the list.
So, we can write this function, which I'll call max/carrying (because it 'carries' the m):
(defun max/carrying (m list)
(if (null list)
m
(max/carrying (max/2 (first list) m)
(rest list))))
And this is now almost all we need. The trick is then to write a little shim around max/carrying which bootstraps it:
to compute the maximum of a list:
if the list is empty it has no maximum, and this is an error;
otherwise the result is max/carrying of the first element of the list and the rest of the list.
I won't write that, but it's pretty easy (to signal an error, the function you want is error).
I am taking a programming language principle class where the professor talks about macro using Lisp (Precisly, Elisp). However, he didn't teach us how to write this language. As a result, I am trying to learn myself.
However, there are something that I just can't understand regarding the use of "tick" (') in Lisp. I do, however, understand the basic use. For example, if we have (cdr '(a b c)) it will give us a list (b c). Without the tick symbol, (a b c) would be evaluated as a function.
In the code written by my professor, I have noticed a strange use of "tick" symbol that I can't really understand the usage:
; not sure why there is a "'" in front of if and it is being added to a list ??
(defmacro myand(x y) (list 'if x y nil))
; Another example. Tick symbol before "greater than" symbol ? and made into a list?
(list 'if (list '> x y))
The uses of list and tick symbol just doesn't really make sense to me. Can anyone explain what is going on here? I suppose this is something special to Lisp
The 'tick symbol' is ': '<x> is syntactic sugar for (quote <x>) for any <x>. And (quote <x>) is simply <x> for any object <x>.
quote is needed in Lisp because programs in Lisp often want to reason about things which would have meaning as parts of Lisp programs, and need to say 'this isn't part of this program: it's data'. So, for instance, if I have a list of the form
((a . 1) (b . 2) ... (x . 26)) and I want to look up a symbol in it, I might write a function like this:
(defun ass (key alist)
(if (null? alist)
'()
(if (eql (car (car alist)) key)
(car alist)
(ass key (cdr alist)))))
Then when I wanted to look up, say x, I would have to say (ass (quote x) ...) because if I said (ass x ...) then x would be treated as a variable, and I don't want that: I want the symbol x.
In your example you are looking at programs which write Lisp programs – macros in other words – and these programs need to spend a lot of their time manipulating what will be Lisp source code as data. So in your myand macro, what you want is that
(myand x y)
should be rewritten as
(if x y nil)
Which is the same thing. So to construct this you need a list of four elements: the symbol if, the two variables and the symbol nil. Well you can make a list with list:
(list 'if x y 'nil)
Except that it turns out that the value of the symbol nil is just itself (nil is rather special in many Lisps in fact), so you can not bother quoting that: (list 'if x y nil) (I personally would have quoted it in this case, to make it clear what was literal and what was being evaluated, but that's probably not common).
I've been reading an article by Olin Shivers titled Stylish Lisp programming techniques and found the second example there (labeled "Technique n-1") a bit puzzling. It describes a self-modifying macro that looks like this:
(defun gen-counter macro (x)
(let ((ans (cadr x)))
(rplaca (cdr x)
(+ 1 ans))
ans))
It's supposed to get its calling form as argument x (i.e. (gen-counter <some-number>)). The purpose of this is to be able to do something like this:
> ;this prints out the numbers from 0 to 9.
(do ((n 0 (gen-counter 1)))
((= n 10) t)
(princ n))
0.1.2.3.4.5.6.7.8.9.T
>
The problem is that this syntax with the macro symbol after the function name is not valid in Common Lisp. I've been unsuccessfully trying to obtain similar behavior in Common Lisp. Can someone please provide a working example of analogous macro in CL?
Why the code works
First, it's useful to consider the first example in the paper:
> (defun element-generator ()
(let ((state '(() . (list of elements to be generated)))) ;() sentinel.
(let ((ans (cadr state))) ;pick off the first element
(rplacd state (cddr state)) ;smash the cons
ans)))
ELEMENT-GENERATOR
> (element-generator)
LIST
> (element-generator)
OF
> (element-generator)
This works because there's one literal list
(() . (list of elements to be generated)
and it's being modified. Note that this is actually undefined behavior in Common Lisp, but you'll get the same behavior in some Common Lisp implementations. See Unexpected persistence of data and some of the other linked questions for a discussion of what's happening here.
Approximating it in Common Lisp
Now, the paper and code you're citing actually has some useful comments about what this code is doing:
(defun gen-counter macro (x) ;X is the entire form (GEN-COUNTER n)
(let ((ans (cadr x))) ;pick the ans out of (gen-counter ans)
(rplaca (cdr x) ;increment the (gen-counter ans) form
(+ 1 ans))
ans)) ;return the answer
The way that this is working is not quite like an &rest argument, as in Rainer Joswig's answer, but actually a &whole argument, where the the entire form can be bound to a variable. This is using the source of the program as the literal value that gets destructively modified! Now, in the paper, this is used in this example:
> ;this prints out the numbers from 0 to 9.
(do ((n 0 (gen-counter 1)))
((= n 10) t)
(princ n))
0.1.2.3.4.5.6.7.8.9.T
However, in Common Lisp, we'd expect the macro to be expanded just once. That is, we expect (gen-counter 1) to be replaced by some piece of code. We can still generate a piece of code like this, though:
(defmacro make-counter (&whole form initial-value)
(declare (ignore initial-value))
(let ((text (gensym (string 'text-))))
`(let ((,text ',form))
(incf (second ,text)))))
CL-USER> (macroexpand '(make-counter 3))
(LET ((#:TEXT-1002 '(MAKE-COUNTER 3)))
(INCF (SECOND #:TEXT-1002)))
Then we can recreate the example with do
CL-USER> (do ((n 0 (make-counter 1)))
((= n 10) t)
(princ n))
023456789
Of course, this is undefined behavior, since it's modifying literal data. It won't work in all Lisps (the run above is from CCL; it didn't work in SBCL).
But don't miss the point
The whole article is sort of interesting, but recognize that it's sort of a joke, too. It's pointing out that you can do some funny things in an evaluator that doesn't compile code. It's mostly satire that's pointing out the inconsistencies of Lisp systems that have different behaviors under evaluation and compilation. Note the last paragraph:
Some short-sighted individuals will point out that these programming
techniques, while certainly laudable for their increased clarity and
efficiency, would fail on compiled code. Sadly, this is true. At least
two of the above techniques will send most compilers into an infinite
loop. But it is already known that most lisp compilers do not
implement full lisp semantics -- dynamic scoping, for instance. This
is but another case of the compiler failing to preserve semantic
correctness. It remains the task of the compiler implementor to
adjust his system to correctly implement the source language, rather
than the user to resort to ugly, dangerous, non-portable, non-robust
``hacks'' in order to program around a buggy compiler.
I hope this provides some insight into the nature of clean, elegant
Lisp programming techniques.
—Olin Shivers
Common Lisp:
(defmacro gen-counter (&rest x)
(let ((ans (car x)))
(rplaca x (+ 1 ans))
ans))
But above only works in the Interpreter, not with a compiler.
With compiled code, the macro call is gone - it is expanded away - and there is nothing to modify.
Note to unsuspecting readers: you might want to read the paper by Olin Shivers very careful and try to find out what he actually means...
I have written the following code snippet in scheme,
(define (test-for-prime number divisor)
(cond (prime? number) (number)
(else (let ((next-divisor) (find-next-divisor number (+ 1 divisor)))
(test-for-prime (/ number next-divisor) (next-divisor))))))
However, I get the following error
let: bad syntax (not an identifier and expression for a binding) in: (next-divisor)
How do I rectify it?
Try this version, it fixes all the syntax errors:
(define (test-for-prime number divisor)
(cond ((prime? number)
number)
(else
(let ([next-divisor (find-next-divisor number (+ 1 divisor))])
(test-for-prime (/ number next-divisor) next-divisor)))))
You have lots of misplaced parenthesis. Some are missing, some are mistaken ... I'd suggest you take a good read at a Scheme tutorial and play around writing some basic procedures to get the hang of it, in particular here is the documentation and correct structure for a let special form:
(let ([id val-expr] ...) body ...+)
The first form evaluates the val-exprs left-to-right, creates a new location for each id, and places the values into the locations. It then evaluates the bodys, in which the ids are bound. The last body expression is in tail position with respect to the let form. The ids must be distinct according to bound-identifier=?
Also it's a good idea to use an IDE/editor which highlights this kind of problems and helps you indent the code properly. In particular, be aware that a variable must not be surrounded in parenthesis, when you write this: (x) Scheme assumes that x is a procedure and that you're calling it.
Let has the following syntax (example with two bindings):
(let ((<var> <expr>)
(<var1> <expr1>))
<body>)
If we fill in your let form, you have two bindings: next-divisor gets bound to nothing, and find-next-divisor gets bound to number, but there is a third form (+ 1 divisor) that does not fit into let's syntax.
This might be what you want:
(let ((next-divisor (find-next-divisor number (+ 1 divisor))))
;; ...
)
I'm porting some code from lisp, but I got stuck at this part (apparently that's for mit-scheme)
(define (end-of-sentence? word)
(and (or (char-exist-last? word '#\.)
(char-exist-last? word '#\!)
(char-exist-last? word '#\?))
(not (initial? word))
(or (eq? (peek-char) '#\Space) ;;peek- so test for linefeed isn't affected
(eq? (peek-char) '#\n) ;;note- test for space isn't neccessary
(eq? (read-char) '#\t))))
;;counts the number of sentences in a given file and
;;stops at the given number
;;returns true once at that position, returns error if eof
(define (goto-sentence? file stop)
(define (c-g-iter num)
(cond ((= num stop)
#t)
((end-of-sentence?)
(c-g-iter (+ num 1)))
((not (char-ready?))
(error "EOF reached, number to large in goto-sentence?: " stop))
(else
(c-g-iter num))))
(begin
(open-path file)
(c-g-iter 1)))
Of course I could just skip that and implement what the comments say it does, but just wanted to be sure there's no magic happening in the background. So... how does this function even work -- where is it actually reading the characters? Is it as ugly as I think and does it consume the characters as a side-effect in the last check in end-of-sentence?? Or does the char-ready? actually read something?
But then again - what does (end-of-sentence?) (c-g-iter (+ num 1)) mean, as I don't expect c-g-iter to return a word.
I'm no scheme programmer, but it appears that characters are being consumed in read-char source
end-of-sentence? on the other hand appears to be getting called without a parameter, even though it is declared to take one. I assume that the functions it calls in turn are tolerant to whatever the system provides for unspecified parameters (nil?)
The pair (end-of-sentence?) (c-g-iter (+ num 1)) is a parameter to cond, which you can think like a switch or concise if/else; the first part is a test (end-of-sentence?), and the second is what to execute if true (c-g-iter (+ num 1))
Just adding my voice to the chorus; maybe I can provide some insight.
Some functions that are in these functions are not standard mit-sheme, such as char-exist-last? and initial?.(1) So I can't be sure what they do.
That being said, I think that end-of-sentence? takes in a string (word, so it should be a word) and returns true if its last character is a '!', '? or '.', and the next character after the word is a space, newline or tab character. Also, looking at intial, it probably can't be the first word in the sentence ('A.', for example, shouldn't return true, but 'A dog.' should.)
read-char does indeed 'consume characters' - "Returns the next character available from input-port, updating input-port to point to the following character." (Googled 'read-char mit scheme' to get MIT-Scheme input procedures.)
Per the same source char-ready? works like so: "Returns #t if a character is ready on input-port and returns #f otherwise."
Hope this is at least someone enlightening!
(1) MIT-Scheme Reference