Scheme Racket Rackunit - testing

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

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

How to rewrite recursive procedure (repeated f n) as an iterative process using Racket?

This is what I have for recursive procedure (repeated f n) that applies the function f n times to an argument:
(define (repeated f count)
(if (= count 1)
f
(lambda (x)
(f ((repeated f (- count 1)) x)))))
E.g. ((repeated sqr 3) 2) returns 256, i.e. (sqr(sqr(sqr 2))).
But I have no idea how to implement repeated as an iterative process using Racket. Any advice is much obliged.
A typical solution for converting a recursive process to an iterative process is to enlist the aid of an accumulator.
Any way you slice it, repeated will have to return a procedure. One solution would use a named let inside the returned procedure that iterates n times, keeping track of the results in an accumulator. Here is a version of repeated that returns a unary procedure; note that there is no input validation here, so calls like ((repeated f 0) 'arg) will lead to trouble.
(define (repeated f n)
(lambda (x)
(let iter ((n n)
(acc x))
(if (= n 1) (f acc)
(iter (- n 1)
(f acc))))))
Named let expressions are very handy for things like this, but you could also define a helper procedure to do the same thing. I will leave that solution as an exercise for OP.
scratch.rkt> ((repeated sqr 3) 2)
256
scratch.rkt> ((repeated add1 8) 6)
14
I think using for/fold makes a cleaner solution
(define ((repeated f n) x)
(for/fold ([acc x]) ([i (in-range n)]) (f acc)))
Using it:
> ((repeated sqr 3) 2)
256
> ((repeated add1 8) 6)
14

Lisp, instructions not working in defun [duplicate]

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.

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.

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