I am trying to define my own function to make my hw2 easier but it is not working. Could you take a look at it and tell me what I am missing?
(DEFUN testAL(x)
COND ( ( ATOMP(x) ) 'this-is-an-atom )
( ( LISTP(x) ) 'this-is-a-list )
( T 'this-is-neither ) )
I want this conditional function to take an input X and output if it is an atom, list, or neither. Problem is that when I input NIL, I get an error: Attempt to take the value of the unbound variable `COND'.
Homework 2 consists of the following question:
Which of the following are atoms, which lists, which both and witch neither?
a. nil
b. (expt 10 3)
c. (a b)
d. 64
e. T
f. (No place like home)
g. ‘(+ 3 5 6)
Your parenthesis are not in the correct places. A parenthesis, unless quoted, are the start of a function application.
It begins with a variable cond that is not bound. It's not the special form (cond (predicate consequent) (predicate2 consequent2)) since it doesn't start with an open parenthesis.
From indentation alone I guess you meant to write:
(DEFUN testAL (x)
(COND ((ATOM x) 'this-is-an-atom)
((LISTP x) 'this-is-a-list)
(T 'this-is-neither)))
(testal 'test) ; ==> THIS-IS-AN-ATOM
(testal '(a b c)) ; ==> THIS-IS-A-LIST
I have removed the extra parenthesis around x since (x) means apply the function x while x means the variable x. With x in a different position like (+ x 3) then + is the function to be applied and x is one of its operands.
I changed atomp to atom. Since atom is one of the very first primitives defined with the very first LISP in the 50's, it does not have a postfix p like most other predicates.
Edit: Multiple match
You could just have several cond (or if since you only have one test in each) and do side effects like (print "THIS-IS-AN-ATOM") since your base case will never trigger (nothing is neither list nor atom in CL). This is perhaps the easies solution.
(DEFUN testAL (x)
(if (ATOM x) (print 'this-is-an-atom))
(if (LISTP x) (print 'this-is-a-list)))
(testal '()) ; ==> THIS-IS-A-LIST (but prints both)
For a more functional approach I would have done it with higher order functions keeping the code testable and supply a print-function that does the side effects. Be aware that this might not be as easy to read for a beginner:
;; a list of pairs of predicate and their desription
(defparameter *type-predicates-and-description*
'((douglasp . this-is-the-answer-to-everything)
(floatp . this-is-a-floating-pont-number)
(integerp . this-is-an-integer)
(numberp . this-is-a-number)
(null . this-is-null)
(listp . this-is-a-list)
(characterp . this-is-a-character)
(stringp . this-is-a-string)))
;; custom made predicate
(defun douglasp (x)
(and (numberp x) (= x 42)))
;; returns all the types of a particular value
(defun get-type-info (x)
"return a list if types thet describes argument"
(flet ((check-type (acc type-pair)
"Accumulate description when predicate match"
(if (funcall (car type-pair) x)
(cons (cdr type-pair) acc)
acc)))
;; test x for each type predicate-description
(let ((res (reduce #'check-type
*type-predicates-and-description*
:initial-value '())))
;; check of empty list (no types matched)
(if (null res)
(list 'this-is-neither)
res))))
;; test it
(get-type-info '()) ; ==> (THIS-IS-A-LIST THIS-IS-NULL)
(get-type-info 42) ; ==> (THIS-IS-A-NUMBER
; THIS-IS-AN-INTEGER
; THIS-IS-THE-ANSWER-TO-EVERYTHING)
(get-type-info #()) ; ==> (THIS-IS-NEITHER)
;; Make a function to do side effects
(defun print-type-info (x)
(format t "~{~a~^, ~}." (get-type-info x)))
(print-type-info '()) ; ==> NIL
; and prints "THIS-IS-A-LIST, THIS-IS-NULL."
Related
During the execution of my code I get the following errors in the different Scheme implementations:
Racket:
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 2 3)
arguments...:
Ikarus:
Unhandled exception
Condition components:
1. &assertion
2. &who: apply
3. &message: "not a procedure"
4. &irritants: ((1 2 3))
Chicken:
Error: call of non-procedure: (1 2 3)
Gambit:
*** ERROR IN (console)#2.1 -- Operator is not a PROCEDURE
((1 2 3) 4)
MIT Scheme:
;The object (1 2 3) is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
Chez Scheme:
Exception: attempt to apply non-procedure (1 2 3)
Type (debug) to enter the debugger.
Guile:
ERROR: In procedure (1 2 3):
ERROR: Wrong type to apply: (1 2 3)
Chibi:
ERROR in final-resumer: non procedure application: (1 2 3)
Why is it happening
Scheme procedure/function calls look like this:
(operator operand ...)
Both operator and operands can be variables like test, and + that evaluates to different values. For a procedure call to work it has to be a procedure. From the error message it seems likely that test is not a procedure but the list (1 2 3).
All parts of a form can also be expressions so something like ((proc1 4) 5) is valid syntax and it is expected that the call (proc1 4) returns a procedure that is then called with 5 as it's sole argument.
Common mistakes that produces these errors.
Trying to group expressions or create a block
(if (< a b)
((proc1)
(proc2))
#f)
When the predicate/test is true Scheme assumes will try to evaluate both (proc1) and (proc2) then it will call the result of (proc1) because of the parentheses. To create a block in Scheme you use begin:
(if (< a b)
(begin
(proc1)
(proc2))
#f)
In this (proc1) is called just for effect and the result of teh form will be the result of the last expression (proc2).
Shadowing procedures
(define (test list)
(list (cdr list) (car list)))
Here the parameter is called list which makes the procedure list unavailable for the duration of the call. One variable can only be either a procedure or a different value in Scheme and the closest binding is the one that you get in both operator and operand position. This would be a typical mistake made by common-lispers since in CL they can use list as an argument without messing with the function list.
wrapping variables in cond
(define test #t) ; this might be result of a procedure
(cond
((< 5 4) result1)
((test) result2)
(else result3))
While besides the predicate expression (< 5 4) (test) looks correct since it is a value that is checked for thurthness it has more in common with the else term and whould be written like this:
(cond
((< 5 4) result1)
(test result2)
(else result3))
A procedure that should return a procedure doesn't always
Since Scheme doesn't enforce return type your procedure can return a procedure in one situation and a non procedure value in another.
(define (test v)
(if (> v 4)
(lambda (g) (* v g))
'(1 2 3)))
((test 5) 10) ; ==> 50
((test 4) 10) ; ERROR! application: not a procedure
Undefined values like #<void>, #!void, #<undef>, and #<unspecified>
These are usually values returned by mutating forms like set!, set-car!, set-cdr!, define.
(define (test x)
((set! f x) 5))
(test (lambda (x) (* x x)))
The result of this code is undetermined since set! can return any value and I know some scheme implementations like MIT Scheme actually return the bound value or the original value and the result would be 25 or 10, but in many implementations you get a constant value like #<void> and since it is not a procedure you get the same error. Relying on one implementations method of using under specification makes gives you non portable code.
Passing arguments in wrong order
Imagine you have a fucntion like this:
(define (double v f)
(f (f v)))
(double 10 (lambda (v) (* v v))) ; ==> 10000
If you by error swapped the arguments:
(double (lambda (v) (* v v)) 10) ; ERROR: 10 is not a procedure
In higher order functions such as fold and map not passing the arguments in the correct order will produce a similar error.
Trying to apply as in Algol derived languages
In algol languages, like JavaScript and C++, when trying to apply fun with argument arg it looks like:
fun(arg)
This gets interpreted as two separate expressions in Scheme:
fun ; ==> valuates to a procedure object
(arg) ; ==> call arg with no arguments
The correct way to apply fun with arg as argument is:
(fun arg)
Superfluous parentheses
This is the general "catch all" other errors. Code like ((+ 4 5)) will not work in Scheme since each set of parentheses in this expression is a procedure call. You simply cannot add as many as you like and thus you need to keep it (+ 4 5).
Why allow these errors to happen?
Expressions in operator position and allow to call variables as library functions gives expressive powers to the language. These are features you will love having when you have become used to it.
Here is an example of abs:
(define (abs x)
((if (< x 0) - values) x))
This switched between doing (- x) and (values x) (identity that returns its argument) and as you can see it calls the result of an expression. Here is an example of copy-list using cps:
(define (copy-list lst)
(define (helper lst k)
(if (null? lst)
(k '())
(helper (cdr lst)
(lambda (res) (k (cons (car lst) res))))))
(helper lst values))
Notice that k is a variable that we pass a function and that it is called as a function. If we passed anything else than a fucntion there you would get the same error.
Is this unique to Scheme?
Not at all. All languages with one namespace that can pass functions as arguments will have similar challenges. Below is some JavaScript code with similar issues:
function double (f, v) {
return f(f(v));
}
double(v => v * v, 10); // ==> 10000
double(10, v => v * v);
; TypeError: f is not a function
; at double (repl:2:10)
// similar to having extra parentheses
function test (v) {
return v;
}
test(5)(6); // == TypeError: test(...) is not a function
// But it works if it's designed to return a function:
function test2 (v) {
return v2 => v2 + v;
}
test2(5)(6); // ==> 11
For an homework, I am trying to iterate through the list and make an if statement to each of the elements I encounter in Common Lisp.
Most of my problems come from me not knowing the syntax very well though.
Here is what I am trying to do:
*lst* is for example (1 4 2 6 4 7 2 4)
(setq finalList())
(loop for x in lst
(if ((< x 5) && (not(equal(x nil)))) ; IF x < 5 and x != nil
(append lst x) ; THEN STATEMENT
(princ "Skip") ; ELSE STATMENT
)
That logically should have done it, however, I am possibly wrong with my syntax
(If I forgot extra colon here, judge if as pseudo code, thanks)
How to iterate through the list and make an if else statements to each of the elements I encounter?
Errors
Syntax: instead of infix &&, you need prefix and
loop requires the keyword do before the if form.
append is non-destructive, so if you did not assign its return value to a variable, you did nothing.
Lisp function call syntax is (func arg1 arg2 ...) and not (func (arg1 arg2 ...)) as you use in your equal call.
The order of conditionals matters: if x is nil, then (< x 5) will signal an error, so you need to check x before the comparison.
The long and complicated (not (equal x nil)) is actually equivalent to x.
Unlike in other languages (e.g., C and Python), in Lisp parens matter, e.g., foo, (foo), ((foo)) are three very different things and can never be used interchangeably.
Solutions
Use the Loop micro-language
The loop facility is perfect as it has the if and collect clauses:
(loop for x in lst
if (and x (< x 5))
then collect x
else (print x))
Note: this does not really look like Lisp, so you might want to steer clear of loop while you are learning the language.
Use Functional Programming
(remove-if-not (lambda (x) (and x (< x 5))) lst)
Note: this does not print the dropped elements, I am sure you had the print clause for debugging only anyway.
Use Iteration
(let ((res ()))
(dolist (x lst (nreverse res))
(when (and x (< x 5))
(push x res))))
Note: I use nreverse: since we construct the result list ourselves, the is no reason not to use the destructive version or reverse.
I want to create a function using abstract list functions that will apply a list of functions onto each other, without a starting element (take the starting point as 0)
So '(list add1 sqr add1) -> 2
What I have so far creates a list of what those function do individually, so for the above example '(1 0 1)
Any help? An explanation would be nice if you could spare one, I'm still iffy about things such as foldr, map, etc
(define (apply_functions lof)
(map (lambda (lof) (lof 0)) lof))
I previously defined a composite function as below in case its helpful at all?
(define (composite f g)
(lambda (x) (f (g x))))
Could the initial problem also be translated to a function which takes in a list of function and an initial number (other than 0) and produces the number result
for example:
'( add1 sqr sub1) 4 -> 10
EDIT::
So looking at the question, it wanted something such as (check-expect ((composite-list (list add1 sqr sub1)) 3) 5), where the start number is not included as a variable. I've tried multiple variations of the code but can't make it work.
This is a perfect situation for using foldr, it behaves as expected:
(define (apply-functions lof)
(foldr (lambda (f acc) (f acc))
0
lof))
(apply-functions (list add1 sqr add1))
=> 2
It works because we apply each f in turn to the accumulated result, starting with 0. Notice that foldr applies the functions in the list in a right-to-left order (that is: the first function applied is the last one in the list, then the result of that is passed to the second-to-last function and so on). If you want to enforce a left-to-right order use foldl instead.
For the last part of your question (after the edit): we can start with a different initial number by simply passing the right parameter to foldr, and returning a curried function:
(define ((composite-list lof) init)
(foldr (lambda (f acc) (f acc))
init
lof))
((composite-list (list add1 sqr sub1)) 3)
=> 5
You can even do it more general than that. You can actually make a generic compose:
(define (my-compose . procedures)
(let* ((proc-in-order (reverse procedures))
(init-proc (car proc-in-order))
(remaining-procs (cdr proc-in-order)))
(lambda g
(foldl (lambda (x acc) (x acc))
(apply init-proc g)
remaining-procs))))
;; test first makes a list of it's arguments,
;; then takes the length, then negates that value
(define test (my-compose - length list))
(test 1 2 3 4) ; ==> -4
The first procedure in the chain (last argument) is applied with the initial argument as a list so it takes many arguments while the rest of the chain takes exactly one.
(define [DML vara]
(cond
((atom? (car vara))
(cond
((eqan? (car vara) 'N)
(display (cdr vara)))
(else (negate vara)))
)))
I'm currently trying to save the content of a return right now for simplicity I was testing the negate function it "returns" a list and I wanted to save the result of that function to do testing. How do I actually save the list return from negate.
Kind of like (x = (negate vara)) where x is the list. I look up let on google and in stack over flow but I can't find a very simple basic assignment.
Excuse my poor syntax on scheme I'm just starting..and going from imperative language to function isn't so smooth..
edit:
I wanted to print out the result expression of (negate vara) but since scheme only prints out the last "recursive call" (pardon my bad wording). I wanted it to use the resulting list from (negate vara) but still print out that list like
say if I had
(else (test (negate vara)))
...
(define (test vara)
(display "test")
)
I wanted it to display
'(O a b)) ;list
here
As you already know, a let expression will do the trick:
(let ((x 10)
(y 20))
(+ x y))
=> 30
The above expression binds values to two variables, x and y. These bindings will exist inside the body of the let. Implicitly, all the expressions in the let form are packed inside a begin, and the end result of the whole expression is the final expression. Notice that one binding cannot refer to the others in the definition part; if one variable needs to refer to previous definitions, then use a let*:
(let* ((x 10)
(y (* x 2)))
(+ x y))
=> 30
Finally, if you need to create a recursive definition use letrec:
(letrec ((fact (lambda (x)
(if (zero? x) 1 (* x (fact (sub1 x)))))))
(fact 10))
=> 3628800
You could make a procedure like you proposed:
(define (test var)
(display var)
var)
(test (negate (test vara)))) ; prints our argument and return
Or you could use DrRacket and use the debugger. You'll miss it after using it once!
Hi everyone I am trying to construct a mixed list with letters and numbers. For example when you call the funciton (inc-list1 '(cat 4 dog 3 x 5)) => (cat 5 dog 4 x 6). I am pretty sure the logic is right, so i think i am missing something from the syntax. Here is my code
(defun inc-list1 (list)
(cond ((null list)
nil
)
(numberp (first list)
(cons ( + 1 (first list)) (inc-list1 (rest list)))
)
(T
cons (first list) (inc-list1 (rest list))
)
)
)
An example of how you could have approached the problem:
(defun mapcar-if (list test if-true &optional (otherwise #'identity))
(mapcar
#'(lambda (x)
(funcall
(if (funcall test x)
if-true
otherwise) x)) list))
(mapcar-if '(cat 4 dog 3 x 5) #'numberp #'1+)
Which would make the function a little bit more useful in other situations too.
Your code:
(T cons ...) doesn't do what you think it does. You probably wanted to call cons rather then simply mention it. Mentioning it in the way you did has no effect and no side effect (it would have side effect, if the symbol cons was unbound - i.e. you'd receive an error). Whatever happens next is the result of the previous error. Calling (first list) has no side effect too (in your case).
"Consing" the list in the way you did isn't a particularly good technique. Because this technique is already implemented in other functions (like mapcar, reduce etc.) They were written with the purpose in mind to reduce the amount of text you have to type to write a program, and to make it easier to read, once you have written it. ;)
There are various typos in your code. Here is a fixed version
(defun inc-list1 (list)
(cond ((null list)
nil
)
((numberp (first list))
(cons ( + 1 (first list)) (inc-list1 (rest list)))
)
(t
(cons (first list) (inc-list1 (rest list)))
)
)
)
Note the added parens around the numberp and cons function calls and the t in lower case.