lazy maps in Clojure?

187 views
Skip to first unread message

Larry Travis

unread,
Jan 21, 2013, 1:27:26 AM1/21/13
to clo...@googlegroups.com, Larry Travis
One of the neat things about Clojure (maybe all functional languages) is
that functions can be defined either extensionally or intensionally. How
can one create a Clojure structure that mixes these two types of
definition?

That is, I would like to define a function f that saves its result the
first time it is called against any particular argument so that if and
when f is later called against the same argument, it does a look-up via
a hash map rather than repeating a possibly expensive computation. I
think I see how to do this with a ref to a mutable map (where, given an
argument k, f would first try to find (f k) in the map but, if k is not
currently a key of the map, the function would compute the value v = (f
k) and then, in addition to returning v, add the entry <k v> to the map
as a side effect. But this seems ugly. Is there some way to do what I
want here without making explicit use of refs?

Lazy-seqs don't give me what I want because the arguments to be given to
f don't occur in any kind of predictable sequence.

--Larry

AtKaaZ

unread,
Jan 21, 2013, 1:29:01 AM1/21/13
to clo...@googlegroups.com
memoize?




  --Larry

--
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+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en



--
I may be wrong or incomplete.
Please express any corrections / additions,
they are encouraged and appreciated.
At least one entity is bound to be transformed if you do ;)

Alex Baranosky

unread,
Jan 21, 2013, 1:38:01 AM1/21/13
to clo...@googlegroups.com
memoize, or delay maybe

Jozef Wagner

unread,
Jan 21, 2013, 2:55:01 AM1/21/13
to clo...@googlegroups.com
Or maybe https://bitbucket.org/kotarak/lazymap ?


On Monday, January 21, 2013 7:38:01 AM UTC+1, Alex Baranosky wrote:
memoize, or delay maybe

On Sun, Jan 20, 2013 at 10:29 PM, AtKaaZ <atk...@gmail.com> wrote:
memoize?


On Mon, Jan 21, 2013 at 7:27 AM, Larry Travis <tra...@cs.wisc.edu> wrote:
One of the neat things about Clojure (maybe all functional languages) is that functions can be defined either extensionally or intensionally. How can one create a Clojure structure that mixes these two types of definition?

That is, I would like to define a function f that saves its result the first time it is called against any particular argument so that if and when f is later called against the same argument, it does a look-up via a hash map rather than repeating a possibly expensive computation. I think I see how to do this with a ref to a mutable map (where, given an argument k, f would first try to find (f k) in the map but, if k is not currently a key of the map, the function would compute the value v = (f k) and then, in addition to returning v, add the entry <k v> to the map as a side effect. But this seems ugly. Is there some way to do what I want here without making explicit use of refs?

Lazy-seqs don't give me what I want because the arguments to be given to f don't occur in any kind of predictable sequence.


  --Larry

--
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
--
I may be wrong or incomplete.
Please express any corrections / additions,
they are encouraged and appreciated.
At least one entity is bound to be transformed if you do ;)

Larry Travis

unread,
Jan 21, 2013, 10:43:34 PM1/21/13
to clo...@googlegroups.com, Larry Travis
Thanks, all. Memoize appears to be exactly what I was looking for. Is there no end to discovering eminently useful capabilities hidden away some place in Clojure's API?

For the moment I don't see what Meikel Brandmeyer's lazymap gives me that memoize doesn't, but I will look into it.
  --Larry


On 1/21/13 1:55 AM, Jozef Wagner wrote:

Larry Travis

unread,
Feb 23, 2013, 5:50:10 PM2/23/13
to clo...@googlegroups.com, Larry Travis
In Clojure, if I have a function call that asks for return of a
function, for example

user> ((fn [a] (fn [b] (+ (inc a) (* b b)))) 5)

I get the function name

#<user$eval4164$fn__4165$fn__4166 user$eval4164$fn__4165$fn__4166@29770daa>

But what I would like to get is an expression that defines this
function, for example

(fn [b] (+ 6 (* b b)))

Is there some way that I can suppress the evaluation of this expression?

--Larry




Michael Klishin

unread,
Feb 23, 2013, 6:50:05 PM2/23/13
to clo...@googlegroups.com

2013/2/24 Larry Travis <tra...@cs.wisc.edu>

Is there some way that I can suppress the evaluation of this expression?

((fn [a]
  '(fn [b] (+ (inc a) (* b b)))) 5)

Larry Travis

unread,
Feb 23, 2013, 10:23:41 PM2/23/13
to clo...@googlegroups.com, Larry Travis
I am afraid I didn't ask my question clearly.


Michael's "solution" would give as output


(fn [b] (+ (inc a) (* b b)))



What I want as output is


(fn [b] (+ 6 (* b b)))


... where those expressions within the inner-lambda scope (of the original nested-lambda expression) that can be evaluated by the binding of the outer-lambda parameter -- that is, the expressions "a" and "(inc a)" -- have been fixed with their values, but what is then output is the resulting Clojure function definition determined by the unevaluatable remainder of the inner-lambda scope.

It occurs to me that whether what I am asking for is possible at all depends on how closures are realized within Clojure, but I think that there would be a way of realizing them in terms of source code rather than compiled code -- and that this source code wouldn't be compiled until values for their open variables become available.
  --Larry





On 2/23/13 5:50 PM, Michael Klishin wrote:

2013/2/24 Larry Travis <tra...@cs.wisc.edu>
Is there some way that I can suppress the evaluation of this expression?

((fn [a]
  '(fn [b] (+ (inc a) (* b b)))) 5)
--
MK


On 2/23/13 4:50 PM, Larry Travis wrote:
In Clojure, if I have a function call that asks for return of a function, for example

user> ((fn [a] (fn [b] (+ (inc a) (* b b)))) 5)

I get the function name

#<user$eval4164$fn__4165$fn__4166 user$eval4164$fn__4165$fn__4166@29770daa>

But what I would like to get is an expression that defines this function, for example

(fn [b] (+ 6 (* b b)))

Is there some way that I can suppress the evaluation of this expression?

  --Larry

AtKaaZ

unread,
Feb 24, 2013, 2:03:07 AM2/24/13
to clo...@googlegroups.com, Larry Travis
=> ((fn [a] (backtick/template (fn [b] (+ ~(inc a) (* b b))) ) ) 5)

(fn [b] (+ 6 (* b b)))

https://github.com/brandonbloom/backtick

=> (eval ((fn [a] (backtick/template (fn [b] (+ ~(inc a) (* b b))) ) ) 5))
#<funxions$eval3145$fn__3146 util.funxions$eval3145$fn__3146@4a7c5889>
=> ((eval ((fn [a] (backtick/template (fn [b] (+ ~(inc a) (* b b))) ) ) 5)) 2)
10
Reply all
Reply to author
Forward
0 new messages