In my answer at Clojure For Comprehension example I have a function that processes its own output:
(defn stream [seed]
(defn helper [slow]
(concat (map #(str (first slow) %) seed) (lazy-seq (helper (rest slow)))))
(declare delayed)
(let [slow (cons "" (lazy-seq delayed))]
(def delayed (helper slow))
delayed))
(take 25 (stream ["a" "b" "c"]))
("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac"
"aba" "abb" "abc" "aca" "acb" "acc" "baa" "bab" "bac" "bba")
It works by creating a forward reference (delayed) which is used as the second entry in a lazy sequence (slow). That sequence is passed to the function, which is lazy, and the output from that function (the very first part of the lazy sequence, which does not require the evaluation of delayed) is then used to set the value of delayed.
In this way I "tie the knot". But this is done much more elegantly in Haskell (eg. Explanation of “tying the knot”). Given that Clojure has delay and force, I wondered if there was a better way to do the above?
The question then: can the (ugly, explicit) mutation (of delayed) somehow be avoided in the code above? Obviously(?) you still need mutation, but can it be hidden by "lazy" constructs?
[I had a question last night with a similar title when I was still trying to understand how to do this; no one replied before the code above worked, so I deleted it, but I am not really happy with this approach so am trying again.]
See also: Must Clojure circular data structures involve constructs like ref? (kinda frustrating that people are duplicating questions).
I'm not sure I can answer the question for the general case, but this function seems to solve the particular case.
(defn stream
[seed]
(let [step (fn [prev] (for [p prev s seed] (str p s)))]
(for [x (iterate step seed) y x] y)))
Although I ran into a out of memory exception for a large (dorun (take ...)). So there probably is an issue with this function.
Related
I'm new to Clojure and I'm wondering how I remove an element from a collection.
Say I have:
(def example ["a" "b" "c"])
I want to be able to remove say "b" and when I call
(println example)
and have it return a collection with only "a" and "c"
I know using (remove (partial = "b") example)
will return what I want but then how do i update the example variable with this?
Thanks!
(filter (fn [x] (not (= x "b"))) example)
Will get you '("a" "c"). Couple of points:
You shouldn't be thinking in terms of mutation. The whole point of using functional programming in general and clojure with it's persistent data structures in particular is to avoid the problems associated with mutability.
If you do really, really need something to be mutable you can use atoms, but if you're not sure you need it to be mutable, you don't.
First, check if you really need mutation in the first place. Clojure is designed around working with immutable data - there's a chance that what you ultimately want to do can be achieved without changing values in place.
If you need mutable data, you can create an atom for that - changing a car's value is generally a bad practice.
(def example (atom ["a" "b" "c"]))
(println #example) ;; ["a" "b" "c"]
(swap! example #(remove (partial = "b") %))
(println #example) ;; ["a" "c"]
Clojure's default data structures are immutable. Hence you cannot change a vector in place, but you can create a new one with the desired elements.
In a function context, this is how you could use remove:
(defn my-func [col]
(let [without-b (remove #(= "b" %) col)]
(println without-b)
; do something else w/ without-b
))
...
=> (my-func ["a" "b" "c"])
(a c)
This is the idiomatic Clojure way to work with collections, i.e., you create a new collection from an old one. This doesn't have "significant" memory or performance implications, as the data structures are implemented on a tree-based data structure, Tries, you can learn more about this here:
https://hypirion.com/musings/understanding-persistent-vector-pt-1
I am calculate k out of n combination from a length n list. I found the python code is very concise, so I did a direct translation.
def comb(sofar, rest, n):
if n == 0:
print sofar
else:
for i in range(len(rest)):
comb(sofar + rest[i], rest[i+1:], n-1)
comb("", "abcde", 3)
yield:
abc, abd, abe etc...
Is going to be translated to clojure code:
(defn comb [sofar v n]
(if (= n 0)
(print sofar)
(for [i (range 0 (count v))]
(comb (str sofar (nth v i)) ;don't it need to be recur ?
(subvec v (inc i))
(dec i)))))
nested loop/recursion is quite confusing.
Problem is how to change code to do the same function as python code?
my clojure code doesn't seem to do the same work.
Firstly, if you want a clojure solution, think in clojure terms, write functions over sequences that generate results in lazy sequences, and let the end consumer reduce those to strings if needed. In the following, I don't use print at all, just return lazy sequences, and let the repl be the printer.
Also, you're trying to translate a python for directly into a clojure for to do looping, which isn't what it's for (no pun intended). clojure's for is a sequence generator, so you're probably getting confused there.
To get a simple solution to your problem you can use math.combinatorics:
user=> (require '[clojure.math.combinatorics :as m])
user=> (m/combinations "abcde" 3)
((\a \b \c) (\a \b \d) (\a \b \e) (\a \c \d) (\a \c \e) (\a \d \e) (\b \c \d) (\b \c \e) (\b \d \e) (\c \d \e))
You can then write a map to convert this to strings for same output as python if needed.
user=> (map #(apply str %1) (m/combinations "abcde" 3))
("abc" "abd" "abe" "acd" "ace" "ade" "bcd" "bce" "bde" "cde")
However, I suspect you're looking for more of a tutorial on doing looping.
There's another solution to this problem here for creating a function to return the sequence as chars, which produces the same sequence as the above example and can be wrapped in a map for string output too. That uses recursion with a cond block to control the end of the iteration.
Here is another good article on doing same combinations with explanation on how it works with recursion by deconstructing the problem into something that is recursive in nature.
If you want more information on recur vs imperative loop, look no further than this SO question.
And here is a gist with some examples of loop/recur vs recursion for factorials so you can directly see the syntax style between the two.
In terms of getting used to writing functions that generate sequences like this, I find The Little Schemer is an excellent resource at explaining the thinking process. It's written in scheme, but is quite easy to understand and apply to clojure. After this, you can then look at higher order functions (map/reduce) rather than using loop.
All in all, when doing this, if you use lazy functions everywhere, your result will generally be lazy, and you want to try and use tail-recursion if you do recurse so that you don't blow the stack when using large combination, and dumping values you're not interested in.
While working in the repl is there a way to specify the maximum times to recur before the repl will automatically end the evaluation of an expression. As an example, suppose the following function:
(defn looping []
(loop [n 1]
(recur (inc n))))
(looping)
Is there a way to instruct the repl to give up after 100 levels of recursion? Something similar to print-level.
I respectfully hope that I'm not ignoring the spirit of your question, but why not simply use a when expression? It's nice and succinct and wouldn't change the body of your function much at all (1 extra line and a closing paren).
Whilst I don't believe what you want exists, it would be trivial to implement your own:
(def ^:dynamic *recur-limit* 100)
(defn looping []
(loop [n 1]
(when (< n *recur-limit*)
(recur (inc n)))))
Presumably this hasn't been added to the language because it's easy to construct what you need with the existing language primitives; apart from that, if the facility did exist but was 'invisible', it could cause an awful lot of confusion and bugs because code wouldn't always behave in a predictable and referentially transparent manner.
The classic book The Little Lisper (The Little Schemer) is founded on two big ideas
You can solve most problems in a recursive way (instead of using loops) (assuming you have Tail Call Optimisation)
Lisp is great because it is easy to implement in itself.
Now one might think this holds true for all Lispy languages (including Clojure). The trouble is, the book is an artefact of its time (1989), probably before Functional Programming with Higher Order Functions (HOFs) was what we have today.(Or was at least considered palatable for undergraduates).
The benefit of recursion (at least in part) is the ease of traversal of nested data structures like ('a 'b ('c ('d 'e))).
For example:
(def leftmost
(fn [l]
(println "(leftmost " l)
(println (non-atom? l))
(cond
(null? l) '()
(non-atom? (first l)) (leftmost (first l))
true (first l))))
Now with Functional Zippers - we have a non-recursive approach to traversing nested data structures, and can traverse them as we would any lazy data structure. For example:
(defn map-zipper [m]
(zip/zipper
(fn [x] (or (map? x) (map? (nth x 1))))
(fn [x] (seq (if (map? x) x (nth x 1))))
(fn [x children]
(if (map? x)
(into {} children)
(assoc x 1 (into {} children))))
m))
(def m {:a 3 :b {:x true :y false} :c 4})
(-> (map-zipper m) zip/down zip/right zip/node)
;;=> [:b {:y false, :x true}]
Now it seems you can solve any nested list traversal problem with either:
a zipper as above, or
a zipper that walks the structure and returns a set of keys that will let you modify the structure using assoc.
Assumptions:
I'm assuming of course data structures that fixed-size, and fully known prior to traversal
I'm excluding the streaming data source scenario.
My question is: Is recursion a smell (in idiomatic Clojure) because of of zippers and HOFs?
I would say that, yes, if you are doing manual recursion you should at least reconsider whether you need to. But I wouldn't say that zippers have anything to do with this. My experience with zippers has been that they are of theoretical use, and are very exciting to Clojure newcomers, but of little practical value once you get the hang of things, because the situations in which they are useful are vanishingly rare.
It's really because of higher-order functions that have already implemented the common recursive patterns for you that manual recursion is uncommon. However, it's certainly not the case that you should never use manual recursion: it's just a warning sign, suggesting you might be able to do something else. I can't even recall a situation in my four years of using Clojure that I've actually needed a zipper, but I end up using recursion fairly often.
Clojure idioms discourage explicit recursion because the call stack is limited: usually to about 10K deep. Amending the first of Halloway & Bedra's Six Rules of Clojure Functional Programming (Programming Clojure (p 89)),
Avoid unbounded recursion. The JVM cannot optimize recursive calls and
Clojure programs that recurse without bound will blow their stack.
There are a couple of palliatives:
recur deals with tail recursion.
Lazy sequences can turn a deep call stack into a shallow call stack
across an unfolding data structure. Many HOFs in the sequence
library, such as map and filter, do this.
I am learning scheme and one of the things I have to do is recursion to figure out if the list is reflective, i.e. the list looks the same when it is reversed. I have to do it primitively so I can't use the reverse method for lists. I must also use recursion which is obvious. The problem is in scheme it's very hard to access the list or shorten the list using the very basic stuff that we have learned, since these are kinda of like linkedlists. I also want to do without using indexing.
With that said I have a few ideas and was wondering If any of these sufficient and do you think I could actually do it better with the basics of scheme.
Reverse the list using recursion (my implementation) and compare the original and this rev. list.
Compare the first and last element by recursing on the rest of the list to find the last element and compare to first. Keeping track of how many times I have recursed and then do it one less for the second last element of the list, to compare to the second element of the list. (This is very complicated to do as I've tried it and wound up failing but I want to see you guys would've done the same)
Shorten the list to trim off the first and last element each time and compare. I'm not sure if this can be done using the basics of scheme.
Your suggestions or hints or anything. I'm very new to scheme. Thanks for reading. I know it's long.
Checking if a list is a palindrome without reversing it is one of the examples of a technique explained in "There and Back Again" by Danvy and Goldberg. They do it in (ceil (/ (length lst) 2)) recursive calls, but there's a simpler version that does it in (length lst) calls.
Here's the skeleton of the solution:
(define (pal? orig-lst)
;; pal* : list -> list/#f
;; If lst contains the first N elements of orig-lst in reverse order,
;; where N = (length lst), returns the Nth tail of orig-lst.
;; Otherwise, returns #f to indicate orig-lst cannot be a palindrome.
(define (pal* lst)
....)
.... (pal* orig-lst) ....)
This sounds like it might be homework, so I don't want to fill in all of the blanks.
I agree that #1 seems the way to go here. It's simple, and I can't imagine it failing. Maybe I don't have a strong enough imagination. :)
The other options you're considering seem awkward because we're talking about linked lists, which directly support sequential access but not random access. As you note, "indexing" into a linked list is verboten. It ends up marching dutifully down the list structure. Because of this, the other options are certainly doable, but they are expensive.
That expense isn't because we're in Scheme: it's because we're dealing with linked lists. Just to make sure it's clear: Scheme has vectors (arrays) which do support fast random-access. Testing palindrome-ness on a vector is as easy as you'd expect:
#lang racket
;; In Professional-level Racket
(define (palindrome? vec)
(for/and ([i (in-range 0 (vector-length vec))]
[j (in-range (sub1 (vector-length vec)) -1 -1)])
(equal? (vector-ref vec i)
(vector-ref vec j))))
;; Examples
(palindrome? (vector "b" "a" "n" "a" "n" "a"))
(palindrome? (vector "a" "b" "b" "a"))
so one point of the problem you're tackling, I think, is to show that the data structure you choose---the representation of the problem---can have a strong effect on the problem solution.
(Aside: #2 is certainly doable, though it goes against the grain of the single-linked list data structure. The approach to #3 requires a radical change to the representation: from a first glance, I think you'd need mutable, double-linked lists to do the solution any justice, since you need to be able march backward.)
To answer dyoo's question, you don't have to know that you're at the halfway point; you just have to make a certain comparison. If that comparison works, then a) the string must be reversible and b) you must be at the midway point.
So that more efficient solution is there, if you can just reach for it...