Lisp, instructions not working in defun [duplicate] - syntax-error

This question already has answers here:
Common lisp error: "should be lambda expression"
(4 answers)
Closed 5 years ago.
I'm trying to make a function that changes infix input to prefix eg : (x + 1) as input outputted as (+ x 1).
So here is my code for the moment :
(setq x '(Y + 1))
(if (listp x ) (list (second x) (first x) (first (last x))) x)
so it returns (+ Y 1) if I input a list and the user input if it's not a list.
However, the problem is that I can't get this code working in a function :
(defun prefixToInfix (x)(
(if (listp x ) (list (second x) (first x) (first (last x))) x)
)
)
the function is indeed created but when I call it
(prefixtoinfix '(Y + 1))
I get an error
Error: Illegal function object: (IF (LISTP X) (LIST # # #) X).
[condition type: TYPE-ERROR]
I don't know why my if statement works in the main program but doesn't when I run it from my function.

What you are missing is that in Lisp parentheses are meaningful.
In C/Java/Python &c, the following expressions are the same:
a+b
(a+b)
(a)+(b)
(((a)+(b)))
(((((a)+(b)))))
In Lisp, the following expressions are very different:
a --- a symbol
(a) --- a list with a single element, which is the symbol a
(1 (2)) --- a list of two elements:
number 1
list of of length 1, containing number 2
In your case, function (note indentation and paren placement!)
(defun prefixToInfix (x)
((if (listp x) (list (second x) (first x) (first (last x))) x)))
has extra parens around if (and this causes the whole if form to be interpreted as a function, with disastrous results), and should be (note line breaks and indentation - lispers do not count parens, they look at indentation to understand the code, see http://lisp-lang.org/style-guide/)
(defun prefix-to-infix (x)
(if (listp x)
(list (second x)
(first x)
(first (last x)))
x))
PS. See also recommendations in want to learn common lisp.

Related

Sum of numeric elements in a nested list LISP

Return the SUM of numeric elements in a nested list using LISP. If there are no numeric elements return an empty list/NIL
Examples:
(6 3 -2 5 (4 2 -3) 4) should return 19
(1 2 3 (-4 5) a b c) should return 7
Asking other people to do your homework for you is almost never a good way of learning anything.
But here's an answer, which is written in a Lisp (Racket) and which does show how you ought to go about solving this problem, and also (I think) demonstrates some nice ways of thinking about problems like this ... but which you almost certainly can't cut and paste.
Note that this does not quite agree with the requirements given: which is supposed to return a non-numeric value for a list with no numbers in it. That breaks a recursive algorithm like this, since the empty list is a list with no numbers in it. So this does something more sensible. Making this answer implement the requirements is left as an exercise to the student.
(define (sum-nested-list l)
(let sum-nested-list-loop ([thing l]
[running-total 0])
(match thing
['()
;; We're done if we've run out of list
running-total]
[(list* (? number? x) r)
;; A list whose first element is a number: add it to the running total
;; and carry on on the rest of the list
(sum-nested-list-loop r (+ running-total x))]
[(list* (? list? x) r)
;; A list whose first element is a nested list: recurse into the
;; nested list
(sum-nested-list-loop r (sum-nested-list-loop x running-total))]
[(list* _ r)
;; A list whose first element is not a number or a nested list:
;; carry on on the rest of the list
(sum-nested-list-loop r running-total)]
[_
;; Not a list at all: explode
(error 'sum-numeric-list "what?")])))
(defun flat-sum (tree)
(let ((count 0))
(tree-equal tree tree :test (lambda (left right)
(if (numberp left)
(incf count left) t)))
count))
1> (flat-sum '(1 2 3 (-4 5) a b c))
7

While loops working mechanism of a program in Scheme

DrRacket user.
I'm struggling to understand how this program works.I wrote it myself and it does what it must but I can't understand how.
I define while loops as:
(define (while test body)
(if (test)
(begin
(body)
(while test body))
(void)))
Now I need to write a program that applies the given procedure to each element of a mutable list.
Here what I wrote:
(define (mlist-map-while f x)
(while (lambda() (not (null? x)))
(lambda ()
(set-mcar! x (f (mcar x)))
(set! x (mcdr x))))
(void))
So, defining
list1 (mlist 1 2 3)
and applying
(mlist-map-while (lambda (x) (+ x 1)) list1)
we get '(2 3 4).
The thing that I don't understand is how the first element of the list stays in it, because if it's done how I wrote here
(set! x (mcdr x))
the first procedure that sets -mcar! must be useless and be overlapped with the second. Like in this example:
(define list1 (mlist 1 2 3))
(set-mcar! list1 9)
(set-mcdr! list1 (mcdr list!))
and we lack the first element, but this program somehow leaves it in and gives the desired output. I would like to know how it works and whether there is another way of traversing the given list.
There is a big difference between set-cdr! abd set!. The first alters the pair's cdr pointer, while the latter alters the binding, thus what the name should point to.
In your mlist-map-while the variable x alters the car, then changes what x represents, to be the cdr of x. It never changes the cdr so your binding list1 always points to the first pair while x points to the first, then second, etc...
Thus it's more like this:
(define list1 (mlist 1 2 3))
(define list1-ref list1) ; variable pointing to the same value as list1
(set-mcar! list1-ref 9) ; set-car! changes the pair
(set! list1-ref (mcdr list)) ; set! updates what list1-ref points to
list1 ; ==> (9 2 3)
list-ref ; ==> (2 3)
You can iterate over a list in the same fashion without using set!, with recursion:
(define (fold function init lst)
(if (null? lst)
init
(fold function
(function (car lst) init)
(cdr lst))))
(fold + 0 '(1 2 3)
; ==> 6
(fold cons '() '(1 2 3))
; ==> (3 2 1)
Notice that here we recurse and change what lst is, to be the cdr. Every recursion has its own lst, which is not to be confused with the caller's own. It ends up doing the same as set! in your example, without mutation.

Scheme Racket Rackunit

I have to create test cases for each of my functions in Scheme. I'm getting an error: check-equal?: bad syntax
What am I doing wrong?
Here's what I have:
(require rackunit)
;Zip takes two lists and pairs each of the nth
;elements together
(define (zip . xss)
(apply map list xss)
)
(define (zip-test2)
(check-eq? (zip '(a b c) '(1 2 3)))
)
check-equal? and check-eq? both require at least 2 arguments: the expression to check and an expected value [1]. You seem to be providing only an expression to check, with no expected value. Presumably you want something like this:
(check-equal? (zip '(a b c) '(1 2 3))
'((a 1) (b 2) (c 3)))
More information is available in the documentation:
[1] http://doc.racket-lang.org/rackunit/api.html

Need help understanding bindings in Scheme code

For the code below, I am unable to comprehend how the bindings (x, y, z) occur. Please check out the code, I'll explain my problem in greater detail below:
(define (w x)
(lambda (y z)
(begin
(set! x (+ (* y x) z)) x)))
(define f1 (w 3))
(f1 4 2)
(f1 2 1)
The output is 14, 29. These are values for x.
This means initially, x=3, y=4, z=2. In the 2nd call, i.e. (f1 2 1), x=14, y=2,z=1.
My doubts:
How does the binding occur at first, why is x=3, y=4, and z=2? If it has got to do with lambda expression in the function, please elaborate on how it works..I have a feeling this is where my understanding breaks down..
Next, why is the initial answer of x=14 retained in the second call, i.e. (f1 2 1)?
Thank you for looking into this :)
When w is run, it creates a closure out of the inner lambda. Because x came from outside of that inner lambda, x is stored inside that closure (in this case, f1).
So, f1 has a variable inside that represents x, and it starts out as 3. When you run f1, it evaluates the math and then sets its own x to be 14.
The moral is, a lambda is more than just code; it's code combined with the variables it closes over, such as this x.

Unbound Variable on Function Name

I'm writing a program in Lisp(common lisp dialect)..
I want the program to count the number of sublists in a list..
This is what I have written till now:
(defun llength (L)
(cond
((null L) 0)
((list (first L)) (progn (+ (llength (first L)) 1) (llength (rest L))))
((atom (first L)) (llength (rest L)))
)
)
The function returns the error "Unbound variable: LLENGTH" and I don't understand why or how I can fix it..
Any suggestions ?
You have multiple errors in your code.
First of all, list function creates new list, not checking if it is a list. The function you need is listp - "p" at the end means "predicate".
Second, (progn (+ (llength (first L)) 1) (llength (rest L)) will not increase counter. progn performs expressions one by one and returns result of the last expression, other results are just thrown out. progn is there mostly for side effects. What you actually need is addition of all three components: 1 to indicate one found list, result of applying function to the first element and result for applying to the rest. So, this line must be:
((listp (first L)) (+ (llength (first L)) (llength (rest L)) 1))
More errors may exist, please, be careful to indent code correctly - it really helps to reduce them.
When you define a function with the (defun function name (parameters)) call you must then call the function by typing:
(function name (parameters))
Perhaps you were simply typing:
function name (parameters)
Doing this will get you the error you are receiving so be sure to encompass your whole statement in parenthesis.
(defun llength (list)
(cond
((null list) 0)
((listp (first list))
;; 1 + the count of any sub-lists in this sub-list + the
;; count of any sub-lists in the rest of the list.
(+ 1 (llength (first list))
(llength (rest list))))
(t (llength (rest list)))))
Test:
> (llength '(1 2 3 4))
0
> (llength '(1 2 (3 4)))
1
> (llength '(1 2 (3 (4))))
2
> (llength '(1 2 (3 4) (5 6) (7 8) (9 (10 (11)))))
6