Recursion in Lisp and making my own length function - function

I am trying to make my own length/2 function(which allows you to find the length of a list) in lisp and am having an issue.
If I were to program this in java I would create a global index variable
that = 0
Then in the method I would do
if(list.equal(null))
{
return index;
}
else
{
index++;
return functioname(tail of list) ;
}.
Obviously this is not actual java syntax but I am just trying to relay the logic I want to apply in lisp.
My main issue is that ifs in lisp only allow you to do
if test expression
then do something
else
do something else
while I am trying to do
if test expression
then do something
else
do 2x something
Is there a way I can accomplish this in lisp or is there a better way to go about this problem?

Do it recursively:
len(list):
if list is null
return 0
else
remove first_item from list
return 1 + len(list)
(define (length items)
(if (null? items)
0
(+ 1
(length (cdr items)))))
(length (list 1 2 3))
3
Or use set!:
(define count 0)
(define (length items)
(when (not (null? items))
(set! count (+ count 1))
(length (cdr items))))
(length (list 1 2 3 4 5))
count
5

Scheme has the special operator begin (the Common Lisp equivalent is progn) that lets you group expressions which are executed in sequence, and returns the last one.
(if (null? items)
0
(begin (set! index (+ 1 index))
(my-length (cdr items))
index))
If the if expression returns nil under the false condition, then you can also use when (as in Rahn's answer) which is a bit more compact.
That said, having a global variable, or any variable at all, whose value gets changed (which is the purpose of a variable) is not the Lisp/recursive way of doing things. (Global variables are not a good thing in any language.) Rahn's first example is the only way any experienced Lisp programmer would do it.
In my example above, the (set! index (+ 1 index)) and index)) lines, and the global variable index are completely unnecessary if you add the 1 to the (my-length (cdr items)). If the list is empty, the length is zero; otherwise, the length is 1 + the length of the tail of the list.

Related

I wrote up some simple scheme functions, but apparently none of them work and I'm wondering why

I wrote up a few little scheme functions
; Given a list, this should return the maximum value in the list.
(define (maxInt lst)
(if (empty? lst) 0 ; if the list is empty, return 0
(max(first lst) (maxInt(rest lst)))))
; ^ What this line does is recursively take the maximum of pairs in the list.
; Ex. If the list was (7 3 6 2), this line would take the max of 7 and (the max of 3 and(the max of 2 and 6)),
; returning a result of 7.
; The zip3 function. Takes three lists of integers and returns a list of ordered triples containing the first, second, or third elements of each original list(i.e. an ordered triple containing the first elements of each list, etc)
(define (zip3 lst1 lst2 lst3)
(if (or((not(= (length lst1)(length lst2))) (not(= (length lst2)(length lst3))) (not(= (length lst 1)(length lst3))))) (error "Error")
(append (map car(lst1 lst2 lst3)) (map cadr(lst1 lst2 lst3)) (map caddr(lst1 lst2 lst3)))))
; This says 'if list 1 and 2 are different lengths or list 2 and 3 are different lengths or list 1 and 3 are different lengths, return an error.
; Otherwise, append the list containing the ordered triple of the second element of each list and that containing said triple of the third element
; to the list containing the ordered triple of the first element of each list.'
; The compute function. takes a list of integers and and integer x and computes a + bx + cx^2 + etc, with a, b, c, etc being the ints in the list.
(define (compute polyLst x)
(for ([i (length polyLst)])
(+ (* (list-ref polyLst i) (expt x i)))))
; Recursion was hinted at for this one, but I found it easier to just use a for loop. This takes the sum of the products of each element of the list and
; x raised to the power of that element's index in the list.
I used the scheme notation exactly right(I thought), but none of these functions worked upon testing with a test program that called them. I'm really confused as to why these functions didn't work. It doesn't make any sense to me. I just want to know what I did wrong.
maxInt seems to work.
zip3 has a few parentheses errors, must use list and should read
(define (zip3 lst1 lst2 lst3)
(if (or (not(= (length lst1)(length lst2))) (not(= (length lst2)(length lst3))) (not(= (length lst1)(length lst3))))
(error "Error")
(append (map car (list lst1 lst2 lst3)) (map cadr (list lst1 lst2 lst3)) (map caddr (list lst1 lst2 lst3)))))
and compute needs to use for/sum:
(define (compute polyLst x)
(for/sum ([i (length polyLst)])
(* (list-ref polyLst i) (expt x i))))
Some refactoring ideas:
(define (maxInt lst)
(apply max lst))
(define (zip3 . l)
(flatten (apply map list l)))
(define (compute polyLst x)
(for/sum ([(e n) (in-indexed polyLst)])
(* e (expt x n))))

recursive definition of map in common lisp [duplicate]

This question already has answers here:
Why do we need funcall in Lisp?
(3 answers)
Closed 8 years ago.
I was expecting the Scheme approach:
(defun mmap (f xs)
(if (equal xs NIL)
'()
(cons (f (car xs)) (mmap f (cdr xs)))))
but i get a compiler warning
;Compiler warnings for ".../test.lisp" :
; In MMAP: Undefined function F
I can see that I need to make the compiler aware that f is a function. Does this have anything to do with #'?
Common Lisp is a LISP2. It means variables that are in the first element of the form is evaluated in a function namespace while everything else is evaluated from a variable namespace. Basically it means you can use the same name as a function in your arguments:
(defun test (list)
(list list list))
Here the first list is looked up in the function namespace and the other two arguments are looked up in the variable namespace. First and the rest become two different values because they are fetched from different places. If you'd do the same in Scheme which is a LISP1:
(define (test list)
(list list list))
And pass a value that is not a procedure that takes two arguments, then you'll get an error saying list is not a procedure.
A function with name x in the function namespace can be fetched from other locations by using a special form (function x). Like quote function has syntax sugar equivalent so you can write #'x. You can store functions in the variable namespace (setq fun #'+) and you can pass it to higher order functions like mapcar (CL version of Scheme map). Since first element in a form is special there is a primitive function funcall that you can use when the function is bound in the variable namespace: (funcall fun 2 3) ; ==> 5
(defun my-mapcar (function list)
(if list
(cons (funcall function (car list))
(my-mapcar function (cdr list)))
nil))
(my-mapcar #'list '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
A version using loop which is the only way to be sure not to blow the stack in CL:
(defun my-mapcar (function list)
(loop :for x :in list
:collect (funcall function x)))
(my-mapcar #'list '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
Of course, mapcar can take multiple list arguments and the function map is like mapcar but it works with all sequences (lists, arrays, strings)
;; zip
(mapcar #'list '(1 2 3 4) '(a b c d)) ; ==> ((1 a) (2 b) (3 c) (4 d))
;; slow way to uppercase a string
(map 'string #'char-upcase "banana") ; ==> "BANANA"
functions in CL that accepts functions as arguments also accept symbols. Eg. #'+ is a function while '+ is a symbol. What happens is that it retrieves #'+ by fetching the function represented by + in the global namespace. Thus:
(flet ((- (x) (* x x)))
(list (- 5) (funcall #'- 5) (funcall '- 5))) ; ==> (25 25 -5)
Trivia: I think the number in LISP1 and LISP2 refer to the number of namespaces rather than versions. The very first LISP interpereter had only one namespace, but dual namespace was a feature of LISP 1.5. It was he last LISP version before commercial versions took over. A LISP2 was planned but was never finished. Scheme was originally written as a interpreter in MacLisp (Which is based on LISP 1.5 and is a LISP2). Kent Pittman compared the two approaches in 1988.

Standard function for replacing subsequences

Quite often I need to replace subsequence of certain elements with another sequence of the same type, but, probably with different length. Implementation of such function is no challenge, this is what I use now:
(defun substitute* (new old where &key key (test #'eql))
(funcall (alambda (rest)
(aif (search old rest :key key :test test)
(concatenate (etypecase rest
(string 'string)
(vector 'vector)
(list 'list))
(subseq rest 0 it)
new
(self (subseq rest (+ it (length old)))))
rest))
where))
Works like this:
CL-USER> (substitute* '(x y) '(z) '(1 z 5 8 y z))
(1 X Y 5 8 Y X Y)
CL-USER> (substitute* "green button" "red button"
"here are red indicator, red button and red wire")
"here are red indicator, green button and red wire"
CL-USER> (substitute* #(4) #(2 2) #(2 2 2 2 2))
#(4 4 2)
You see, it's very handy and useful, so I've feeling that I'm reinventing wheel and it must be in the standard library, I just don't know its name (sometimes names are not obvious, you may search for filter while what you need is set-difference).
As a result of compromise between clarity and efficiency:
(defun substitute* (new old where &key key (test #'eql))
(let ((type (etypecase where
(string 'string)
(vector 'vector)
(list 'list)))
(new (coerce new 'list))
(old (coerce old 'list))
(where (coerce where 'list)))
(coerce (funcall (alambda (rest)
(aif (search old rest :key key :test test)
(append (remove-if (constantly t) rest :start it)
new
(self (nthcdr (+ it (length old)) rest)))
rest))
where)
type)))
I don't think that there's any standard function for this. It's more complicated than the standard replace family of functions. Those can operate destructively because you know in advance that you can replace element by element. Even in that case, it's still somewhat difficult to do this efficiently, because the access time for lists and vectors is very different, so general-purpose functions like subseq can be problematic. As Rainer Joswig pointed out in a comment:
It's kind of unfortunate that for many algorithms over sequences there
is no single efficient implementation. I see often that there are two
versions, one for lists and one for vectors, which then get hidden
behind a dispatching function. For a hack a simple common version is
fine, but for a library function, often there are different
implementations - like shown here.
(In fact, in doing a bit of research on whether some library contains a function for this, one of the first Google results I got was a question on Code Review, Generic sequence splitter in Common Lisp, in which Rainer and I both had some comment similar to those here.)
A version for lists
However, your implementation is rather inefficient because it makes multiple copies of the the remainders of sequences. E.g., when you replace (z) in (1 z 2 z 3 z), with (x y), you'll first make (3 x y), then copy it in making (2 x y 3 z y), and then you'll copy that in making (1 x y 2 x y 3 x y). You might be better off in doing one pass over the sequence, determining the indices of the subsequences to replace, or collecting the bits that need to don't need to be replaced, etc. You'll probably want separate implementations for lists and for other sequences. E.g., with a list, you might do:
(defun splice-replace-list (old new list)
(do ((new (coerce new 'list))
(old-len (length old))
(parts '()))
((endp list)
(reduce 'append (nreverse parts) :from-end t))
(let ((pos (search old list)))
(push (subseq list 0 pos) parts)
(cond
((null pos)
(setf list nil))
(t
(push new parts)
(setf list (nthcdr (+ old-len pos) list)))))))
There are some optimizations you could make here, if you wanted. For instance, you could implement a search-list that, rather than returning the position of the first instance of the sought sequence, could return a copy of the head up until that point and the tail beginning with the sequence as multiple values, or even the copied head, and the tail after the sequence, since that's what you're really interested in, in this case. Additionally, you could do something a bit more efficient than (reduce 'append (nreverse parts) :from-end t) by not reversing parts, but using a reversed append. E.g.,
(flet ((xappend (l2 l1)
(append l1 l2)))
(reduce #'xappend '((5 6) (x y) (3 4) (x y))))
;=> (x y 3 4 x y 5 6)
I wrote this in a somewhat imperative style, but there's no reason that you can't use a functional style if you want. Be warned that not all Lisp implementation support tail call optimization, so it might be better to use do, but you certainly don't have to. Here's a more functional version:
(defun splice-replace-list (old new list)
(let ((new-list (coerce new 'list))
(old-len (length old)))
(labels ((keep-going (list parts)
(if (endp list)
(reduce 'append (nreverse parts) :from-end t)
(let* ((pos (search old list))
(parts (list* (subseq list 0 pos) parts)))
(if (null pos)
(keep-going '() parts)
(keep-going (nthcdr (+ old-len pos) list)
(list* new-list parts)))))))
(keep-going list '()))))
A version for vectors
For non lists, this is more difficult, because you don't have the specific sequence type that you're supposed to be using for the result. This is why functions like concatenate require a result-type argument. You can use array-element-type to get an element type for the input sequence, and then use make-array to get a sequence big enough to hold the result. That's trickier code, and will be more complicated. E.g., here's a first attempt. It's more complicated, but you'll get a result that's pretty close to the original vector type:
(defun splice-replace-vector (old new vector &aux (new-len (length new)))
(flet ((assemble-result (length parts)
(let ((result (make-array length :element-type (array-element-type vector)))
(start 0))
(dolist (part parts result)
(cond
((consp part)
(destructuring-bind (begin . end) part
(replace result vector :start1 start :start2 begin :end2 end)
(incf start (- end begin))))
(t
(replace result new :start1 start)
(incf start new-len)))))))
(do ((old-len (length old))
(total-len 0)
(start 0)
(indices '()))
((null start) (assemble-result total-len (nreverse indices)))
(let ((pos (search old vector :start2 start)))
(cond
((null pos)
(let ((vlength (length vector)))
(push (cons start vlength) indices)
(incf total-len (- vlength start))
(setf start nil)))
(t
(push (cons start pos) indices)
(push t indices)
(incf total-len (- pos start))
(incf total-len new-len)
(setf start (+ pos old-len))))))))
CL-USER> (splice-replace-vector '(#\z) '(#\x #\y) "12z")
"12xy"
CL-USER> (splice-replace-vector '(z) '(x y) #(x y))
#(X Y)
CL-USER> (splice-replace-vector '(z) '(x y) #(1 z 2 z 3 4 z))
#(1 X Y 2 X Y 3 4 X Y)
CL-USER> (splice-replace-vector '(#\z) #(#\x #\y) "1z2z34z")
"1xy2xy34xy"
If you only want to make one pass through the input vector, then you could use an adjustable array as the output, and append to it. An adjustable array will have a bit more overhead than a fixed size array, but it does make the code a bit simpler.
(defun splice-replace-vector (old new vector)
(do ((vlength (length vector))
(vnew (coerce new 'vector))
(nlength (length new))
(result (make-array 0
:element-type (array-element-type vector)
:adjustable t
:fill-pointer 0))
(start 0))
((eql start vlength) result)
(let ((pos (search old vector :start2 start)))
(cond
;; add the remaining elements in vector to result
((null pos)
(do () ((eql start vlength))
(vector-push-extend (aref vector start) result)
(incf start)))
;; add the elements between start and pos to the result,
;; add a copy of new to result, and increment start
;; accordingly
(t
;; the copying here could be improved with adjust-array,
;; and replace, instead of repeated calls to vector-push-extend
(do () ((eql start pos))
(vector-push-extend (aref vector start) result)
(incf start))
(loop for x across vnew
do (vector-push-extend x result))
(incf start (1- nlength)))))))
A “generic” version
Using these two functions, you could define a general splice-replace that checks the type of the original input sequence and calls the appropriate function:
(defun splice-replace (old new sequence)
(etypecase sequence
(list (splice-replace-list old new sequence))
(vector (splice-replace-vector old new sequence))))
CL-USER> (splice-replace #(z) '(x y) #(1 z 2 z 3 4 z))
#(1 X Y 2 X Y 3 4 X Y)
CL-USER> (splice-replace '(z) #(x y) '(1 z 2 z 3 4 z))
(1 X Y 2 X Y 3 4 X Y)

Defining a Racket Function?

I'm supposed to define the function n! (N-Factorial). The thing is I don't know how to.
Here is what I have so far, can someone please help with this? I don't understand the conditionals in Racket, so an explanation would be great!
(define fact (lambda (n) (if (> n 0)) (* n < n)))
You'll have to take a good look at the documentation first, this is a very simple example but you have to understand the basics before attempting a solution, and make sure you know how to write a recursive procedure. Some comments:
(define fact
(lambda (n)
(if (> n 0)
; a conditional must have two parts:
; where is the consequent? here goes the advance of the recursion
; where is the alternative? here goes the base case of the recursion
)
(* n < n))) ; this line is outside the conditional, and it's just wrong
Notice that the last expression is incorrect, I don't know what it's supposed to do, but as it is it'll raise an error. Delete it, and concentrate on writing the body of the conditional.
The trick with scheme (or lisp) is to understand each little bit between each set of brackets as you build them up into more complex forms.
So lets start with the conditionals. if takes 3 arguments. It evaluates the first, and if that's true, if returns the second, and if the first argument is false it returns the third.
(if #t "some value" "some other value") ; => "some value"
(if #f "some value" "some other value") ; => "some other value"
(if (<= 1 0) "done" "go again") ; => "go again"
cond would work too - you can read the racket introduction to conditionals here: http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Conditionals_with_if__and__or__and_cond%29
You can define functions in two different ways. You're using the anonymous function approach, which is fine, but you don't need a lambda in this case, so the simpler syntax is:
(define (function-name arguments) result)
For example:
(define (previous-number n)
(- n 1))
(previous-number 3) ; => 2
Using a lambda like you have achieves the same thing, using different syntax (don't worry about any other differences for now):
(define previous-number* (lambda (n) (- n 1)))
(previous-number* 3) ; => 2
By the way - that '*' is just another character in that name, nothing special (see http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Identifiers%29). A '!' at the end of a function name often means that that function has side effects, but n! is a fine name for your function in this case.
So lets go back to your original question and put the function definition and conditional together. We'll use the "recurrence relation" from the wiki definition because it makes for a nice recursive function: If n is less than 1, then the factorial is 1. Otherwise, the factorial is n times the factorial of one less than n. In code, that looks like:
(define (n! n)
(if (<= n 1) ; If n is less than 1,
1 ; then the factorial is 1
(* n (n! (- n 1))))) ; Otherwise, the factorial is n times the factorial of one less than n.
That last clause is a little denser than I'd like, so lets just work though it down for n = 2:
(define n 2)
(* n (n! (- n 1)))
; =>
(* 2 (n! (- 2 1)))
(* 2 (n! 1))
(* 2 1)
2
Also, if you're using Racket, it's really easy to confirm that it's working as we expect:
(check-expect (n! 0) 1)
(check-expect (n! 1) 1)
(check-expect (n! 20) 2432902008176640000)

Difference between a macro definition and function definition

I'm trying to learn Lisp but I got stuck by this example (you can find it on "ANSI Common Lisp", by Paul Graham, page 170):
(defmacro in (obj &rest choices)
(let ((insym (gensym)))
`(let ((,insym ,obj))
(or ,#(mapcar #'(lambda (c) `(eql ,insym ,c))
choices)))))
Graham then states:
The second macro [...] in returns true if its first argument is eql to any of the other arguments. The Expression that we can write as:
(in (car expr) '+ '- '*)
we would otherwise have to write as
(let ((op (car expr)))
(or (eql op '+)
(eql op '-)
(eql op '*)))
Why I should write a macro when the following function I wrote seems to behave in the same way?
(defun in-func (obj &rest choices)
(dolist (x choices)
(if (eql obj x)
(return t))))
I do not understand if I am missing something or, in this case, in-func is equivalent to in.
The difference in using the macro vs function is in whether all the choices always are evaluated.
The expanded in macro evaluates the choices sequentially. If it reaches a choice that is eql to the first argument, it returns a true value without evaluating any more
forms.
In contrast, the in-func function will evaluate all the choices at the time the function is called.
The two other answers are correct, but to make things more concrete, consider this interaction:
CL-USER(1): (defmacro in ...)
IN
CL-USER(2): (defun in-func ...)
IN-FUNC
CL-USER(3): (defvar *count* 0)
*COUNT*
CL-USER(4): (defun next () (incf *count*))
NEXT
CL-USER(5): (in 2 1 2 3 (next))
T
CL-USER(6): *count*
0
CL-USER(7): (in-func 2 1 2 3 (next))
T
CL-USER(8): *count*
1