Is there some function to combine multiple sequences over a function? [duplicate] - clojure

This question already has an answer here:
Zip two lists in clojure into list of concatenated strings
(1 answer)
Closed 6 years ago.
If I have two sequences
(let [v1 '(1 2 3 4)
v2 '(2 4 6 8)]
...)
is there some way of combining them through a function to single vector, something like:
(combine #(* % %2) [1 2 3 4] [2 4 6 8]) => [2 8 18 32]
The "mapping" function would take one argument for each sequence "combined", so calling it with 3 sequences would require a 3-arity function.
If either sequence runs out of elements it should either just stop or repeat the shorter one, doesn't matter.

You can use the map function for this (from clojure.core).
map takes a function as its first argument, and any number of sequences as its subsequent arguments. It constructs each element of the output by taking an element from each input sequence and applying the function with that collection of elements as arguments, just as you require.
So your example would become:
(map * [1 2 3 4] [2 4 6 8])

Related

Why does list* in Clojure only work with a vector in tail position?

I am a clojure newbie. I am trying to play around repl and i see the following as output. And I don't quite understand why each of them behave so differently
(def a (list 1 2 3)) =>#'test.core/a
(list* 4 5 a) =>(4 5 1 2 3)
(list* a 4 5) =>IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:542)
why does the above 2 statements behave the same way in the above 2 statements?
(list* 4 5 [1 2 3]) =>(4 5 1 2 3)
(list* 4 5 [a]) =>(4 5 (1 2 3))
(list* 4 5 (1 2)) =>ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn test.core/eval3837 (form-init633779145118520639.clj:1)
Could someone explain why each of the above statement has a different output?
If you look at the definition and docstring, it'll make sense.
The docs say:
"Creates a new seq containing the items prepended to the rest, the last of which will be treated as a sequence."
Emphasis mine.
In the first block, the last expression fails because 5 is the last argument, but isn't a sequence.
(list* 4 5 [1 2 3]) works for the same reason that (list* 4 5 a) works. The last argument is a sequence, as it's expecting. It just cons onto the last argument as you can see in the definition.
(list* 4 5 [a]) gives different results because you've wrapped the collection a in another collection. It just adds onto the outer collection, leaving the inner one untouched.
The failure of (list* 4 5 (1 2)) isn't really a related problem. Remember, any time you have (...) unquoted, it will attempt to evaluate it, and is expecting that the first element in the list is callable. 1 however isn't callable, thus the error. You need to quote it to treat it as a list literal and not code that you want evaluated.
See the doc string for list*:
Creates a new seq containing the items prepended to the rest, the last
of which will be treated as a sequence.
Note a seq is not a list but lists and vectors and other things can be treated as sequences. Also a seq when output at the repl looks like a list - it is printed within parens.
So in the first case your last argument is a literal vector and it is treated as a sequence and you get an unnested sequence.
In the second case you have the list 'a' as a single element within a literal vector so the vector is treated as a sequence but the inner list is not, your returned sequence is three elements long: 4, 5, and the list a.
In the last case you are tripping up on the function call syntax in lisps being very similar to the list syntax. (1 2) is trying to call the number 1 as if it in a function (with the argument 2). A literal number can not be interpreted as a function.
If you want a list literal not a function call you have to quote it:
(list* 4 5 '(1 2)) => (4 5 1 2)

Difference between (list 1 2 3 4) and '(1 2 3 4)?

Here is my code:
(format t "~a~%" (list 1 2 3 4))
(format t "~a~%" '(1 2 3 4))
(format t "~a~%" (remove-if-not #'evenp (list 1 2 3 4)))
(format t "~a~%" (remove-if-not #'evenp '(1 2 3 4)))
Here is the output:
$ clisp bar.lisp
(1 2 3 4)
(1 2 3 4)
(2 4)
(2 4)
My questions:
What is the difference between the two syntaxes: (list 1 2 3 4) and '(1 2 3 4)?
Is there any advantage of using one syntax over another?
The difference between '(1 2 3 4) and (list 1 2 3 4) which seem to return absolutely the same result (1 2 3 4) is not visible, because numbers in Lisp evaluate to themselves.
Instead of numbers take symbols or expressions:
(list (+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5))
;; returns/evaluates to:
(3 5 7 9) ;; each of the arguments in a list gets evaluated.
;; while:
'((+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5)) ;; equals to: (quote ((+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5)))
;; returns/evaluates to:
((+ 1 2) (+ 2 3) (+ 3 4) (+ 4 5)) ;; arguments of list not evaluated
;; since `quote` means: take the argument as data - unevaluated.
Now you see clearly the difference: '(1 2 3 4) expanding to (and thus is syntactic sugar to) (quote (1 2 3 4)) is a special form, while (list 1 2 3 4) is a function. Functions in Lisp evaluate each of their arguments. But special forms don't evaluate each of their arguments. In the case of quote, the argument of quote is not evaluated.
And now you see, with a, b, c, d not defined before, this
'(a b c d)
;; returns: (A B C D)
works, since a b c d are not evaluated!
But this:
(list a b c d)
causes an error:
*** - SYSTEM::READ-EVAL-PRINT: variable A has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of A.
STORE-VALUE :R2 Input a new value for A.
ABORT :R3 Abort main loop
because neither a nor b nor c nor d are yet defined but the Lisp interpreter tries to evaluate them, since they are function arguments.
But you still can get (A B C D) using the function list by quoting each of the arguments - thus making them evaluate to their symbol names instead of the Lisp interpreter to lookup their undefined values:
(list 'a 'b 'c 'd)
;; now it works - though a b c d are not defined yet:
(A B C D)
Note: Interestingly, not in all languages, function arguments get evaluated, just because they are function arguments. While Python evaluates all of its function arguments similar to Lisp before entering and evaluation of the function body, R doesn't.
So the evaluation of function arguments is a Lisp-specific way to handle its function arguments. (But it shares it with most of the other languages - I just want to say the evaluation of function arguments is not a general rule). And that is also the fundamental difference between Lisp macros (and special forms) and Lisp functions. In Lisp macros (and special forms), you can specify which of the function arguments get evaluated in the macro body and which not. So that you have full control over evaluation of any of the macro arguments. In Lisp functions, by default, all arguments first get evaluated before you enter the function body.
That is also one of the reasons why you have also to learn macros (which specify special forms) in Lisp. quote together with list is actually the mother of all macros. Any backquote and unquote operations can be expressed by quote and list (though looking nastier for the human reader). One could ponder quite long about this topic, as you can imagine. And your question goes directly into the heart and essence of what makes Lisp so fascinating.
The difference is when the list gets created. One is created by the reader, the other at runtime.
The reader is responsible for turning your text file into a data structure representing code. This data structure happens to be mostly lists; this is the idea of Lisp (LISt Processing).
When the reader reads the text (foo bar), it creates a list of two elements, namely the symbols foo and bar. This is then compiled, i. e. translated, into a function call (or other call, but let's not divert here), where the function named by foo is called with with the value of the variable named by bar.
There is a special operator that tells the compiler not to do this translation: quote. When the compiler encounters the list (constructed by the reader) (quote (foo bar)), it uses the thing „protected“ by quote literally, i. e. exactly that list (foo bar) constructed by the reader.
The apostrophe ' is a shorthand for quote, so '(foo bar) is read as (quote (foo bar)).
The form '(1 2 3) is thus exactly the list that you wrote into your text file, as read by the reader. This is called a literal list.
On the other hand, (list 1 2 3) is a normal function call of the function list with three arguments. It creates a new list of these arguments any time this code is executed at runtime.
You should use a literal list only if it is constant. For example, when creating a multidimensional array, you might know its size is always the same (maybe it is intrinsic to the problem), so you write (make-array '(3 5)). If you want to make it configurable, you parameterize it: (make-array (list width height)).
One thing you absolutely must avoid is modifying literal data.

Why do nested applications of cons construct improper lists?

What do nested applications of cons construct improper lists?
I am learning scheme and confused about cons. I came across this answer:
Cons element to list vs cons list to element in Scheme
I know when the second argument to cons is a list , it adds the first argument to the head of the list
(cons 1 (list 2 3)
=>'(1 2 3)
The following pair makes sense to me:
(cons 2 3); 2.3 pair
However I don't understand why the following expression constructs an improper list
(cons 1 (cons 2 3))
=> '(1 2 . 3) ; an improper list
I just can't visualize what's going on with the expression above
can you please elaborate on that?
The confusion you're experiencing is not unique. It's just notation, that is all, and until you learn to see that notation, everything is confusing.
First, let's start with proper lists. These are lists that end with an empty list:
(cons 1 (cons 2 (cons 3 '())))
; => (1 2 3)
This list, (1 2 3), is actually a shorthand for (1 2 3 . ()): basically a list where the last cons points to an empty list.
Now, if we substitute the () with 4, let's see what we get:
(cons 1 (cons 2 (cons 3 4)))
; => (1 2 3 . 4)
Notice, it's not so different from (1 2 3 . ()), is it?
Of course, both of these are shorthands for the much longer forms of (1 . (2 . (3 . ()))) and (1 . (2 . (3 . 4))), respectively.

Using Racket plot lines

I'm trying to use the lines function to plot a graph, but I can't seem to figure out the exact syntax.
Here's some code I tried:
(require plot)
(define lst '(1 2 3 4 5 6 7 8 9))
(define f (plot-frame (lines lst)))
(send f show #t)
But it gives me the following error message:
lines: contract violation
expected: sequence of length >= 2
given: #<sequence>
The lines function's first argument is supposed to be a sequence of sequences of real numbers (as opposed to just a sequence of real numbers). That's what this contract shown in the documentation means: (sequence/c (sequence/c real?))
For example, this is a valid input: (lines '((1 2) (3 4)))
There's also a full example in the docs: http://www.cs.utah.edu/plt/snapshots/current/doc/plot/renderer2d.html?q=lines#%28def._%28%28lib._plot%2Fmain..rkt%29._lines%29%29

combining 2 lists in clojure

I'm trying to make a new list that is made up of 2 pre-existing lists. Basically, if a is a list and b is a list, I want to make List c which is the elements of a followed by the elements of b. Any help is appreciated!
You are looking for concat function:
(concat a b)
For example:
(concat '(1 2) '(2 3 4))
:> (1 2 2 3 4)