Racket - Remove a key from association list - racket

I'm trying to write a function which consumes a number, key, and an association list, al, and produces the association list resulting from removing key from al.
For example:
(check-expect (remove-al 5 (list (list 4 "A") (list 5 "B") (list 1 "C")))
(list (list 4 "A") (list 1 "C")))
I'm not permitted to use certain functions, like map, filter or remove, but have managed to write this so far. Below is my code:
define (remove-al key al)
(cond
[(empty? al) empty]
[(= key (first (first al))) empty]
[else (cons (first al)
(remove-al key (rest al)))]))
Which part of my code is wrong?

The concept behind this algorithm is to think of it in terms of an extended append implementation. If you are to look up the implementation of append in Racket, it is a recursive algorithm where the base case checks if the rhs list is empty, but if not it cons the first value of the lhs list with the result of the recursive call with the rest of lhs list and rhs. Here is a link to the implementation. The algorithm is simply the append implementation with an extra check to make sure to ignore the cons recursive call if the first element of the list matches the key.
SPOILERS
---->
(define (remove-al key lhs rhs)
(cond [(empty? lhs) rhs]
[else (cond [(not (=(first (first lhs)) key))
(cons (first lhs) (remove-al key (rest lhs) rhs))]
[else (remove-al key (rest lhs) rhs)])]))
(check-expect (remove-al 5 (list (list 4 "A") (list 5 "B") (list 1 "C")) '() )
(list (list 4 "A") (list 1 "C")))

Related

How to concatenate all the elements of the argument lists into a single list

I am trying to concatenate all elements in the list argument into a single list.
I have this code:
(define (concatenate . lsts)
(let rec ([l lsts]
[acc '()])
(if (empty? l)
acc
(rec (cons (list* l)
acc)))))
An example of output is here:
> (concatenate '(1 2 3) '(hi bye) '(4 5 6))
'(1 2 3 hi bye 4 5 6)
But I keep getting this error:
rec: arity mismatch;
the expected number of arguments does not match the given number
expected: 2
given: 1
Can someone please explain this?
Another answer explains the OP error,
and shows how the code can be fixed using append.
But there could be reasons for append to be disallowed in this assignment
(of course, it could be replaced with, for example, an inner "named let" iteration).
This answer will present an alternative approach and describe how it can be derived.
#lang racket
(require test-engine/racket-tests)
(define (conc . lols) ;; ("List of Lists" -> List)
;; produce (in order) the elements of the list elements of lols as one list
;; example: (conc '(1 2 3) '(hi bye) '(4 5 6)) => '(1 2 3 hi bye 4 5 6)
(cond
[(andmap null? lols) empty ] ;(1) => empty result
[else
(cons (if (null? (car lols)) ;(2) => head of result
(car (apply conc (cdr lols)))
(caar lols))
(apply conc ;(3) => tail of result
(cond
[(null? (car lols))
(list (cdr (apply conc (cdr lols)))) ]
[(null? (cdar lols))
(cdr lols) ]
[else
(cons (cdar lols) (cdr lols)) ]))) ]))
(check-expect (conc '() ) '())
(check-expect (conc '() '() ) '())
(check-expect (conc '(1) ) '(1))
(check-expect (conc '() '(1) ) '(1))
(check-expect (conc '() '(1 2) ) '(1 2))
(check-expect (conc '(1) '() ) '(1))
(check-expect (conc '(1) '(2) ) '(1 2))
(check-expect (conc '(1 2) '(3 4) ) '(1 2 3 4))
(check-expect (conc '(1 2 3) '(hi bye) '(4 5 6)) '(1 2 3 hi bye 4 5 6))
(test)
Welcome to DrRacket, version 8.6 [cs].
Language: racket, with debugging; memory limit: 128 MB.
All 8 tests passed!
>
How was this code derived?
"The observation that program structure follows data structure is a key lesson in
introductory programming" [1]
A systematic program design method can be used to derive function code from the structure
of arguments. For a List argument, a simple template (natural recursion) is often appropriate:
(define (fn lox) ;; (Listof X) -> Y ; *template*
;; produce a Y from lox using natural recursion ;
(cond ;
[(empty? lox) ... ] #|base case|# ;; Y ;
[else (... #|something|# ;; X Y -> Y ;
(first lox) (fn (rest lox))) ])) ;
(Here the ...s are placeholders to be replaced by code to create a particular list-argumented
function; eg with 0 and + the result is (sum list-of-numbers), with empty and cons it's
list-copy; many list functions follow this pattern. Racket's "Student Languages" support
placeholders.)
Gibbons [1] points out that corecursion, a design recipe based on result structure, can also
be helpful, and says:
For a structurally corecursive program towards lists, there are three questions to ask:
When is the output empty?
If the output isn’t empty, what is its head?
And from what data is its tail recursively constructed?
So for simple corecursion producing a List result, a template could be:
(define (fn x) ;; X -> ListOfY
;; produce list of y from x using natural corecursion
(cond
[... empty] ;(1) ... => empty
[else (cons ... ;(2) ... => head
(fn ...)) ])) ;(3) ... => tail data
Examples are useful to work out what should replace the placeholders:
the design recipe for structural recursion calls for examples that cover all possible input variants,
examples for co-programs should cover all possible output variants.
The check-expect examples above can be worked through to derive (1), (2), and (3).
[1] Gibbons 2021 How to design co-programs
Assuming you are allowed to call append, for simplicity. You have
(define (concatenate . lsts)
(let rec ([l lsts]
[acc '()])
(if (empty? l)
acc
(rec (cons (list* l) ; only ONE
acc) ; argument
))))
calling rec with only one argument. I have added a newline there so it becomes more self-evident.
But your definition says it needs two. One way to fix this is
(define (conc . lsts)
(let rec ([ls lsts]
[acc '()])
(if (empty? ls)
acc
(rec (cdr ls) ; first argument
(append acc (car ls)) ; second argument
))))
Now e.g.
(conc (list 1 2) (list 3 4))
; => '(1 2 3 4)
I used append. Calling list* doesn't seem to do anything useful here, to me.
(edit:)
Using append that way was done for simplicity. Repeatedly appending on the right is actually an anti-pattern, because it leads to quadratic code (referring to its time complexity).
Appending on the left with consequent reversing of the final result is the usual remedy applied to that problem, to get the linear behavior back:
(define (conc2 . lsts)
(let rec ([ls lsts]
[acc '()])
(if (empty? ls)
(reverse acc)
(rec (cdr ls)
(append (reverse (car ls))
acc)))))
This assumes that append reuses its second argument and only creates new list structure for the copy of its first.
The repeated reverses pattern is a bit grating. Trying to make it yet more linear, we get this simple recursive code:
(define (conc3 . lols)
(cond
[(null? lols) empty ]
[(null? (car lols))
(apply conc3 (cdr lols)) ]
[else
(cons (caar lols)
(apply conc3
(cons (cdar lols) (cdr lols))))]))
This would be even better if the "tail recursive modulo cons" optimization was applied by a compiler, or if cons were evaluated lazily.
But we can build the result in the top-down manner ourselves, explicitly, set-cdr!-ing the growing list's last cell. This can be seen in this answer.

Custom pattern-matching facility for Chez Scheme

I am trying to make my own pattern-matching system in Scheme. To begin I am making a parser for s-expressions that divides them into tokens like this:
'(1 2 b (3 4)) => '(number number symbol (number number))
It should be noted that I have not used define-syntax before in Scheme so that may be where I am messing up. Chez Scheme throws me this error:
Exception: invalid syntax classify at line 21, char 4 of pmatch.scm. Note that the line numbers won't correspond exactly to the snippet here. Does anyone know what I am doing wrong?
(define-syntax classify
(syntax-rules ()
((_ checker replacement)
((checker (car sexpr)) (cons replacement (classify-sexpr (cdr sexpr)))))))
(define (classify-sexpr sexpr)
(cond
((null? sexpr) sexpr)
(classify list? (classify-sexpr (car sexpr)))
(classify number? 'number)
(classify symbol? 'symbol)
(else
(cons 'symbol (classify-sexpr (cdr sexpr))))))
(display (classify-sexpr '(1 (b 3) (4 5) 6)))
Your code is hugely confused. In fact it's so confused I'm not sure what you're trying to do completely: I've based my answer on what you say the classifier should produce at the start of your question.
First of all your macro refers to sexpr which has no meaning in the macro, and because Scheme macros are hygienic it will definitely not refer to the sexpr which is the argument to classify-sexpr.
Secondly you don't need a macro at all here. I suspect that you may be thinking that because you are trying to write a macro you must use macros in its construction: that's not necessarily true and often a bad idea.
Thirdly the syntax of your cond is botched beyond repair: I can't work out what it's trying to do.
Finally the list classification will never be needed: if you want to classify (1 2 3 (x)) as (number number number (symbol)) then you'll simply never reach a case where you have a list which you want to classify since you must walk into it to classify its elements.
Instead just write the obvious functions do do what you want:
(define classification-rules
;; an alist of predicate / replacement which drives classigy
`((,number? number)
(,symbol? symbol)))
(define (classify thing)
;; classify thing using classification-rules
(let loop ([tail classification-rules])
(cond [(null? tail)
'something]
[((first (first tail)) thing)
(second (first tail))]
[else
(loop (rest tail))])))
(define (classify-sexpr sexpr)
;; classify a sexpr using classify.
(cond
[(null? sexpr) '()]
[(cons? sexpr) (cons (classify-sexpr (car sexpr))
(classify-sexpr (cdr sexpr)))]
[else (classify sexpr)]))
And now
> (classify-sexpr '(1 2 3 (x 2) y))
'(number number number (symbol number) symbol)
It may be that what you really want is something which classifies (1 2 (x 2)) as (list number number (list symbol number)) say. You can do this fairly easily:
(define atomic-classification-rules
;; an alist of predicate / replacements for non-conses
`((,number? number)
(,symbol? symbol)))
(define (classify-sexpr sexpr)
(cond
[(null? sexpr) '()]
[(list? sexpr)
`(list ,#(map classify-sexpr sexpr))]
[(cons? sexpr)
`(cons ,(classify-sexpr (car sexpr))
,(classify-sexpr (cdr sexpr)))]
[else
(let caloop ([rtail atomic-classification-rules])
(cond [(null? rtail)
'unknown]
[((first (first rtail)) sexpr)
(second (first rtail))]
[else
(caloop (rest rtail))]))]))
And now
> (classify-sexpr '(1 2 3 (x 2) y))
'(list number number number (list symbol number) symbol)
> (classify-sexpr '(1 2 3 (x 2) . y))
'(cons number (cons number (cons number (cons (list symbol number) symbol))))

Racket: Make list of pairs from two lists

I'm trying to make a function that takes in two lists of atoms as a parameter and returns them as a list of pairs.
Example Input
(combine '(1 2 3 4 5) '(a b c d e))
Example Output
'((1 a) (2 b) (3 c) (4 d) (5 e))
However, I'm new to Racket and can't seem to figure out the specific syntax to do so. Here is the program that I have so far:
(define connect
(lambda (a b)
(cond [(> (length(list a)) (length(list b))) (error 'connect"first list too long")]
[(< (length(list a)) (length(list b))) (error 'connect"first list too short")]
[else (cons (cons (car a) (car b)) (connect(cdr a) (cdr b)))]
)))
When I run it, it gives me the error:
car: contract violation
expected: pair?
given: '()
Along with that, I don't believe the error checking here works either, because the program gives me the same error in the else statement when I use lists of different lengths.
Can someone please help? The syntax of cons doesn't make sense to me, and the documentation for Racket didn't help me solve this issue.
When you're new to Scheme, you have to learn to write code in the way recommended for the language. You'll learn this through books, tutorials, etc. In particular, most of the time you want to use built-in procedures; as mentioned in the comments this is how you'd solve the problem in "real life":
(define (zip a b)
(apply map list (list a b)))
Having said that, if you want to solve the problem by explicitly traversing the lists, there are a couple of things to have in mind when coding in Scheme:
We traverse lists using recursion. A recursive procedure needs at least one base case and one or more recursive cases.
A recursive step involves calling the procedure itself, something that's not happening in your solution.
If we needed them, we create new helper procedures.
We never use length to test if we have processed all the elements in the list.
We build new lists using cons, be sure to understand how it works, because we'll recursively call cons to build the output list in our solution.
The syntax of cons is very simple: (cons 'x 'y) just sticks together two things, for example the symbols 'x and 'y. By convention, a list is just a series of nested cons calls where the last element is the empty list. For example: (cons 'x (cons 'y '())) produces the two-element list '(x y)
Following the above recommendations, this is how to write the solution to the problem at hand:
(define (zip a b)
; do all the error checking here before calling the real procedure
(cond
[(> (length a) (length b)) (error 'zip "first list too long")]
[(< (length a) (length b)) (error 'zip "first list too short")]
[else (combine a b)])) ; both lists have the same length
(define (combine a b)
(cond
; base case: we've reached the end of the lists
[(null? a) '()]
; recursive case
[else (cons (list (car a) (car b)) ; zip together one element from each list
(combine (cdr a) (cdr b)))])) ; advance the recursion
It works as expected:
(zip '(1 2 3 4 5) '(a b c d e))
=> '((1 a) (2 b) (3 c) (4 d) (5 e))
The reason your error handling doesn't work is because you are converting your lists to a list with a single element. (list '(1 2 3 4 5)) gives '((1 2 3 4 5)) which length is 1. You need to remove the list.
This post is a good explanation of cons. You can use cons to build a list recursively in your case.
(define connect
(lambda (a b)
(cond [(> (length a) (length b)) (error 'zip "first list too long")]
[(< (length a) (length b)) (error 'zip "first list too short")]
[(empty? a) '()]
[else (cons (list (car a) (car b)) (connect (cdr a) (cdr b)))]
)))
However, I would prefer Sylwester's solution
(define (unzip . lists) (apply map list lists))
which uses Racket's useful apply function.
#lang racket
(define (combine lst1 lst2)
(map list lst1 lst2))
;;; TEST
(combine '() '())
(combine (range 10) (range 10))
(combine (range 9) (range 10))
map have buildin check mechanism. We don't need to write check again.
#lang racket
(define (combine lst1 lst2)
(local [(define L1 (length lst1))
(define L2 (length lst2))]
(cond
[(> L1 L2)
(error 'combine "first list too long")]
[(< L1 L2)
(error 'combine "second list too long")]
[else (map list lst1 lst2)])))

Common LISP: Make Your Own Union Function

I'm trying to make my own union function and realizing how much I dislike LISP. The goal is to give the function two lists and it will return a set theoretic union of the two. My attempted solution has grown increasingly complex with the same result: NIL. I can't change that from being the result no matter what I do.
I was thinking of building a separate list in my "removeDuplicates" function below, but then idk how I'd return that with recursion. I think what's happening is my "removeDuplicates" function eventually returns an empty list (as intended) but then an empty list is return at every level of the stack when the recursion unfurls (starts returning values up the stack) but I could be wrong. I've always had trouble understanding recursion in detail. The code is below.
(defun rember (A LAT)
(cond
((null LAT) ())
((EQ (car LAT) A) (cdr LAT))
(T (cons (car LAT)(rember A (cdr LAT))))
)
)
(defun my_member (A LAT)
(cond
((null LAT) nil)
((EQ (car LAT) A) T)
(T (my_member A (cdr LAT)))
)
)
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
(T (removeDuplicates (cdr L)))
)
)
(defun my_union (A B)
(setq together(append A B))
(removeDuplicates together)
)
I'm aware most people are not a fan of this format of LISP code, but I prefer it. It allows me to see how parentheses line up better than if you just put all the closing parentheses together at the end of functions and condition blocks.
If I run (my_union '(a b) '(b c)) for example, the result is NIL.
When you call removeDuplicates recursively in the last condition, you're not combining the result with the car of the list, so you're discarding that element.
You're also not using the result of rember.
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L))
(cons (car L)
(removeDuplicates
(rember (car L) (cdr L))
))
)
(T (cons (car L) (removeDuplicates (cdr L))))
)
)
Here's a simple, obvious, union function:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
(pushnew e result)))))))
(union/spread (first lists) (rest lists))))
I think this is reasonably natural CL, although of course the whole point of using a language like CL is avoiding endless wheel-reinvention like this.
So the rules of the game perhaps say you're not allowed to use PUSHNEW: well, you can easily can replace it with a conditional involving MEMBER:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
;; Really use PUSHNEW for this
(unless (member e result)
(setf result (cons e result)))))))))
(union/spread (first lists) (rest lists))))
And perhaps you are also not allowed to use MEMBER: well you can easily write a predicate which does what you need:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
;; Really use MEMBER for this, and in fact
;; PUSHNEW
(unless (found-in-p e result)
(setf result (cons e result))))))))
(found-in-p (e list)
;; is e found in LIST? This exists only because we're not
;; meant to use MEMBER
(cond ((null list) nil)
((eql e (first list)) t)
(t (found-in-p e (rest list))))))
(union/spread (first lists) (rest lists))))
If you want the result to be a set with unique elements even if the first list is not you can trivially do that (note CL's UNION does not promise this, and you can get the same result with the earlier version of UNION/TFB by (union/tfb '() ...)):
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(let ((result l1))
(destructuring-bind (l2 . more) ls
(dolist (e l2 (union/spread result more))
;; Really use MEMBER for this, and in fact
;; PUSHNEW
(unless (found-in-p e result)
(setf result (cons e result))))))))
(found-in-p (e list)
;; is e found in LIST? This exists only because we're not
;; meant to use MEMBER
(cond ((null list) nil)
((eql e (first list)) t)
(t (found-in-p e (rest list))))))
(union/spread '() lists)))
Finally if the rules prevent you using iterative constructs and assignment you can do that too:
(defun union/tfb (&rest lists)
;; compute the union of any number of lists, implicitly using EQL
(labels ((union/spread (l1 ls)
;; UNION/SPREAD just exists to avoid the impedance
;; mismatch in argument convention
(if (null ls)
l1
(union/loop l1 (first ls) (rest ls))))
(union/loop (result l more)
;; UNION/LOOP is just an iteration
(if (null l)
(union/spread result more)
(destructuring-bind (e . remainder) l
(union/loop (if (found-in-p e result)
result
(cons e result))
remainder more))))
(found-in-p (e list)
;; is e found in LIST? This exists only because we're not
;; meant to use MEMBER
(cond ((null list) nil)
((eql e (first list)) t)
(t (found-in-p e (rest list))))))
(union/spread '() lists)))
The final result of all these changes is something which is, perhaps, very pure, but is not natural CL at all: something like it might be more natural in Scheme (albeit not gratuitously replacing MEMBER with a home-grown predicate like this).
One way to test your Common Lisp code is to ask your interpreter to TRACE functions:
(trace removeDuplicates my_member rember)
To avoid having too many traces, use small examples.
First, let's try with an empty list; this is an example from the REPL ("read eval print loop"), tested with SBCL, while in the "SO" package (StackOverflow); the trace is printed a bit indented, a is numbered according to the depth of the recursion. Here the call is not recursive and terminates right away:
SO> (removeduplicates nil)
0: (SO::REMOVEDUPLICATES NIL)
0: REMOVEDUPLICATES returned NIL
NIL
This works, let's try an example with a singleton list, where there is obviously no duplicate:
SO> (removeduplicates '(1))
0: (SO::REMOVEDUPLICATES (1))
1: (SO::MY_MEMBER 1 NIL)
1: MY_MEMBER returned NIL
1: (SO::REMOVEDUPLICATES NIL)
1: REMOVEDUPLICATES returned NIL
0: REMOVEDUPLICATES returned NIL
NIL
removeDuplicate calls my_member, which correctly returns nil, followed by a recursive call to removeDuplicates with nil, which correctly returns nil. There is however a problem because then, the outermost call returns nil too, which is incorrect.
Looking at the trace, we have to look back at the code to find a place where my_member is called, followed by a recursive call to removeDuplicates. There is only one place wher my_member is called, as a test to the second clause in the cond;
Since the result is nil for that test, the next clause is tried, in that case the default case:
(cond
...
;; this is the call to my_member (= nil)
((my_member (car L) (cdr L)) ...)
;; this is the recursive call
(t (removeDuplicates (cdr L))))
The value of the cond is the one given by the last (removeDuplicates (cdr L)), which just does not retain the existing elements in front of L. If you were mutating a sequence, you could just recurse down the subsequence and ignore the previous elements: in that case the caller would still hold a reference to the original sequence, which would get its element removed by a side-effect of your functions. But here you are following a strictly immutable approach, and you have to recontruct a list as a return value.
In other words, removeDuplicates is expressed as: return a new list which contains the same elements as the original list, but without duplicates.
So you have to add (car L) in front of (removeDuplicates (cdr L)).
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
(T (cons (car L)
(removeDuplicates (rest L))))))
Let's test:
SO> (removeduplicates '())
0: (SO::REMOVEDUPLICATES NIL)
0: REMOVEDUPLICATES returned NIL
NIL
SO> (removeduplicates '(1))
0: (SO::REMOVEDUPLICATES (1))
1: (SO::MY_MEMBER 1 NIL)
1: MY_MEMBER returned NIL
1: (SO::REMOVEDUPLICATES NIL)
1: REMOVEDUPLICATES returned NIL
0: REMOVEDUPLICATES returned (1)
(1)
You can test with a longer list (without duplicates), the result is correct, but the trace is longer.
Now, let's add duplicates:
SO> (removeduplicates '(1 2 2 1))
0: (SO::REMOVEDUPLICATES (1 2 2 1))
1: (SO::MY_MEMBER 1 (2 2 1))
2: (SO::MY_MEMBER 1 (2 1))
3: (SO::MY_MEMBER 1 (1))
3: MY_MEMBER returned T
2: MY_MEMBER returned T
1: MY_MEMBER returned T
1: (SO::REMBER 1 (1 2 2 1))
1: REMBER returned (2 2 1)
1: (SO::REMOVEDUPLICATES (2 2 1))
2: (SO::MY_MEMBER 2 (2 1))
2: MY_MEMBER returned T
2: (SO::REMBER 2 (2 2 1))
2: REMBER returned (2 1)
2: (SO::REMOVEDUPLICATES (2 1))
3: (SO::MY_MEMBER 2 (1))
4: (SO::MY_MEMBER 2 NIL)
4: MY_MEMBER returned NIL
3: MY_MEMBER returned NIL
3: (SO::REMOVEDUPLICATES (1))
4: (SO::MY_MEMBER 1 NIL)
4: MY_MEMBER returned NIL
4: (SO::REMOVEDUPLICATES NIL)
4: REMOVEDUPLICATES returned NIL
3: REMOVEDUPLICATES returned (1)
2: REMOVEDUPLICATES returned (2 1)
1: REMOVEDUPLICATES returned (2 1)
0: REMOVEDUPLICATES returned (2 1)
(2 1)
The result is correct (order does not matter).
So far, our tests are good.
You might not have identified the other problem in that function, namely that all calls to rember are useless, and frankly this is not necessarily easy to spot with the trace. But looking at the code, it should be clear if you write code to have little side-effects that the following clause calls (rember ...) for nothing:
((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
A cond clause has for syntax (TEST . BODY), where BODY is a sequence of expressions that evaluates like a PROGN: the value of a PROGN is the value of its last clause, all intermediate clauses are only used for their side-effects. For example:
(progn
(print "I am here")
(* 10 3))
Here above, the call to PRINT returns a value, but it is discarded: the value of the enclosing PROGN is 30.
In your code, rember does no side-effect, and its return value is discarded. Just remove it:
(defun removeDuplicates (L)
(cond
((null L) '())
((my_member (car L) (cdr L))
(removeDuplicates (cdr L)))
(T (cons (first L)
(removeDuplicates (rest L))))))
I would write the same code as follows, personally:
(defun remove-duplicate-elements (list)
(when list
(let ((head (first list))
(tail (remove-duplicate-elements (rest list))))
(if (member head tail) tail (cons head tail)))))
Here is a remove-dupes that removes duplicates from a list in O(n) time using a hash table. It supports a custom equality function (which must be eq, eql, equal or `equalp) and a custom test function, so that any aspect of an item can be treated as the key.
(defun remove-dupes (list &key (test #'eql) (key #'identity))
(let ((hash (make-hash-table :test test)))
(loop for item in list
for item-key = (funcall key item)
for seen = (gethash item-key hash)
unless seen collect item and
do (setf (gethash item-key hash) t))))
For instance, suppose we have the assoc list ((a . 1) (a . 2) (b . 3) (c . 4) (b . 4)). We'd like to remove duplicates by car:
[1]> (remove-dupes '((a . 1) (a . 2) (b . 3) (c . 4) (b . 4)) :key #'car)
((A . 1) (B . 3) (C . 4))
Only the leftmost A, B and C entries are reported; the duplicates are suppressed. Now let's do it by cdr:
[2]> (remove-dupes '((a . 1) (a . 2) (b . 3) (c . 4) (b . 4)) :key #'cdr)
((A . 1) (A . 2) (B . 3) (C . 4))
The (b . 4) got culled due to the duplicated 4 value.
But, why do all this, when Common Lisp provides a remove-duplicates function (not to mention union).
remove-duplicates is more general than what I have here: it handles sequences, rather than just lists, so it works on vectors and strings. It has more keyword parameters.

reversing list in Lisp

I'm trying to reverse a list in Lisp, but I get the error: " Error: Exception C0000005 [flags 0] at 20303FF3
{Offset 25 inside #}
eax 108 ebx 200925CA ecx 200 edx 2EFDD4D
esp 2EFDCC8 ebp 2EFDCE0 esi 628 edi 628 "
My code is as follows:
(defun rev (l)
(cond
((null l) '())
(T (append (rev (cdr l)) (list (car l))))))
Can anyone tell me what am I doing wrong? Thanks in advance!
Your code as written is logically correct and produces the result that you'd want it to:
CL-USER> (defun rev (l)
(cond
((null l) '())
(T (append (rev (cdr l)) (list (car l))))))
REV
CL-USER> (rev '(1 2 3 4))
(4 3 2 1)
CL-USER> (rev '())
NIL
CL-USER> (rev '(1 2))
(2 1)
That said, there are some issues with it in terms of performance. The append function produces a copy of all but its final argument. E.g., when you do (append '(1 2) '(a b) '(3 4)), you're creating a four new cons cells, whose cars are 1, 2, a, and b. The cdr of the final one is the existing list (3 4). That's because the implementation of append is something like this:
(defun append (l1 l2)
(if (null l1)
l2
(cons (first l1)
(append (rest l1)
l2))))
That's not exactly Common Lisp's append, because Common Lisp's append can take more than two arguments. It's close enough to demonstrate why all but the last list is copied, though. Now look at what that means in terms of your implementation of rev, though:
(defun rev (l)
(cond
((null l) '())
(T (append (rev (cdr l)) (list (car l))))))
This means that when you're reversing a list like (1 2 3 4), it's like you're:
(append '(4 3 2) '(1)) ; as a result of (1)
(append (append '(4 3) '(2)) '(1)) ; and so on... (2)
Now, in line (2), you're copying the list (4 3). In line one, you're copying the list (4 3 2) which includes a copy of (4 3). That is, you're copying a copy. That's a pretty wasteful use of memory.
A more common approach uses an accumulator variable and a helper function. (Note that I use endp, rest, first, and list* instead of null, cdr, car, and cons, since it makes it clearer that we're working with lists, not arbitrary cons-trees. They're pretty much the same (but there are a few differences).)
(defun rev-helper (list reversed)
"A helper function for reversing a list. Returns a new list
containing the elements of LIST in reverse order, followed by the
elements in REVERSED. (So, when REVERSED is the empty list, returns
exactly a reversed copy of LIST.)"
(if (endp list)
reversed
(rev-helper (rest list)
(list* (first list)
reversed))))
CL-USER> (rev-helper '(1 2 3) '(4 5))
(3 2 1 4 5)
CL-USER> (rev-helper '(1 2 3) '())
(3 2 1)
With this helper function, it's easy to define rev:
(defun rev (list)
"Returns a new list containing the elements of LIST in reverse
order."
(rev-helper list '()))
CL-USER> (rev '(1 2 3))
(3 2 1)
That said, rather than having an external helper function, it would probably be more common to use labels to define a local helper function:
(defun rev (list)
(labels ((rev-helper (list reversed)
#| ... |#))
(rev-helper list '())))
Or, since Common Lisp isn't guaranteed to optimize tail calls, a do loop is nice and clean here too:
(defun rev (list)
(do ((list list (rest list))
(reversed '() (list* (first list) reversed)))
((endp list) reversed)))
In ANSI Common Lisp, you can reverse a list using the reverse function (nondestructive: allocates a new list), or nreverse (rearranges the building blocks or data of the existing list to produce the reversed one).
> (reverse '(1 2 3))
(3 2 1)
Don't use nreverse on quoted list literals; it is undefined behavior and may behave in surprising ways, since it is de facto self-modifying code.
You've likely run out of stack space; this is the consequence of calling a recursive function, rev, outside of tail position. The approach to converting to a tail-recursive function involves introducing an accumulator, the variable result in the following:
(defun reving (list result)
(cond ((consp list) (reving (cdr list) (cons (car list) result)))
((null list) result)
(t (cons list result))))
You rev function then becomes:
(define rev (list) (reving list '()))
Examples:
* (reving '(1 2 3) '())
(3 2 1)
* (reving '(1 2 . 3) '())
(3 2 1)
* (reving '1 '())
(1)
If you can use the standard CL library functions like append, you should use reverse (as Kaz suggested).
Otherwise, if this is an exercise (h/w or not), you can try this:
(defun rev (l)
(labels ((r (todo)
(if todo
(multiple-value-bind (res-head res-tail) (r (cdr todo))
(if res-head
(setf (cdr res-tail) (list (car todo))
res-tail (cdr res-tail))
(setq res-head (list (car todo))
res-tail res-head))
(values res-head res-tail))
(values nil nil))))
(values (r l))))
PS. Your specific error is incomprehensible, please contact your vendor.