I think the way to understand what's going on is to realize that laziness
(coming from map) creates extra thunks, for each iteration, you're creating
an extra stack frame to dereference the elements of the lazy seq.

(defmacro lazy-seq
  "Takes a body of expressions that returns an ISeq or nil, and yields
  a Seqable object that will invoke the body only the first time seq
  is called, and will cache the result and return it on all subsequent
  seq calls. See also - realized?"
  {:added "1.0"}
  [& body]
  (list 'new 'clojure.lang.LazySeq (list* '^{:once true} fn* [] body)))

So, if your maps get numerous and layered enough, it's no longer possible
to deref values from them.

I've created a simple example that demonstrates this.
user> (defn my-map
  [n]
  (first (loop [out [1] counter n]
           (if (<= counter 0)
             out
             (recur (map identity out) (dec counter))))))
#'user/my-map
user>  (my-map 1)
1
user>  (my-map 10)
1
user>  (my-map 100)
1
user>  (my-map 1000)
1
user>  (my-map 10000)
StackOverflowError   clojure.core/seq (core.clj:133)
user> (pst *e)
StackOverflowError
clojure.core/seq (core.clj:133)
clojure.core/map/fn--4087 (core.clj:2426)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:473)
clojure.core/seq (core.clj:133)
clojure.core/map/fn--4087 (core.clj:2426)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:473)
clojure.core/seq (core.clj:133)
clojure.core/map/fn--4087 (core.clj:2426)
nil
user>




On Sat, Jun 22, 2013 at 1:10 PM, Gary Trakhman <gary.trakh...@gmail.com>wrote:

> Do you have the stack trace? It's not simple to run the code, but I made a
> github project so we can look at it easier.
> https://github.com/gtrak/grad-descent-test
>
> When I run (gradient-descent example-grad [0 1] 0.001 0.001)
>
> Here's the actual problem:
> grad-descent.core> (pst *e)
> StackOverflowError
>  clojure.lang.LazySeq.seq (LazySeq.java:60)
> clojure.lang.RT.seq (RT.java:484)
> clojure.core/seq (core.clj:133)
>  clojure.core/map/fn--4211 (core.clj:2490)
> clojure.lang.LazySeq.sval (LazySeq.java:42)
> clojure.lang.LazySeq.seq (LazySeq.java:60)
>  clojure.lang.RT.seq (RT.java:484)
> clojure.core/seq (core.clj:133)
> clojure.core/map/fn--4211 (core.clj:2490)
>  clojure.lang.LazySeq.sval (LazySeq.java:42)
> clojure.lang.LazySeq.seq (LazySeq.java:60)
> clojure.lang.RT.seq (RT.java:484)
>
> The actual problem is in the vec functions, switching them to mapv fixes
> it.
>
> grad-descent.core> (gradient-descent example-grad [0 1] 0.001 0.001)
> [0.0 0.018256499170212572]
>
>
>
> On Sat, Jun 22, 2013 at 12:12 PM, P Martin <prof.pmarti...@gmail.com>wrote:
>
>> Ah ok - so I may be using it wrong. I am not calling the function itself
>> - I was simply trying to bind local variables in a loop.
>>
>> I have placed the code into gists for easier reading!
>>
>> https://gist.github.com/anonymous/5841405#file-core-clj
>> https://gist.github.com/anonymous/5841420#file-vec-clj
>>
>> Is there another way to mimic procedural type looping?
>>
>> On Saturday, June 22, 2013 2:39:01 AM UTC-4, Cedric Greevey wrote:
>>
>>> An algorithm like that generating StackOverflowErrors suggests it's
>>> recursing deeply, which suggests you're not using recur *enough*. If the
>>> function calls itself, try to see if you can get that call into tail
>>> position and change it to "recur".
>>>
>>>
>>> On Fri, Jun 21, 2013 at 4:06 PM, P Martin <prof.pm...@gmail.com> wrote:
>>>
>>>> Hi,
>>>>
>>>> I am new to clojure and I am trying to reimplement some optimization
>>>> code that uses gradient descent. I have attached the source to this post.
>>>> My experience with gradient descent is in Matlab, which is procedural.
>>>>
>>>> When I run my function gradient-descent I supply step sizes and error
>>>> values of 0.01, it runs correctly and gives me good results. However, if I
>>>> decrease the error value below 0.001 it produces a stack overflow error. I
>>>> get the same error if my step value goes down to 0.001.
>>>>
>>>> Is my looping mechanism correct and I am just having numerical
>>>> limitations? Am I abusing loop/recur? Any suggestions/critiques would be
>>>> great!
>>>>
>>>> Thanks,
>>>> Patrick
>>>>
>>>> --
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com
>>>>
>>>> Note that posts from new members are moderated - please be patient with
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@**googlegroups.com
>>>>
>>>> For more options, visit this group at
>>>> http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to clojure+u...@**googlegroups.com.
>>>>
>>>> For more options, visit 
>>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>>>> .
>>>>
>>>>
>>>>
>>>
>>>  --
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>>
>>
>
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to