refs implement IFn, atoms and agents do not?

4 views
Skip to first unread message

Stuart Halloway

unread,
Oct 3, 2009, 1:50:04 PM10/3/09
to clo...@googlegroups.com
Is there a principled reason for this? I have written some code that
(unintentionally) limits itself to refs because it assumes that all
reference types can sit in function position.

Thanks,
Stu

Stephen C. Gilardi

unread,
Oct 4, 2009, 4:07:48 PM10/4/09
to clo...@googlegroups.com

This discussion:

http://groups.google.com/group/clojure/browse_thread/thread/534dd074f18851ab

suggests that reference types implementing IFn isn't the intended
behavior.

Using deref or @ works with all reference types:

user> (defn my-fn [x] (+ x 3))
#'user/my-fn
user> (def my-agent (agent my-fn))
#'user/my-agent
user> (@my-agent 4)
7

--Steve

Mark Volkmann

unread,
Oct 4, 2009, 5:04:21 PM10/4/09
to clo...@googlegroups.com
On Sun, Oct 4, 2009 at 3:07 PM, Stephen C. Gilardi <sque...@mac.com> wrote:
>
> On Oct 3, 2009, at 1:50 PM, Stuart Halloway wrote:
>
>> Is there a principled reason for this? I have written some code that
>> (unintentionally) limits itself to refs because it assumes that all
>> reference types can sit in function position.
>
> This discussion:
>
> http://groups.google.com/group/clojure/browse_thread/thread/534dd074f18851ab
>
> suggests that reference types implementing IFn isn't the intended behavior.
>
> Using deref or @ works with all reference types:

Minor technicality ... Vars are a reference type, but deref and @
don't work with them.

--
R. Mark Volkmann
Object Computing, Inc.

Stephen C. Gilardi

unread,
Oct 4, 2009, 5:26:25 PM10/4/09
to clo...@googlegroups.com

On Oct 4, 2009, at 5:04 PM, Mark Volkmann wrote:

> Minor technicality ... Vars are a reference type, but deref and @
> don't work with them.

I'm guessing you're thinking of an interaction like this:

user=> (def a 3)
#'user/a
user=> @a
java.lang.ClassCastException: java.lang.Integer cannot be cast to
clojure.lang.IDeref (NO_SOURCE_FILE:0)
user=>

However, it's important to remember that the expression "a" does not
evaluate to the Var named "a". The Var named by "a" can be accessed
via (var a) or #'a.

deref does work with Vars:

user=> @(var a)
3
user=> @#'a
3
user=>

deref works with objects that implement clojure.lang.IDeref and
clojure.lang.Var is among them:

user=> (isa? clojure.lang.Var clojure.lang.IDeref)
true
user=>

--Steve

Mark Volkmann

unread,
Oct 4, 2009, 5:36:16 PM10/4/09
to clo...@googlegroups.com
On Sun, Oct 4, 2009 at 4:26 PM, Stephen C. Gilardi <sque...@mac.com> wrote:
>
> On Oct 4, 2009, at 5:04 PM, Mark Volkmann wrote:
>
>> Minor technicality ... Vars are a reference type, but deref and @ don't
>> work with them.
>
> I'm guessing you're thinking of an interaction like this:
>
>        user=> (def a 3)
>        #'user/a
>        user=> @a
>        java.lang.ClassCastException: java.lang.Integer cannot be cast to
> clojure.lang.IDeref (NO_SOURCE_FILE:0)

Yes, that's what I was thinking about.

> However, it's important to remember that the expression "a" does not
> evaluate to the Var named "a". The Var named by "a" can be accessed via (var
> a) or #'a.
>
> deref does work with Vars:
>
>        user=> @(var a)
>        3
>        user=> @#'a
>        3
>        user=>
>
> deref works with objects that implement clojure.lang.IDeref and
> clojure.lang.Var is among them:
>
>        user=> (isa? clojure.lang.Var clojure.lang.IDeref)
>        true
>        user=>

Thanks for clarifying that!

Reply all
Reply to author
Forward
0 new messages