Reverse list on top level without 'appent' or 'list' - lisp

I made some function that can reverse simple lists, like (q w e r t y)
By the task it should correctly process: empty lists, lists, pairs, improper lists.
But now it fails on improper lists, like (q w e r t . y) or pairs.
How to process this situations?
My code:
(define myInverse2
(lambda (original result)
(
cond ((null? original)
result )
(#t
(myInverse2 (cdr original) (cons (car original) result)) )
) ) )
And dr Racket output:

Your code fails because when original is not null?, you assume you can take the cdr of it, which is not always guaranteed. You could fix your code to distinguish between cons? values and other values.
But first, ask yourself if this is necessary and what would be the reverse of some of your inputs. The reverse of a simple pair (x . y) is (y . x).
But what about the reverse of
(q w e r t . y)? I would expect reverse be its own inverse function (i.e. involution), so that you always have:
(equal? x (reverse (reverse x)))
... and if the reverse of the above is (y t r e w q), then you lose this property. Or, you could chose to have the result be (y t r e w . q), which, when reversed, gives you your result back. That is why you first have to chose what is the meaning of your function. Then, if the above approach is the one you want to take, then change should be easy; e.g. add a case in your cond which matches (cons? original).

Related

What does the expression (define (f x) (length (range 3000))) evaluate to?

For the expression
(define x (length (range 3000)))
I think it is evaluated to
(define x 3000)
For the expression
(define (f x) (length (range 3000)))
Does it evaluate to the following as well?
(define (f x) 3000)
No, they evaluate to two different procedures, with different bodies. A completely different matter is that when executed, they both will return the same value, namely 3000, ignoring the parameter in both cases. To be clear, the first expression binds f to a lambda (this is how define expands a procedure definition under the hood):
(define f
(lambda (x) (length (range 3000))))
The second expression also binds f to a lambda, but it's a different one:
(define f
(lambda (x) 3000))
Either one will return 3000 when invoked:
(f 42)
=> 3000
But the first one will do more work, it has to create a range and calculate its length, whereas the second one simply returns 3000. Regarding your first example - in the end x will have the same value, and it won't matter how you calculated it. But for the second example, the two fs are different objects, even though the values they calculate are the same.

How to convert from value with Any type to Real?

I'm playing with Racket-Stamps, which is a mix of typed and regular Racket.
I'm writing a new feature and the code below attempts to call a function with a list of Reals, however because this list comes from untyped racket, it is actually a list of Any:
(define bounding (make-parameter '()))
;; snip
(when (not (empty? (bounding)))
(let-values ([(x1 y1 x2 y2) (apply values (bounding))])
(send pr set-bounding x1 y1 x2 y2)))
And in another file that calls the code above:
(bounding '(-20 -100 100 2))
Here's the error:
Type Checker: Bad arguments to function in `apply':
Domains: a b ... b
#f *
Arguments: (Listof Any) *
in: (apply values (bounding))
So how do I convert the Listof Any to a Listof Real?
The apply function here is given an arbitrary-length list as input, but the context expects exactly 4 values. If the list had any length other than 4, it would fail.
It seems like you meant for bounding to contain either the empty list or a list of exactly 4 real numbers.
(: bounding : (Parameterof (U Null (List Real Real Real Real))))
(define bounding (make-parameter '()))
Then every time your program tests whether the contents of (bounding) are empty and then relies on it being a list of 4 numbers, you need to put the value in a local variable first, so that Typed Racket sees the connection between the (not (empty? ...)) test and the use below it.
In other words, transform the pattern
(if (not (empty? (bounding)))
(.... (bounding) ....)
....)
Into
(let ([bounding-v (bounding)])
(if (not (empty? bounding-v))
(.... bounding-v ....)
....))
In your example, that transformation gives:
(: bounding : (Parameterof (U Null (List Real Real Real Real))))
(define bounding (make-parameter '()))
....
(let ([bounding-v (bounding)])
(when (not (empty? bounding-v))
(let-values ([(x1 y1 x2 y2) (apply values bounding-v)])
(send pr set-bounding x1 y1 x2 y2))))

Creating a custom reverse of list

I'm trying to create a custom reverse of list in Lisp. I'm pretty new to Lisp programming, and still struggling with syntax. This is my code so far
(defun new-union(l1 l2)
(setq l (union l1 l2))
(let (res)
(loop for x in l
do(setq res (cons (car l) res))
do(setq l (cdr l)))))
Here I'm taking two lists, and forming union list l. Then for reversing the list l I'm accessing element wise to append it to a new list res. Then consequently using the cons, car and cdr to update the list.
However, I'm getting a weird output. Can someone please suggest where I'm going wrong?
I'm aware of an inbuilt function for the same called nreverse , but I wanted to experiment to see how the Lisp interprets the data in list.
On printing res at the end, for example
(new-union '(a b c) '(d e f))
the output for above call gives me
(L A A A A A A A X X)
I think I'm doing the looping wrong.
Problems
(summary of previous comments)
Bad indentation, spaces, and names; prefer this:
(defun new-union (l1 l2)
(setq list (union l1 l2))
(let (reversed)
(loop for x in list
do (setq res (cons (car list) reversed))
do (setq list (cdr list)))))
Usage of SETQ on undeclared, global variables, instead of a LET
Mutation of the structure being iterated (LIST)
Not using X inside the LOOP (why define it?)
The return value is always NIL
Refactoring
(defun new-union (l1 l2)
(let ((reverse))
(dolist (elt (union l1 l2) reverse)
(push elt reverse))))
Define a local reverse variable, bound to NIL by default (you could set it to '(), this is sometimes preferred).
Use DOLIST to iterate over a list and perform side-effects; the third argument is the return value; here you can put the reverse variable where we accumulate the reversed list.
For each element elt, push it in front of reverse; if you want to avoid push for learning purposes, use (setf reverse (cons elt reverse)).
Common Lisp is multi-paradigm and favors pragmatic solutions: sometimes a loop is more natural or more efficient, and there is no reason to force yourself to adopt a functional style.
Functional implementation
However, lists provide a natural inductive structure: recursive approaches may be more appropriate in some cases.
If you wanted to use a functional style to compute reverse, be aware that tail-call optimization, though commonly available, is not required by the language specification (it depends on your implementation capabilities and compiler options).
With default settings, SBCL eliminates calls in tail positions and would eliminate the risk of stack overflows with large inputs. But there are other possible ways to obtain bad algorithmic complexities (and wasteful code) if you are not careful.
The following is what I'd use to define the combination of union and reverse; in particular, I prefer to define a local function with labels to avoid calling new-union with a dummy nil parameter. Also, I iterate the list resulting from the union only once.
(defun new-union (l1 l2)
(labels ((rev (list acc)
(etypecase list
(null acc)
(cons (rev (rest list)
(cons (first list) acc))))))
(rev (union l1 l2) nil)))
Trace
0: (NEW-UNION (A B C) (D E F))
1: (UNION (A B C) (D E F))
1: UNION returned (C B A D E F)
1: (REV (C B A D E F) NIL)
2: (REV (B A D E F) (C))
3: (REV (A D E F) (B C))
4: (REV (D E F) (A B C))
5: (REV (E F) (D A B C))
6: (REV (F) (E D A B C))
7: (REV NIL (F E D A B C))
7: REV returned (F E D A B C)
6: REV returned (F E D A B C)
5: REV returned (F E D A B C)
4: REV returned (F E D A B C)
3: REV returned (F E D A B C)
2: REV returned (F E D A B C)
1: REV returned (F E D A B C)
0: NEW-UNION returned (F E D A B C)
Remark
It is quite surprising to reverse the result of union, when the union is supposed to operate on unordered sets: the order of elements in the result do not have to reflect the ordering of list-1 or list-2 in any way. Sets are unordered collections having no duplicates; if your input lists already represent sets, as hinted by the name of the function (new-union), then it makes no sense to remove duplicates or expect the order to be meaningful.
If, instead, the input lists represents sequences of values, then the order matters; feel free to use append or concatenate in combination with remove-duplicates, but note that the latter will remove elements in front of the list by default:
(remove-duplicates (concatenate 'list '(4 5 6) '(2 3 4)))
=> (5 6 2 3 4)
You may want to use :from-end t instead.
Ok...I think you want to take two lists, combine them together, remove duplicates, and then reverse them.
Your biggest problem is that you're using loops instead of recursion. LISP was born to do list processing using recursion. It's far more natural.
Below is a very simple example of how to do that:
(defvar l1 '(a b c)) ;first list
(defvar l2 '(d e f)) ;second list
(defun my-reverse (a b) ;a and b are lists
"combines a and b into lst, removes duplicates, and reverses using recursion"
(let ((lst (remove-duplicates (append a b))))
(if (> (length lst) 0)
(append (last lst) (my-reverse nil (butlast lst)))
nil)))
Sample Run compiled in SLIME using SBCL
; compilation finished in 0:00:00.010
CL-USER> l1 ;; verify l1 variable
(A B C)
CL-USER> l2 ;; verify l2 variable
(D E F)
CL-USER> (append l1 l2) ;; append l1 and l2
(A B C D E F)
CL-USER> (my-reverse l1 l2) ;; reverse l1 and l2
(F E D C B A)

LISP common list function

Hey guys I have one last problem Im trying to solve for my semester. I need to create:
(myCommon L1 L2)
Evaluates to a list of elements that are common in both lists L1 and L2.
Assume L1 and L2 have no repeated elements.
eg. (myCommon ‘(p a e g) ‘(a q r e)) → (a e)
I can only use the following functions:
(atom X)
(quote X)
‘X
(eq X Y)
(cons X L)
(car L)
(cdr L)
(list A B C)
(if X Y Z) .
(cond (C1 S1) (C2 S2) …… (Cn Sn))
(lambda (P1 P2 …… Pn) E)
(funcall F (P1 P2 …… Pn))
I can also use the functions I have created within the assignment. So far I have created:
(defun myLast (L)
(if (eq (cdr L) '())
(car L)
(myLast (cdr L)))) ;Evaluates to the last element of list L
(defun myCount (X L)
(cond ((eq L '()) 0)
((eq X (car L))(+ 1 (myCount X (cdr L))))
(+ (myCount X (cdr L))))) ;Evaluates to number of occurrences of X in L
(defun myMember (X L)
(cond ((eq L '()) '())
((eq X (car L)) t)
(t (myMember X (cdr L))))) ;Evaluates to true if X in L, false otherwise
The problem with this assignment is I cant meet up with the teacher to ask questions as hes gone, and has "limited email access" right now. I cant ask questions on how to solve this problem and I am very confused on even where to start for this function. I think I would have to use myMember on like the car of L1 and check if its in L2, if it is put it in a new list and recursively add to the list. I wasnt sure how to do this. Could anyone help me out so I can finally finish this semester? Thank you!
Your idea is a good one. You should look at the pattern you used in myCount. You can use nearly the same pattern for myCommon.
Think about how to bottom out of the recursion. You are building up a list, not a number, so instead of 0 as the terminal value, think about what the end of a list is.
For the recursion clauses, instead of using + 1 when you should include the item, use a function that adds an item to a list.
Remember to only recurse down one of the lists in myCommon. You should be looking at one element at a time, and compare that element to the complete second list, which for the purposes of myCommon should be a constant.
Hopefully this should help you along, in the spirit of your previous functions. But this is a very inefficient way of implementing a intersection-function.
A common trick which can help your compiler produce more efficient code is to use a helper function with a third parameter - an accumulator that you build up as you recurse down one of your input lists. (The accumulator trick lets you write your function in a style called tail recusive.)
And when you are not doing artificially restricted excercises to learn recursion, I would prefer to use iteration (loop or dolist) to solve this, especially when you are using common lisp, which doesn't mandate that the compiler produces efficient code even for the tail recursive calls. But then again, if you're not using a restricted version of common lisp, you could just call the built-in function intersection. :-)

scheme higher order func

Given the skeleton of a function:
(define gen-hash-division-method (lambda (size)))
as well as:
(define hash-1 (gen-hash-division-method 701))
What I have coded:
(define gen-hash-division-method
(lambda (size)
(lambda (w)
(modulo key(flip(w)) size))))
key(flip(w)) takes a list w and returns an integer.
And call:
(hash-1 '(h e l l o))
I keep getting this error:
procedure application: expected procedure, given: (h e l l o) (no arguments)
You're getting the error because in Scheme (w) expects w to be a function. But w is just a list of symbols.
In your case you have key(flip(w)) which doesn't make sense in Scheme land.
everything is surrounded by parentheses
You want (key (flip w))
Remember the lisp mantra : (function args ...)