When would I use mapc instead of mapcar? - dictionary

So far I have been using mapcar to apply a function to all elements of a list, such as:
(mapcar (lambda (x) (* x x))
'(1 2 3 4 5))
;; => '(1 4 9 16 25)
Now I learned that there is also the mapc function which does exactly the same, but does not return a new list, but the original one:
(mapc (lambda (x) (* x x))
'(1 2 3 4 5))
;; => '(1 2 3 4 5)
What's the intent of this function? When would I use mapc instead of mapcar if I am not able to access the result?

The Common Lisp Hyperspec says:
mapc is like mapcar except that the results of applying function are not accumulated. The list argument is returned.
So it is used when mapping is done for possible side-effects. mapcar could be used, but mapc reduces unnecessary consing. Also its return value is the original list, which could be used as input to another function.
Example:
(mapc #'delete-file (mapc #'compile-file '("foo.lisp" "bar.lisp")))
Above would first compile the source files and then delete the source files. Thus the compiled files would remain.
(mapc #'delete-file (mapcar #'compile-file '("foo.lisp" "bar.lisp")))
Above would first compile the source files and then delete the compiled files.

You should use mapc when you don't need to use the result of applying the function over the list. For example, to print out every element, you could use:
(mapc #'print '(1 2 3 4 5))
Technically, the print function will return something, but you don't need to use it, so you ignore it.

Related

Function with rest arguments calling a function with rest arguments

Let us suppose we have a function func1 :
(defun func1 (&rest values)
; (do something with values...)
(loop for i in values collect i))
Now, we have a function func2 which calls func1 :
(defun func2 (&rest values)
; (do something with values...)
(func1 ???))
What should I put instead of ??? to "copy" all the parameters of func2's values to func1's values ?
For instance, I would have the following behavior :
(func2 1 2 3 4) ; result is (1 2 3 4) and not ((1 2 3 4)).
In an earlier question I tried to do something like this :
(defun func2 (&rest values)
(macrolet ((my-macro (v)
`(list ,#v)))
(func1 (my-macro values))))
But the defun cannot get the value because it is not runtime. In this answer, he suggested that I use apply, but this function takes a &rest parameter too, so it doesn't solve my problem...
If possible, I would rather avoid to change the prototype of both functions, and the behavior of func1.
In common lisp, it has to be
(apply #'func1 values) ;; since `func1` has to be looked up in function namespace
remember, Clojure and Racket/Scheme are Lisp1, and common lisp is Lisp2.
Alternative solution (just for the sake)
I was asking myself, how to get it done without apply - just for the sake.
The problem with
`(func2 ,#values)
is, that if e.g.
(func2 (list 1 2 3) (list 4) 5)
is called, the values variable is ((1 2 3) (4) 5)
But when it is spliced into (func1 ,#values), what is created is
(func1 (1 2 3) (4) 5). But if we compare this with the func2 call,
it should be rather (func1 (list 1 2 3) (list 4) 5) which is perhaps not possible, because when (func2 (list 1 2 3) (list 4) 5) is called -
in the lisp manner - the arguments of func2 are each evaluated, before they enter the function body of func2, so we end up with values as a list of already evaluated arguments, namely ((1 2 3) (4) 5).
So somehow, concerning the arguments for func1 in the last expression, we are one evaluation-step offbeat.
But there is a solution with quote, that we manage to quote each of the arguments before giving it to func1 in the last expression, to "synchronize" the func1 function call - to let the arguments' evaluation pause for one round.
So my first aim was to generate a new values list inside the func2 body where each of the values list's argument is quoted (this is done in the let-binding).
And then at the end to splice this quoted-values list into the last expression: (func1 '(1 2 3) '(4) '5) which can be regarded as equivalent to (func1 (list 1 2 3) (list 4) 5) for this kind of problems / for this kind of calls.
This was achieved by this code:
(defun func2 (&rest vals)
(let ((quoted-values (loop for x in vals
collect `',x)))
; do sth with vals here - the func2 function -
(eval `(func1 ,#quoted-values))))
This is kind of a macro (it creates code btw. it organizes new code) but executed and created in run-time - not in pre-compile time. Using an eval we execute that generated code on the fly.
And like macroexpand-1, we can look at the result - the code - to which the func1 expression "expands", by removing eval around it - I call it func2-1:
(defun func2-1 (&rest vals)
(let ((quoted-values (loop for x in vals
collect `',x)))
; do sth with vals here - the func2 function -
`(func1 ,#quoted-values)))
And if we run it, it returns the last expression as code immediately before it is evluated in the func2 version:
(func2-1 (list 1 2 3) (list 4) 5)
;; (FUNC1 '(1 2 3) '(4) '5) ;; the returned code
;; the quoted arguments - like desired!
And this happens if we call it using func2 (so with evaluation of the func1 all:
(func2 (list 1 2 3) (list 4) 5)
;; ((1 2 3) (4) 5) ;; the result of (FUNC1 '(1 2 3) '(4) '5)
So I would say this is exactly what you desired!
lists vs. spread arguments
In Common Lisp it is good style to pass lists as lists and not as spread arguments:
(foo (list 1 2 3)) ; better interface
(foo 1 2 3) ; interface is not so good
The language has been defined in a way that efficient function calling can be used by a compiler and this means that the number of arguments which can be passed to a function is limited. There is a standard variable which will tell us how many arguments a particular implementation supports:
This is LispWorks on my Mac:
CL-USER 13 > call-arguments-limit
2047
Some implementations allow much larger number of arguments. But this number can be as low as 50 - for example ABCL, Common Lisp on the JVM, allows only 50 arguments.
Computing with argument lists
But sometimes we want the arguments as a list and then we can use the &rest parameter:
(lambda (&rest args)
(print args))
This is slightly in-efficient, since a list will be consed for the arguments. Usually Lisp tries to avoid to cons lists for arguments - they will be passed in registers or on the stack - if possible.
If we know that the argument list will not be used, then we can give the compiler a hint to use stack allocation - if possible:
(lambda (&rest args)
(declare (dynamic-extent args))
(reduce #'+ args))
In above function, the list of arguments can be deallocated when leaving the function - because the argument list is no longer used then.
If you want to pass these arguments to another function you can use FUNCALL and usually more useful APPLY:
(lambda (&rest args)
(funcall #'write (first args) (second args) (third args)))
or more useful:
(lambda (&rest args)
(apply #'write args))
One can also add additional arguments to APPLY before the list to apply:
CL-USER 19 > ((lambda (&rest args)
(apply #'write
(first args) ; the object
:case :downcase ; additional args
(rest args))
(values))
'(defun foo () 'bar)
:pretty t
:right-margin 15)
(defun foo ()
'bar)

Average using &rest in lisp

So i was asked to do a function i LISP that calculates the average of any given numbers. The way i was asked to do this was by using the &rest parameter. so i came up with this :
(defun average (a &rest b)
(cond ((null a) nil)
((null b) a)
(t (+ (car b) (average a (cdr b))))))
Now i know this is incorrect because the (cdr b) returns a list with a list inside so when i do (car b) it never returns an atom and so it never adds (+)
And that is my first question:
How can i call the CDR of a &rest parameter and get only one list instead of a list inside a list ?
Now there is other thing :
When i run this function and give values to the &rest, say (average 1 2 3 4 5) it gives me stackoverflow error. I traced the funcion and i saw that it was stuck in a loop, always calling the function with the (cdr b) witch is null and so it loops there.
My question is:
If i have a stopping condition: ( (null b) a) , shouldnt the program stop when b is null and add "a" to the + operation ? why does it start an infinite loop ?
EDIT: I know the function only does the + operation, i know i have to divide by the length of the b list + 1, but since i got this error i'd like to solve it first.
(defun average (a &rest b)
; ...
)
When you call this with (average 1 2 3 4) then inside the function the symbol a will be bound to 1 and the symbol b to the proper list (2 3 4).
So, inside average, (car b) will give you the first of the rest parameters, and (cdr b) will give you the rest of the rest parameters.
But when you then recursively call (average a (cdr b)), then you call it with only two arguments, no matter how many parameters where given to the function in the first place. In our example, it's the same as (average 1 '(3 4)).
More importantly, the second argument is now a list. Thus, in the second call to average, the symbols will be bound as follows:
a = 1
b = ((3 4))
b is a list with only a single element: Another list. This is why you'll get an error when passing (car b) as argument to +.
Now there is other thing : When i run this function and give values to the &rest, say (average 1 2 3 4 5) it gives me stackoverflow error. I traced the funcion and i saw that it was stuck in a loop, always calling the function with the (cdr b) witch is null and so it loops there. My question is:
If i have a stopping condition: ( (null b) a) , shouldnt the program stop when b is null and add "a" to the + operation ? why does it start an infinite loop ?
(null b) will only be truthy when b is the empty list. But when you call (average a '()), then b will be bound to (()), that is a list containing the empty list.
Solving the issue that you only pass exactly two arguments on the following calls can be done with apply: It takes the function as well as a list of parameters to call it with: (appply #'average (cons a (cdr b)))
Now tackling your original goal of writing an average function: Computing the average consists of two tasks:
Compute the sum of all elements.
Divide that with the number of all elements.
You could write your own function to recursively add all elements to solve the first part (do it!), but there's already such a function:
(+ 1 2) ; Sum of two elements
(+ 1 2 3) ; Sum of three elements
(apply #'+ '(1 2 3)) ; same as above
(apply #'+ some-list) ; Summing up all elements from some-list
Thus your average is simply
(defun average (&rest parameters)
(if parameters ; don't divide by 0 on empty list
(/ (apply #'+ parameters) (length parameters))
0))
As a final note: You shouldn't use car and cdr when working with lists. Better use the more descriptive names first and rest.
If performance is critical to you, it's probably best to fold the parameters (using reduce which might be optimized):
(defun average (&rest parameters)
(if parameters
(let ((accum
(reduce #'(lambda (state value)
(list (+ (first state) value) ;; using setf is probably even better, performance wise.
(1+ (second state))))
parameters
:initial-value (list 0 0))))
(/ (first accum) (second accum)))
0))
(Live demo)
#' is a reader macro, specifically one of the standard dispatching macro characters, and as such an abbreviation for (function ...)
Just define average*, which calls the usual average function.
(defun average* (&rest numbers)
(average numbers))
I think that Rainer Joswig's answer is pretty good advice: it's easier to first define a version that takes a simple list argument, and then define the &rest version in terms of it. This is a nice opportunity to mention spreadable arglists, though. They're a nice technique that can make your library code more convenient to use.
In most common form, the Common Lisp function apply takes a function designator and a list of arguments. You can do, for instance,
(apply 'cons '(1 2))
;;=> (1 . 2)
If you check the docs, though, apply actually accepts a spreadable arglist designator as an &rest argument. That's a list whose last element must be a list, and that represents a list of all the elements of the list except the last followed by all the elements in that final list. E.g.,
(apply 'cons 1 '(2))
;;=> (1 . 2)
because the spreadable arglist is (1 (2)), so the actual arguments (1 2). It's easy to write a utility to unspread a spreadable arglist designator:
(defun unspread-arglist (spread-arglist)
(reduce 'cons spread-arglist :from-end t))
(unspread-arglist '(1 2 3 (4 5 6)))
;;=> (1 2 3 4 5 6)
(unspread-arglist '((1 2 3)))
;;=> (1 2 3)
Now you can write an average* function that takes one of those (which, among other things, gets you the behavior, just like with apply, that you can pass a plain list):
(defun %average (args)
"Returns the average of a list of numbers."
(do ((sum 0 (+ sum (pop args)))
(length 0 (1+ length)))
((endp args) (/ sum length))))
(defun average* (&rest spreadable-arglist)
(%average (unspread-arglist spreadable-arglist)))
(float (average* 1 2 '(5 5)))
;;=> 3.25
(float (average* '(1 2 5)))
;;=> 2.66..
Now you can write average as a function that takes a &rest argument and just passes it to average*:
(defun average (&rest args)
(average* args))
(float (average 1 2 5 5))
;;=> 3.5
(float (average 1 2 5))
;;=> 2.66..

Clojure map. Pass function multiple parameters

I'm looking for a way how to use map function in more custom way. If there is a different function for what I'm trying to achieve, could you please let me know this.
;lets say i have addOneToEach function working as bellow
(defn plusOne[singleInt]
(+ 1 singleInt))
(defn addOneToEach[intCollection] ;[1 2 3 4]
(map plusOne intCollection)) ;=>(2 3 4 5)
;But in a case I would want to customly define how much to add
(defn plusX[singleInt x]
(+ x singleInt))
(defn addXToEach[intCollection x] ;[1 2 3 4]
;how do I use plusX here inside map function?
(map (plusX ?x?) intCollection)) ;=>((+ 1 x) (+ 2 x) (+ 3 x) (+ 4 x))
I'm not looking for a function that adds x to each in the collection, but a way to pass extra arguments to the function that map is using.
another option to the already mentioned would be partial (note that in the example the order of the params does not matter, since you just add them, but partial binds them from left to right, so beware):
user=> (doc partial)
-------------------------
clojure.core/partial
([f] [f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more])
Takes a function f and fewer than the normal arguments to f, and
returns a fn that takes a variable number of additional args. When
called, the returned function calls f with args + additional args.
nil
user=> (defn plus-x [x i] (+ x i))
#'user/plus-x
user=> (map (partial plus-x 5) [1 2 3])
(6 7 8)
There are several ways to go about it. One is using an explicit local function via letfn:
(defn add-x-to-each [ints x]
(letfn [(plus-x [i]
(+ i x))]
(map plus-x ints)))
For this small piece of code this is probably overkill and you can simply streamline it via an anonymous function:
(defn add-x-to-each [ints x]
(map #(+ % x) ints))
Both of these solutions basically apply the use of a closure which is an important concept to know: it boils down to defining a function dynamically which refers to a variable in the environment at the time the function was defined. Here we defer the creation of plus-x (or the anonymous) function until x is bound, so plus-x can refer to whatever value is passed in to add-x-to-each.
You almost got it right.
There are several possible ways:
1.
(defn addXToEach[intCollection x]
(map #(plusX % x) intCollection))
#(%) means same as (fn [x] (x)) (be aware that x is being evaluated here).
2.
(defn addXToEach[intCollection x]
(map (fn [item] (plusX item x)) intCollection))
3.
(defn addXToEach[intCollection x]
(map #(+ % x) intCollection))
and then you don't have to define your plusX function.
Hope it helps!
You are applying map to one collection, so the function that map applies must take one argument. The question is, how is this function to be composed?
The function
(defn plusOne [singleInt]
(+ 1 singleInt))
... works. It is otherwise known as inc.
But the function
(defn plusX [singleInt x]
(+ x singleInt))
... doesn't work, because it takes two arguments. Given a number x, you want to return a function that adds x to its argument:
(defn plusX [x]
(fn [singleInt] (+ x singleInt))
You can use a function returned by plusX in the map.
It is when you compose such a function that you can use extra arguments. This kind of function, composed as an expression involving captured data, is called a closure.
For example, (plusX 3) is a function that adds 3 to its argument.
(map (plusX 3) stuff)
;(4 5 6 7)
As you see, you don't need to name your closure.
Specifically for + the following will also work:
(map + (repeat 4) [3 4 9 0 2 8 1]) ;=> (7 8 13 4 6 12 5)
Of course, instead '4' put your number, or wrap with (let [x 4] ...) as suggested above.
It might not be the most performant, although, I guess.

When do you use "apply" and when "funcall"?

The Common Lisp HyperSpec says in the funcall entry that
(funcall function arg1 arg2 ...)
== (apply function arg1 arg2 ... nil)
== (apply function (list arg1 arg2 ...))
Since they are somehow equivalent, when would you use apply, and when funcall?
You should use funcall if you have one or more separate arguments and apply if you have your arguments in a list
(defun passargs (&rest args) (apply #'myfun args))
or
(defun passargs (a b) (funcall #'myfun a b))
apply is useful when the argument list is known only at runtime, especially when the arguments are read dynamically as a list. You can still use funcall here but you have to unpack the individual arguments from the list, which is inconvenient. You can also use apply like funcall by passing in the individual arguments. The only thing it requires is that the last argument must be a list:
> (funcall #'+ 1 2)
3
> (apply #'+ 1 2 ())
3
Well I think a good rule of thumb would be: use apply when you can't use funcall: the latter is clearer but is also less general than apply in that it doesn't allow you to call a function whose number of arguments is only known at runtime.
Of course it is only good practice and you could systematically do this the ugly way (systematically using apply), but as you've probably noticed, using the ugly way when a very similar but cleaner way is available is not very common-lisp-y.
Example of function that needs apply instead of funcall:
could you implement map in such a way that (map #'+ '(1 2) '(2 3)) and (map #'+ '(1 2) '(2 3) '(3 4)) both work (which is the case with the standard function) without using apply (or eval, which is cheating)?
EDIT: as has also been pointed out, it would be silly to write:(funcall func (first list) (second list) (third list) etc.) instead of (apply func list).
Apply function is curring the result, like it returns a function that applies to next argument, to next argument.
It is important subject on functional programming languages.
(mapcar 'list '((1 2)(3 4)))
(((1 2)) ((3 4)))
(funcall 'mapcar 'list '((1 2)(3 4)))
(((1 2)) ((3 4)))
(apply 'mapcar 'list '((1 2)(3 4)))
((1 3) (2 4))

Scheme: Implementing n-argument compose using fold

I'm trying to find the "best" implementation of a multi-argument "compose" in Scheme (I know it's a builtin in some implementations, but assume for the moment I am using one that doesn't have this).
For a 2-argument compose function I have this:
(define compose
(lambda (f g)
(lambda x
(f (apply g x)))))
This has the advantage that if the right-most function needs additional arguments, these can still be passed through the combined function. This has the pleasing property that composing the identity function on top of something does not change the function.
For example:
(define identity
(lambda (x) x))
(define list1
(compose identity list))
(define list2
(compose identity list1))
(list2 1 2 3)
> (1 2 3)
Now to do an "n-argument" compose I could do this:
(define compose-n
(lambda args
(foldr compose identity args)))
((compose-n car cdr cdr) '(1 2 3))
> 3
But this no longer preserves that nice "identity" property:
((compose-n identity list) 1 2 3)
> procedure identity: expects 1 argument, given 3: 1 2 3
The problem is that "initial" function used for the foldr command. It has built:
(compose identity (compose list identity))
So... I'm not sure the best way around this. "foldl" would seem to be the natural better alternative, because I want to it start with "identity" on the left not the right...
But a naive implementation:
(define compose-n
(lambda args
(foldl compose identity args)))
which works (have to reverse the order of function applications):
((compose-n cdr cdr car) '(1 2 3))
> 3
doesn't solve the problem because now I end up having to put the identity function on the left!
((compose-n cdr cdr car) '(1 2 3))
> procedure identity: expects 1 argument, given 3: 1 2 3
It's like, I need to use "foldr" but need some different "initial" value than the identity function... or a better identity function? Obviously I'm confused here!
I'd like to implement it without having to write an explicit tail-recursive "loop"... it seems there should be an elegant way to do this, I'm just stuck.
You might want to try this version (uses reduce from SRFI 1):
(define (compose . fns)
(define (make-chain fn chain)
(lambda args
(call-with-values (lambda () (apply fn args)) chain)))
(reduce make-chain values fns))
It's not rocket science: when I posted this on the #scheme IRC channel, Eli noted that this is the standard implementation of compose. :-) (As a bonus, it also worked well with your examples.)
The OP mentioned (in a comment to my answer) that his implementation of Scheme does not have call-with-values. Here's a way to fake it (if you can ensure that the <values> symbol is never otherwise used in your program: you can replace it with (void), (if #f #f), or whatever you like that's not used, and that's supported by your implementation):
(define (values . items)
(cons '<values> items))
(define (call-with-values source sink)
(let ((val (source)))
(if (and (pair? val) (eq? (car val) '<values>))
(apply sink (cdr val))
(sink val))))
What this does is that it fakes a multi-value object with a list that's headed by the <values> symbol. At the call-with-values site, it checks to see if this symbol is there, and if not, it treats it as a single value.
If the leftmost function in your chain can possibly return a multi-value, your calling code has to be prepared to unpack the <values>-headed list. (Of course, if your implementation doesn't have multiple values, this probably won't be of much concern to you.)
The issue here is that you're trying to mix procedures of different arity. You probably want to curry list and then do this:
(((compose-n (curry list) identity) 1) 2 3)
But that's not really very satisfying.
You might consider an n-ary identity function:
(define id-n
(lambda xs xs))
Then you can create a compose procedure specifically for composing n-ary functions:
(define compose-nary
(lambda (f g)
(lambda x
(flatten (f (g x))))))
Composing an arbitrary number of n-ary functions with:
(define compose-n-nary
(lambda args
(foldr compose-nary id-n args)))
Which works:
> ((compose-n-nary id-n list) 1 2 3)
(1 2 3)
EDIT: It helps to think in terms of types. Let's invent a type notation for our purposes. We'll denote the type of pairs as (A . B), and the type of lists as [*], with the convention that [*] is equivalent to (A . [*]) where A is the type of the car of the list (i.e. a list is a pair of an atom and a list). Let's further denote functions as (A => B) meaning "takes an A and returns a B". The => and . both associate to the right, so (A . B . C) equals (A . (B . C)).
Now then... given that, here's the type of list (read :: as "has type"):
list :: (A . B) => (A . B)
And here's identity:
identity :: A => A
There's a difference in kind. list's type is constructed from two elements (i.e. list's type has kind * => * => *) while identity's type is constructed from one type (identity's type has kind * => *).
Composition has this type:
compose :: ((A => B).(C => A)) => C => B
See what happens when you apply compose to list and identity. A unifies with the domain of the list function, so it must be a pair (or the empty list, but we'll gloss over that). C unifies with the domain of the identity function, so it must be an atom. The composition of the two then, must be a function that takes an atom C and yields a list B. This isn't a problem if we only give this function atoms, but if we give it lists, it will choke because it only expects one argument.
Here's how curry helps:
curry :: ((A . B) => C) => A => B => C
Apply curry to list and you can see what happens. The input to list unifies with (A . B). The resulting function takes an atom (the car) and returns a function. That function in turn takes the remainder of the list (the cdr of type B), and finally yields the list.
Importantly, the curried list function is of the same kind as identity, so they can be composed without issue. This works the other way as well. If you create an identity function that takes pairs, it can be composed with the regular list function.
While it would have been nice for the "empty" list to devolve to the identity function, surrendering this appears to result in the following, which isn't too bad:
(define compose-n
(lambda (first . rest)
(foldl compose first rest)))
((compose-n cdr cdr car) '(1 2 3))
((compose-n list identity identity) 1 2 3)

Resources