It seems to me there is a way to make the JVM's stack effectively
deeper -- even limited only by available memory.

Threads have separate stacks, and there's no limit on threads,
*especially* if they're nearly all sleeping. So ...

(defn apply-with-stack-extension [f & args]
  (let [x (future
            (try
              [(apply f args) nil]
              (catch Throwable t [nil t])))
       [res exc] @x]
    (if exc (throw exc) res)))

In theory (untested as yet) this should act like "apply", except that
almost the full maximum stack depth is available to f, no matter how
far the stack has piled up with apply-with-stack-extension. As a side
effect, if an exception is thrown its stack trace starts after the
last apply-with-stack-extension; everything before that is cut off.
That may be more of a mixed blessing than a curse. :)

In practice, something like this (plus tracking nesting depth to
trigger it every 100 or so stack frames) could be used to make the
lazy-stuff framework much more resistant to SOE throws. Another
variation is to have an SOE handler in many common lazy functions,
like map, that catches SOE and retries using
apply-with-stack-extension, or using a version of the function that
applies it periodically. That might reduce the performance impact to
nearly nil for cases that don't have a problem with SOE without
a-w-s-e.

-- 
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

Reply via email to