I am using Common Lisp Series package ( https://series.sourceforge.net/ ) to work on Advent Of Code.
(series::defun find-14-character-marker (stream)
(declare (optimizable-series-function))
(declare (off-line-port stream))
(->> (mapping (((a b c d e f g h i j k l m n) (chunk 14 1 stream)))
(char/= a b c d e f g h i j k l m n))
(until-if #'identity)
(collect-length)))
Is it possible to map chunks using map-fn function instead of mapping?
I could do something like this:
(lambda (&rest xs)
(apply #'char/= xs))
without having to type all 14 parameters. I tried using map-fn but my lambda function was invoked with only one parameter.
chunk returns its series as multiple values, while map-fn requires each of its argument series as individual arguments. Therefore, (multiple-value-call #'map-fn 'boolean #'char= (chunk 14 1 stream)) is the form you're looking for, as it will pass each of the multiple series returned by chunk as an argument to map-fn. (the #'char= is used in place of the lambda given in the question, as it is equivalent).
By default, when a form which evaluates to multiple values is used as an argument to a function, all values but the first are discarded, which is probably why your original attempt to use map-fn failed. multiple-value-call instead passes each of the multiple values of the form as individual arguments, which is what you want here.
Related
This question already has answers here:
I'm trying to figure out how to incorporate 3 variables into my tail recursion code for racket
(2 answers)
Closed 3 years ago.
Here's the question:
Write a tail recursive function that takes as input two non-negative integers P and k and outputs a list of the first 10 years of a population that has initial population P and multiplies the population by k every year. Your function can have helper variables if you want.
I was trying to get code to form a list with ten numbers. I assumed that the input for number would be 10. I tried to go in the direction of making the base case empty instead of 0. Does anyone have any advice on how to fix this code or to make it better?
(define (pop2 P k number)
(cond
[(= number 0) '()]
[else
(append (pop2 k (* P k)(- number 1)(list P)))]))
A recursive function definition is tail-recursive if nothing needs to be done after recursive call(s). But pop2 has append around the recursive call! To make sure that the function returns exactly what the recursive call returns, that keeps track of the result using an extra parameter to the function (an accumulator).
In the recursive call, the arguments don't match up with their corresponding meaning, and there is an extra arg too:
(pop2 k (* P k) (- number 1) (list P))
(pop2 P k number ???)
Here's something that can get you started:
;; pop2-acc : Nat Nat Nat [Listof Nat] -> [Listof Nat]
(define (pop2-acc P k number acc)
(cond
[(= number 0) <???>]
[else (pop2-acc P k (- number 1) <???>)]))
;; pop2 : Nat Nat Nat -> [Listof Nat]
;; initial-population (P), factor (k), years (number)
(define (pop2 P k number)
(pop2-acc P k number acc))
Note that acc is "the result so far." The helper pop2-acc could be turned into a local function within pop2, and we wouldn't have to pass in k into pop2-acc (because it stays the same).
I need to remove the last two elements from a list in common list, but I can remove only one. What's the way?
(defun my-butlast (list)
(loop for l on list
while (rest l)
collect (first l)))
Simple: reverse, pop, pop, reverse ;-) 1
More efficiently, the following works too:
(let ((list '(a b c d)))
(loop
for x in list
for y in (cddr list)
collect x))
This can also be written, for some arbitrary L and N:
(mapcar #'values L (nthcdr N L))
It works because iteration over multiple lists is bounded by the shortest one. What matters here is the length of the second list (we don't care about its values), which is the length of the original list minus N, which must be a non-negative integer. Notice that NTHCDR conveniently works with sizes greater than the length of the list given in argument.
With the second example, I use the VALUES function as a generalized identity function; MAPCAR only uses the primary value of the computed values, so this works as desired.
The behavior is consistent with the actual BUTLAST2 function, which returns nil for N larger than the number of elements in the list. The actual BUTLAST function can also deal with improper (dotted) lists, but the above version cannot.
1. (alexandria:compose #'nreverse #'cddr #'reverse)
2. BUTLAST is specified as being equivalent to (ldiff list (last list n)). I completely forgot about the existence of LDIFF !
There's a function in the standard for this: butlast, or if you're willing to modify the input list, nbutlast.
butlast returns a copy of list from which the last n conses have been omitted. If n is not supplied, its value is 1. If there are fewer than n conses in list, nil is returned and, in the case of nbutlast, list is not modified.
nbutlast is like butlast, but nbutlast may modify list. It changes the cdr of the cons n+1 from the end of the list to nil.
Examples:
CL-USER> (butlast '(1 2 3 4 5) 2)
(1 2 3)
CL-USER> (nbutlast (list 6 7 8 9 10) 2)
(6 7 8)
The fact that you called your function my-butlast suggests that you might know about this function, but you didn't mention wanting to not use this function, so I assume it's still fair game. Wrapping it up is easy:
CL-USER> (defun my-butlast (list)
(butlast list 2))
MY-BUTLAST
CL-USER> (my-butlast (list 1 2 3 4))
(1 2)
I've been thinking about the following problem. Suppose I'm dealing with a function returning multiple values, such as truncate. Is there a clever way to reverse the order of values that get returned? I'm talking about something more clever than e.g.
(multiple-value-bind (div rem) (truncate x y)
(values rem div))
I don't know how clever this is, but here's what you want:
(reverse (multiple-value-list (the-function-that-returns-multiple-values)))
multiple-value-list being the key, here.
To return these again as separate values, use values-list:
(values-list (reverse (multiple-value-list (the-function-that-returns-multiple-values))))
This whole page may be enlightening.
This problem can be solved more cleverly by writing a higher order function whose input is a function that returns some (values a b), and which returns a function which calls that function, but returns (values b a). In other words a value reversing combinator:
(defun val-rev (function)
(lambda (&rest args)
(multiple-value-bind (a b) (apply function args)
(values b a))))
Though inside the definition of this function we are doing the cumbersome thing you don't want (capturing the values with m-v-bind and reversing with values) this is encapsulated in the combinator and just an implementation detail. It's probably more efficient than consing up a value list and reversing it. Also, it specifically targets the first two values. If a function returns four values, A B C D, then reversing the multiple-value-list means that the first two return values will be C D. However, if we just bind the first two and reverse them, then we bet B A. Reversing the first two (or only two) values is clearly not the same as reversing all values.
Demo:
[1]> (truncate 17 3)
5 ;
2
[2]> (funcall (val-rev #'truncate) 17 3)
2 ;
5
Note that in a Lisp-1 dialect, the invocation loses the added noise of #' and funcall, reducing simply to: ((val-rev truncate) 17 3).
val-rev is kind of a dual of the flip higher order function which you see in some functional languages, which takes a binary function and returns a binary function which is that function, but with the arguments reversed.
To have it as clean/consistent as multiple-value-bind, you could define a macro such as this:
(defmacro reverse-multiple-value-bind (args f &rest body)
`(multiple-value-bind ,(reverse args)
,f
,#body))
Then you have
>> (multiple-value-bind (x y) (floor 3.7) (print x) (print y))
3
0.70000005
and
> (reverse-multiple-value-bind (x y) (floor 3.7) (print x) (print y))
0.70000005
3
If I understand correctly Clojure can return lists (as in other Lisps) but also vectors and sets.
What I don't really get is why there's not always a collection that is returned.
For example if I take the following code:
(loop [x 128]
(when (> x 1)
(println x)
(recur (/ x 2))))
It does print 128 64 32 16 8 4 2. But that's only because println is called and println has the side-effect (?) of printing something.
So I tried replacing it with this (removing the println):
(loop [x 128]
(when (> x 1)
x
(recur (/ x 2))))
And I was expecting to get some collecting (supposedly a list), like this:
(128 64 32 16 8 4 2)
but instead I'm getting nil.
I don't understand which determines what creates a collection and what doesn't and how you switch from one to the other. Also, seen that Clojure somehow encourages a "functional" way of programming, aren't you supposed to nearly always return collections?
Why are so many functions that apparently do not return any collection? And what would be an idiomatic way to make these return collections?
For example, how would I solve the above problem by first constructing a collection and then iterating (?) in an idiomatic way other the resulting list/vector?
First I don't know how to transform the loop so that it produces something else than nil and then I tried the following:
(reduce println '(1 2 3))
But it prints "1 2nil 3nil" instead of the "1 2 3nil" I was expecting.
I realize this is basic stuff but I'm just starting and I'm obviously missing basic stuff here.
(P.S.: retag appropriately, I don't know which terms I should use here)
A few other comments have pointed out that when doesn't really work like if - but I don't think that's really your question.
The loop and recur forms create an iteration - like a for loop in other languages. In this case, when you are printing, it is indeed just for the side effects. If you want to return a sequence, then you'll need to build one:
(loop [x 128
acc []]
(if (< x 1)
acc
(recur (/ x 2)
(cons x acc))))
=> (1 2 4 8 16 32 64 128)
In this case, I replaced the spot where you were calling printf with a recur and a form that adds x to the front of that accumulator. In the case that x is less than 1, the code returns the accumulator - and thus a sequence. If you want to add to the end of the vector instead of the front, change it to conj:
(loop [x 128
acc []]
(if (< x 1)
acc
(recur (/ x 2)
(conj acc x))))
=> [128 64 32 16 8 4 2 1]
You were getting nil because that was the result of your expression -- what the final println returned.
Does all this make sense?
reduce is not quite the same thing -- it is used to reduce a list by repeatedly applying a binary function (a function that takes 2 arguments) to either an initial value and the first element of a sequence, or the first two elements of the sequence for the first iteration, then subsequent iterations are passed the result of the previous iteration and the next value from the sequence. Some examples may help:
(reduce + [1 2 3 4])
10
This executes the following:
(+ 1 2) => 3
(+ 3 3) => 6
(+ 6 4) => 10
Reduce will result in whatever the final result is from the binary function being executed -- in this case we're reducing the numbers in the sequence into the sum of all the elements.
You can also supply an initial value:
(reduce + 5 [1 2 3 4])
15
Which executes the following:
(+ 5 1) => 6
(+ 6 2) => 8
(+ 8 3) => 11
(+ 11 4) => 15
HTH,
Kyle
The generalized abstraction over collection is called a sequence in Clojure and many data structure implement this abstraction so that you can use all sequence related operations on those data structure without thinking about which data structure is being passed to your function(s).
As far as the sample code is concerned - the loop, recur is for recursion - so basically any problem that you want to solve using recursion can be solved using it, classic example being factorial. Although you can create a vector/list using loop - by using the accumulator as a vector and keep appending items to it and in the exist condition of recursion returning the accumulated vector - but you can use reductions and take-while functions to do so as shown below. This will return a lazy sequence.
Ex:
(take-while #(> % 1) (reductions (fn [s _] (/ s 2)) 128 (range)))
Whilst learning Clojure, I've spent ages trying to make sense of monads - what they are and how we can use them.... with not too much success. However, I found an excellent 'Monads for Dummies' Video Series - http://vimeo.com/20717301 - by Brian Marik for Clojure
So far, my understanding of monads is that it is sort of like a macro in that it allows a set of statements to be written in a form that is easy to read - but monads are much more formalised. My observations are limited to two examples:
1. The Identity Monad (or the 'let' monad) taken from http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/
The form that we wish to write is:
(let [a 1
b (inc a)]
(* a b))
and the corresponding monad is
(domonad identity-m
[a 1
b (inc a)]
(* a b))
2. The Sequence Monad (or the 'for' monad) taken from http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-2/
The form we wish to write is:
(for [a (range 5)
b (range a)]
(* a b))
and the corresponding monad is
(domonad sequence-m
[a (range 5)
b (range a)]
(* a b))
Monad Definitions in Clojure
Looking at the source, using clojure monads library - https://github.com/clojure/algo.monads:
user=>(use 'clojure.algo.monads)
nil
indentity monad:
user=> (source identity-m)
(defmonad identity-m
[m-result identity
m-bind (fn m-result-id [mv f]
(f mv))
])
sequence monad:
user=> (source sequence-m)
(defmonad sequence-m
[m-result (fn m-result-sequence [v]
(list v))
m-bind (fn m-bind-sequence [mv f]
(flatten* (map f mv)))
m-zero (list)
m-plus (fn m-plus-sequence [& mvs]
(flatten* mvs))
])
So my conclusion is that a monad is some sort of a generalised higher-order function that takes in an input-function and input-values, adds its own control logic and spits out a 'thing' that can be used in a 'domonad' block.
Question 1
So finally, to the questions: I want to learn how to write a monad and say I want to write a 'map monad' that imitates the 'map' form in clojure:
(domonad map-m
[a [1 2 3 4 5]
b [5 6 7 8 9]]
(+ a b))
Should be equivalent to
(map + [1 2 3 4 5] [5 6 7 8 9])
and return the values
[6 8 10 12 14]
If I look at the source, it should give me something similar to identity-m and sequence-m:
user=> (source map-m)
(defmonad map-m
[m-result ...
m-bind ...
m-zero ...
m-plus ...
])
Question 2
I also want to be able to define 'reduce-m' such that I can write:
(domonad reduce-m
[a [1 2 3 4 5]]
(* a))
this could potentially give me 1 x 2 x 3 x 4 x 5 = 120 or
(domonad reduce-m
[a [1 2 3 4 5]
b [1 2 3 4 5]]
(+ a b))
will give me (1+2+3+4+5) + (1+2+3+4+5) = 30
Finally
Would I also be able to write a 'juxt monad' that imitates the juxt function but instead of passing in values for binding, I pass in a set of functions. :
(domonad juxt-m
[a #(+ % 1)
b #(* % 2)]
'([1 2 3 4 5] b a) )
gives
[ [2 2] [4 3] [6 4] [8 5] [9 6] ]
Potentially, I could do all of those things with macros so I don't really know how useful these 'monads' will be or if they are even considered 'monads'... With all the resources on the internet, It seems to me that if I wanted to learn Monads properly, I have to learn Haskell and right now, learning another syntactic form is just too hard. I think I found some links that maybe relevant but it is too cryptic for me
Please can someone shed some light!
Your examples are not monads. A monad represents composable computational steps. In the trivial identity monad, the computational step is just an expression evaluation.
In the maybe monad, a step is an expression that may succeed or fail.
In the sequence monad, a step is an expression that produces a variable number of results (the elements of the sequence).
In the writer monad, a computational step is a combination of expression evaluation and log output. In the state monad, a computational step involves accessing and/or modifying a piece of mutable state.
In all these cases, the monad plumbery takes care of correctly combining steps. The m-result function packages a "plain" value to fit into the monadic computation scheme, and the m-bind function feeds the result of one computational step into the next computational step.
In (map + a b), there are no computational steps to be combined. There is no notion of order. It's just nested expression evaluation. Same for reduce.
Your questions are not a type of monads. They seems more like a syntactic sugar and that you can accomplish using macros and I won't even suggest you do that because map, reduce etc are simple functions and there is no need to make their interface complex.
The reason these cases are not monads because moands are sort of amplified values which wrap normal values. In map and reduce case the vector that you use doesn't needs to be amplified to allow it to work in map or reduce.
It would be helpful for you to try macroexpand on the domoand expressions.
For ex: the sequence monad example should expand to something like:
(bind (result (range 5))
(fn [a]
(bind (result (range a))
(fn [b] (* a b))
)))
Where the bind and result are functions defined in the sequence monad m-bind and m-result.
So basically the vector expression(s) after the domand get nested and the expression(s) after the vector are used as it is in above case the (* a b) is called as it is (just that the a and b values are provided by the monad). In your example of map monad the vector expressions are supposed to be as it is and the last expression (+ a b) should somehow mean (map + a b) which is not what a monad is supposed to do.
I found some really good monads resources:
http://www.clojure.net/tags.html#monads-ref (Jim Duey's Monads Guide, which really goes into the nitty gritty monad definitions)
http://homepages.inf.ed.ac.uk/wadler/topics/monads.html#marktoberdorf (A whole load of papers on monads)
http://vimeo.com/17207564 (A talk on category theory, which I half followed)
So from Jim's Guide - http://www.clojure.net/2012/02/06/Legalities/ - he gives three axioms for definition of 'bind-m' and 'reduce-m' functions:
Identity
The first Monad Law can be written as
(m-bind (m-result x) f) is equal to (f x)
What this means is that whatever m-result does to x to make it into a monadic value, m-bind undoes before applying f to x. So with regards to m-bind, m-result is sort of like an identity function. Or in category theory terminology, its unit. Which is why sometimes you’ll see it named ‘unit’.
Reverse Identity The second Monad Law can be written as
(m-bind mv m-result) is equal to mv where mv is a monadic value.
This law is something like a complement to the first law. It basically ensures that m-result is a monadic function and that whatever m-bind does to a monadic value to extract a value, m-result undoes to create a monadic value.
Associativity
The third Monad Law can be written as
(m-bind (m-bind mv f) g) is equal to (m-bind mv (fn [x] (m-bind (f x) g)))
where f and g are monadic functions and mv is a monadic value.
What this law is saying is that it doesnt matter whether the f is applied to mv and then g is applied to the result, or whether a new monadic function is created out of a composition of f and g which is then applied to mv. In either order, the resulting value is the same monadic value. Stated another way, m-bind is left and right associative.
In http://www.clojure.net/2012/02/04/Sets-not-lists/ he gives an monad that takes sets as inputs instead of taking lists. Will work through all the examples...