I'm using scheme as part of a course I'm taking. I've been told to use high order functions in my homework. However this instruction seems somewhat unclear.
I don't fully understand the idea of a high order procedure. I'm able to do all the questions using recursion but that it's the same thing. Can anyone explain it with an example of a recursive function vs one written with a high order procedure.
As a second question:
Example: try to grab all the odd numbers
I could use (flatten (map odd ((1 4 5) (4 5 1 4 9)))), but what if there were nested lists, can I use map on a nested lists like:
(flatten (map odd ((1 3 (9 5 7)))) ; is there a function for this or a clean way to do it?
The point of a higher-order function is to reduce the boilerplate in your code, and to decrease coupling between the looping (technically it's a recursion, but its purpose is looping, so I will refer to it as such) and the actual logic. Here's an example (re grabbing all the odd numbers): a manual loop would look like this:
(define (filter-odd lst)
(cond ((null? lst) '())
((odd? (car lst)) (cons (car lst) (filter-odd (cdr lst))))
(else (filter-odd (cdr lst)))))
But notice that you've got the looping and the filtering in one function. This makes it harder to figure out what the function is doing, since these two unrelated operations are coupled together. With higher-level functions, you can do differently:
(define (filter pred lst)
(cond ((null? lst) '())
((pred (car lst)) (cons (car lst) (filter pred (cdr lst))))
(else (filter pred (cdr lst)))))
(define (filter-odd lst)
(filter odd? lst))
Notice now, how odd? is separated from the looping logic, which has now been separated into filter? filter now takes a function object which decides whether the item is to be kept or not, and callers of filter can slot in any function of their choice.
That is what is meant by a higher-order function: it's a function that takes a function object as a parameter, to customise its operation.
As mentioned in the original edit of your question, map is another higher-order function, but instead of filtering items from a list, it returns a transformation of every item in the original list, where the specific transformation is given by map's caller via a parameter.
To answer your actual question about flattening, etc., (map filter-odd '((1 3 (9 5 7)))) will return a list with a single item, the result of calling (filter-odd '(1 3 (9 5 7))). So no, map will not recurse into sublists for you (and neither will filter).
But you can flatten the input first (since you're flattening the output anyway), then call filter-odd on that directly. I hope that will give you the result you expect.
(I renamed your odd to filter-odd, since that is less likely to be confused with odd? (the predicate).)
Bonus material
By the way, both filter and map are specialisations of a much more general higher-order function, called a fold (or more specifically, a right-fold). Folds can express things that cannot be accommodated by either filter or map, but that somehow involve traversing all the items in a list. Here's an example of a length function, expressed as a fold:
(define (foldl func init lst)
(if (null? lst) init
(foldl func (func (car lst) init) (cdr lst))))
(define (length lst)
(foldl (lambda (elem count)
(+ count 1))
0 lst))
The benefit here is that the length function does not have to worry about traversing the list: that is handled by the fold. It only needs to worry about what to do at each iteration (which, here, is simply adding 1 to count, which starts out as 0).
In this case, the length is the same whether we traverse from the left or the right, and in Scheme, traversing from the left is more space-efficient, so we prefer that. But for implementing map and filter, a right-fold is necessary (otherwise the elements come out reversed---try substituting the foldr with foldl in the below functions and you'll see):
(define (foldr func init lst)
(if (null? lst) init
(func (car lst) (foldr func init (cdr lst)))))
(define (map func lst)
(foldr (lambda (elem result)
(cons (func elem) result))
'() lst))
(define (filter pred lst)
(foldr (lambda (elem result)
(if (pred elem)
(cons elem result)
result))
'() lst))
Related
I want to append the element b to the list a (let's say (a1, a2, ... an)), e.g. appending the number 3 to (1 2) gives (1 2 3)
So far I've been doing
(append a (list b)), which is kind of long and inelegant, so I wonder if there's a "better" way...
Are you building a list piecemeal, an item at a time? If so, the idiomatic way to do this is to build the list backward, using cons, and then reversing the final result:
(define (map-using-cons-and-reverse f lst)
(let loop ((result '())
(rest lst))
(if (null? rest)
(reverse result)
(loop (cons (f (car rest)) (cdr rest))))))
Alternatively, if your list-building is amenable to a "right-fold" recursive approach, that is also idiomatic:
(define (map-using-recursion f lst)
(let recur ((rest lst))
(if (null? rest)
'()
(cons (f (car rest)) (recur (cdr rest))))))
The above code snippets are just for illustrating the solution approach to take in the general case; for things that are directly implementable using fold, like map, using fold is more idiomatic:
(define (map-using-cons-and-reverse f lst)
(reverse (foldl (lambda (item result)
(cons (f item) result))
'() lst)))
(define (map-using-recursion f lst)
(foldr (lambda (item result)
(cons (f item) result))
'() lst))
How frequent do you have to append to the end?
If you want to do it a lot (more than cons'ing to the front), then you are doing it wrong. The right way is to flip things around: think that cons put things to the back, first retrieves the last element, rest retrieves everything but last, etc. Then, you can use list normally.
However, if you want to put things to the end of the list as frequent as to cons things to the front, then this is the best that you can do with one list. You could write a function to wrap what you consider "inelegant". Traditionally it's called snoc (backward cons)
(define (snoc lst e) (append lst (list e)))
Or if you prefer to implement the whole thing by yourself:
(define (snoc lst e)
(cond
[(empty? lst) (list e)]
[(cons? lst) (cons (first lst) (snoc (rest lst) e))]))
Note that both approaches have the same time complexity: O(n) where n is length of the list.
But if you want it to be efficient, you can use a data structure called double-ended queue, which is very efficient (constant time per operation). See http://www.westpoint.edu/eecs/SiteAssets/SitePages/Faculty%20Publication%20Documents/Okasaki/jfp95queue.pdf for more details.
I'm trying to write a simple procedure for finding the n:th prime but I don't think I understand how to reference variables correctly in racket.
What I want is for the inner procedure sieve-iter to add primes to the list primlst which is in the namespace of sieve but I get an infinite loop. My guess is that primlst within sieve-iter is causing issues.
(define (sieve n) ;; returns the n:th prime (n>0)
(let [(primlst '(2))
(cand 3)]
(define (sieve-iter i lst)
(cond ((null? lst) (and (cons i primlst) (sieve-iter (+ i 2) primlst))) ;;prime
((= (length primlst) n) (car primlst)) ;;end
((= (modulo i (car lst)) 0) (sieve-iter (+ i 2) primlst)) ;;non-prime
(#t (sieve-iter n (cdr lst))))) ;;unclear if prime
(sieve-iter cand primlst)))
Any help is appreciated!
First of all, you shouldn't refer to primlist at all within the sieve-iter function. Instead, you should refer to lst.
Second of all, you appear to be mistaken on the effect of this expression:
(and (cons i primlst) (sieve-iter (+ i 2) primlst))
You seem to be interpreting that as meaning "Add i to the primlist and then start the next iteration."
(cons i primlist) changes nothing. Instead, it creates a new list consisting of primlist with i in front of it and then evaluates to that value. The original primlist (which should have been lst anyway) is left untouched.
Also, and is for Boolean logic, not for stringing commands together. It evaluates each of its subexpressions separately until it finds one that evaluates to #f and then it stops.
You should replace that whole expression with this:
(sieve-iter (+ i 2) (cons i lst))
...which passes the new list created by cons to the next run of sieve-iter.
Your trying to do too much in one function, let prime-iter just worry about the iteration to build up the list of primes. Make another internal function to recurse down the existing primes to test the new candidate.
(define (sieve n) ;; returns the n:th prime (n>0)
(define (sieve-iter i lst remaining)
(cond ;((null? lst) (and (cons i primlst) (sieve-iter (+ i 2) primlst))) ;;should never be null, we are building the list up
((<= remaining 0) (car lst)) ;;checking length every time gets expensive added a variable to the function
((sieve-prime? i lst) ;;if prime add to lst and recurse on next i
(sieve-iter (+ i 2) (cons i lst) (- remaining 1)))
(else
(sieve-iter (+ i 2) lst remaining)))) ; else try next
(define (sieve-prime? i lst)
(cond ((null? lst) #t)
((= 0 (modulo i (car lst))) #f)
(else (sieve-prime? i (cdr lst)))))
(let ((primlst '(2)) ;;you generally don't modify these,
(cand 3)) ;mostly they just bind values to name for convenience or keep from having to re-calculate the same thing more than once
(sieve-iter cand primlst (- n 1))))
You could have used set! to modify primlist where it was before, but the procedure is no longer obviously a pure function.
There is another low-handing optimization possible here, when calling sieve-prime? filter the lst argument to remove values larger than the square root of i.
I'm totally new to Scheme and I am trying to implement my own map function. I've tried to find it online, however all the questions I encountered were about some complex versions of map function (such as mapping functions that take two lists as an input).
The best answer I've managed to find is here: (For-each and map in Scheme). Here is the code from this question:
(define (map func lst)
(let recur ((rest lst))
(if (null? rest)
'()
(cons (func (car rest)) (recur (cdr rest))))))
It doesn't solve my problem though because of the usage of an obscure function recur. It doesn't make sense to me.
My code looks like this:
(define (mymap f L)
(cond ((null? L) '())
(f (car L))
(else (mymap (f (cdr L))))))
I do understand the logic behind the functional approach when programming in this language, however I've been having great difficulties with coding it.
The first code snippet you posted is indeed one way to implement the map function. It uses a named let. See my comment on an URL on how it works. It basically is an abstraction over a recursive function. If you were to write a function that prints all numbers from 10 to 0 you could write it liks this
(define (printer x)
(display x)
(if (> x 0)
(printer (- x 1))))
and then call it:
(printer 10)
But, since its just a loop you could write it using a named let:
(let loop ((x 10))
(display x)
(if (> x 0)
(loop (- x 1))))
This named let is, as Alexis King pointed out, syntactic sugar for a lambda that is immediately called. The above construct is equivalent to the snippet shown below.
(letrec ((loop (lambda (x)
(display x)
(if (> x 0)
(loop (- x 1))))))
(loop 10))
In spite of being a letrec it's not really special. It allows for the expression (the lambda, in this case) to call itself. This way you can do recursion. More on letrec and let here.
Now for the map function you wrote, you are almost there. There is an issue with your two last cases. If the list is not empty you want to take the first element, apply your function to it and then apply the function to the rest of the list. I think you misunderstand what you actually have written down. Ill elaborate.
Recall that a conditional clause is formed like this:
(cond (test1? consequence)
(test2? consequence2)
(else elsebody))
You have any number of tests with an obligatory consequence. Your evaluator will execute test1? and if that evaluated to #t it will execute the consequence as the result of the entire conditional. If test1? and test2? fail it will execute elsebody.
Sidenote
Everything in Scheme is truthy except for #f (false). For example:
(if (lambda (x) x)
1
2)
This if test will evaluate to 1 because the if test will check if (lambda (x) x) is truthy, which it is. It is a lambda. Truthy values are values that will evaluate to true in an expression where truth values are expected (e.g., if and cond).
Now for your cond. The first case of your cond will test if L is null. If that is evaluated to #t, you return the empty list. That is indeed correct. Mapping something over the empty list is just the empty list.
The second case ((f (car L))) literally states "if f is true, then return the car of L".
The else case states "otherwise, return the result mymap on the rest of my list L".
What I think you really want to do is use an if test. If the list is empty, return the empty list. If it is not empty, apply the function to the first element of the list. Map the function over the rest of the list, and then add the result of applying the function the first element of the list to that result.
(define (mymap f L)
(cond ((null? L) '())
(f (car L))
(else (mymap (f (cdr L))))))
So what you want might look look this:
(define (mymap f L)
(cond ((null? L) '())
(else
(cons (f (car L))
(mymap f (cdr L))))))
Using an if:
(define (mymap f L)
(if (null? L) '()
(cons (f (car L))
(mymap f (cdr L)))))
Since you are new to Scheme this function will do just fine. Try and understand it. However, there are better and faster ways to implement this kind of functions. Read this page to understand things like accumulator functions and tail recursion. I will not go in to detail about everything here since its 1) not the question and 2) might be information overload.
If you're taking on implementing your own list procedures, you should probably make sure they're using a proper tail call, when possible
(define (map f xs)
(define (loop xs ys)
(if (empty? xs)
ys
(loop (cdr xs) (cons (f (car xs)) ys))))
(loop (reverse xs) empty))
(map (λ (x) (* x 10)) '(1 2 3 4 5))
; => '(10 20 30 40 50)
Or you can make this a little sweeter with the named let expression, as seen in your original code. This one, however, uses a proper tail call
(define (map f xs)
(let loop ([xs (reverse xs)] [ys empty])
(if (empty? xs)
ys
(loop (cdr xs) (cons (f (car xs)) ys)))))
(map (λ (x) (* x 10)) '(1 2 3 4 5))
; => '(10 20 30 40 50)
My task is to write function in lisp which finds maximum of a list given as argument of the function, by using recursion.I've tried but i have some errors.I'm new in Lisp and i am using cusp plugin for eclipse.This is my code:
(defun maximum (l)
(if (eq((length l) 1)) (car l)
(if (> (car l) (max(cdr l)))
(car l)
(max (cdr l))
))
If this isn't a homework question, you should prefer something like this:
(defun maximum (list)
(loop for element in list maximizing element))
Or even:
(defun maximum (list)
(reduce #'max list))
(Both behave differently for empty lists, though)
If you really need a recursive solution, you should try to make your function more efficient, and/or tail recursive. Take a look at Diego's and Vatine's answers for a much more idiomatic and efficient recursive implementation.
Now, about your code:
It's pretty wrong on the "Lisp side", even though you seem to have an idea as to how to solve the problem at hand. I doubt that you spent much time trying to learn lisp fundamentals. The parentheses are messed up -- There is a closing parenthesis missing, and in ((length l) 1), you should note that the first element in an evaluated list will be used as an operator. Also, you do not really recurse, because you're trying to call max (not maximize). Finally, don't use #'eq for numeric comparison. Also, your code will be much more readable (not only for others), if you format and indent it in the conventional way.
You really should consider spending some time with a basic Lisp tutorial, since your question clearly shows lack of understanding even the most basic things about Lisp, like the evaluation rules.
I see no answers truly recursive and I've written one just to practice Common-Lisp (currently learning). The previous answer that included a recursive version was inefficient, as it calls twice maximum recursively. You can write something like this:
(defun my-max (lst)
(labels ((rec-max (lst actual-max)
(if (null lst)
actual-max
(let ((new-max (if (> (car lst) actual-max) (car lst) actual-max)))
(rec-max (cdr lst) new-max)))))
(when lst (rec-max (cdr lst) (car lst)))))
This is (tail) recursive and O(n).
I think your problem lies in the fact that you refer to max instead of maximum, which is the actual function name.
This code behaves correctly:
(defun maximum (l)
(if (= (length l) 1)
(car l)
(if (> (car l) (maximum (cdr l)))
(car l)
(maximum (cdr l)))))
As written, that code implies some interesting inefficiencies (it doesn't have them, because you're calling cl:max instead of recursively calling your own function).
Function calls in Common Lisp are typically not memoized, so if you're calling your maximum on a long list, you'll end up with exponential run-time.
There are a few things you can do, to improve the performance.
The first thing is to carry the maximum with you, down the recursion, relying on having it returned to you.
The second is to never use the idiom (= (length list) 1). That is O(n) in list-length, but equivalent to (null (cdr list)) in the case of true lists and the latter is O(1).
The third is to use local variables. In Common Lisp, they're typically introduced by let. If you'd done something like:
(let ((tail-max (maximum (cdr l))))
(if (> (car l) tail-max)
(car l)
tail-max))
You would've had instantly gone from exponential to, I believe, quadratic. If in combination had done the (null (cdr l)) thing, you would've dropped to O(n). If you also had carried the max-seen-so-far down the list, you would have dropped to O(n) time and O(1) space.
if i need to do the max code in iteration not recursive how the code will be ??
i first did an array
(do do-array (d l)
setf b (make-array (length d))
(do (((i=0)(temp d))
((> i (- l 1)) (return))
(setf (aref b i) (car temp))
(setq i (+ i 1))
(setq temp (cdr temp))))
I made this, hope it helps and it is recursive.
(defun compara ( n lista)
(if(endp lista)
n
(if(< n (first lista))
nil
(compara n (rest lista)))))
(defun max_lista(lista)
(if (endp lista)
nil
(if(compara (first lista) (rest lista))
(first lista)
(max_lista(rest lista)))))
A proper tail-recursive solution
(defun maximum (lst)
(if (null lst)
nil
(maximum-aux (car lst) (cdr lst))))
(defun maximum-aux (m lst)
(cond
((null lst) m)
((>= m (car lst)) (maximum-aux m (cdr lst)))
(t (maximum-aux (car lst) (cdr lst)))))
(defun maxx (l)
(if (null l)
0
(if(> (car l) (maxx(cdr l)))
(car l)
(maxx (cdr l)))))
I'm trying to make a procedure called map-odd-mapper where I take a proc that can then be applied to a list
ex:
((make-odd-mapper add-one) (list 14 38 29 10 57))
(15 30 58)
I was thinking of putting it as a let function as in
(define (make-odd-mapper f)
(let (..........something using ret-odds to allow for the indices so that you can get the odd numbers....
ret-odds is defined as
(define (ret-odds lst)
(if (null? lst) null
(cons (car lst) (if (null? (cdr lst)) null (ret-odds (cdr (cdr lst))))))) the point of this is just to make a proc which will allow me to apply a procedure such as add-one to a list of odd indices....
This problem can be broken down into two smaller ones. At the risk of being pedantic: can you describe what these two smaller problems would be, and provide test cases for them?
(define (make-odd-mapper f)
(lambda (lst) (ret-odds (map f lst))))