Message from discussion
Introduce fields as part of reify?
Date: Thu, 15 Nov 2012 02:56:54 -0800 (PST)
From: Howard Lewis Ship <hls...@gmail.com>
To: clojure-dev@googlegroups.com
Message-Id: <a7f47451-54c8-4e47-b218-d28b13f776d2@googlegroups.com>
In-Reply-To: <CAPC9Oaf-cd+4UhZB07rtdJ6wRJHEjEXBnQEyA1vMxQCvH=EHAA@mail.gmail.com>
References: <dfeabca1-de54-47af-8f8b-1e37e44233c3@googlegroups.com>
<CAPC9Oaf-cd+4UhZB07rtdJ6wRJHEjEXBnQEyA1vMxQCvH=EHAA@mail.gmail.com>
Subject: Re: Introduce fields as part of reify?
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_1603_8744855.1352977014047"
------=_Part_1603_8744855.1352977014047
Content-Type: multipart/alternative;
boundary="----=_Part_1604_6371933.1352977014047"
------=_Part_1604_6371933.1352977014047
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
On Wednesday, 14 November 2012 22:31:49 UTC, David Nolen wrote:
>
> Why can't you just implement ILookup and the other relevant bits for
> map-like behavior if you need it?
That still doesn't get me closer to having a field of my reified instance
containing (a collection containing) the reified instance itself.
What I have now is more like:
(let [init-map (fn [context] {:me context})]
(reify
MyProtocol
(do-that-thing [this event] (handle-event (init-map this) event))))
... though in my application's code, the init-map function is a bit more
complicated.
I'd love to be able to avoid invoking init-map for each invocation of
do-that-thing, since the result if init-map is always an exactly equivalent
map.
I believe I now see what you meant about ILookup; I could implement ILookup
and intercept requests for the :me key, and delegate the rest to the other
map (in my simplified example, it looks like the context map has only one
key, but in the real app, there's a context map for the instance with a
number of key/value pairs already in it, to which I want to add a new
key/value pair to identify the reified instance). However, the code inside
handle-event needs that parameter to be a map to which new keys can be
assoc-ed.
>
>
> On Wednesday, November 14, 2012, Howard M. Lewis Ship wrote:
>
>> I'm in a situation where, if I was using Java code, I would introduce
>> final fields initialized in the constructor. Instead I'm using reify with
>> protocols, and hitting what I perceive to be a small limitation.
>>
>> Here's a simplified version of what I'm doing.
>>
>> (reify
>> MyProtocol
>> (do-that-thing [this event] (handle-event {:me this} event)))
>>
>> ... in my real code there's a lot of repetition concerning building that
>> context map; in addition, it has to be built all the time, when a single
>> instance could be created once and shared.
>>
>> To address this repetition, i'd like to have some syntax for initializing
>> fields of the reified class, perhaps:
>>
>> (reify
>> [context-map {:me this}]
>>
>> MyProtocol
>> (do-that-thing [this event] (handle-event context-map event)))
>>
>> In other words, a let-style block of field assignments that are
>> implicitly part of the generated class' constructor, and with values that
>> are in lexical scope of the protocol function implementations.
>>
>> I think this is a reasonable thing to want to do ... as is, I have
>> several protocol methods that all want to extend a context map with a
>> reference back to this reified instance and I don't like the duplication.
>>
>> Thoughts?
>>
>>
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Clojure Dev" group.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msg/clojure-dev/-/oKnRndNNAnQJ.
>> To post to this group, send email to clojure-dev@googlegroups.com.
>> To unsubscribe from this group, send email to
>> clojure-dev+unsubscribe@googlegroups.com.
>> For more options, visit this group at
>> http://groups.google.com/group/clojure-dev?hl=en.
>>
>
------=_Part_1604_6371933.1352977014047
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, 14 November 2012 22:31:49 UTC, David Nolen wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">Why can't you just implement ILoo=
kup and the other relevant bits for map-like behavior if you need it?</bloc=
kquote><div><br></div><div>That still doesn't get me closer to having a fie=
ld of my reified instance containing (a collection containing) the reified =
instance itself. </div><div><br></div><div>What I have now is more li=
ke:</div><div><br></div><div><div><font face=3D"courier new, monospace">(le=
t [init-map (fn [context] {:me context})]</font></div><div><font face=3D"co=
urier new, monospace"> (reify </font></div><div><font face=3D"co=
urier new, monospace"> MyProtocol</font></div><div><font face=
=3D"courier new, monospace"> (do-that-thing [this event] (hand=
le-event (init-map this) event))))</font></div><div><font face=3D"courier n=
ew, monospace"><br></font></div><div><font face=3D"arial, sans-serif">... t=
hough in my application's code, the init-map function is a bit more complic=
ated. </font></div><div><font face=3D"arial, sans-serif"><br></font></=
div><div><font face=3D"arial, sans-serif">I'd love to be able to avoid invo=
king init-map for each invocation of do-that-thing, since the result if ini=
t-map is always an exactly equivalent map.</font></div><div><br></div><div>=
I believe I now see what you meant about ILookup; I could implement ILookup=
and intercept requests for the :me key, and delegate the rest to the other=
map (in my simplified example, it looks like the context map has only one =
key, but in the real app, there's a context map for the instance with a num=
ber of key/value pairs already in it, to which I want to add a new key/valu=
e pair to identify the reified instance). However, the code inside ha=
ndle-event needs that parameter to be a map to which new keys can be assoc-=
ed.<br></div></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><span></spa=
n><br><br>On Wednesday, November 14, 2012, Howard M. Lewis Ship wrote:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
I'm in a situation where, if I was using Java code, I would introduce final=
fields initialized in the constructor. Instead I'm using reify with protoc=
ols, and hitting what I perceive to be a small limitation.<div>
<br></div><div>Here's a simplified version of what I'm doing.</div><div><br=
></div><div><font face=3D"courier new, monospace">(reify </font></div>=
<div><font face=3D"courier new, monospace"> MyProtocol</font></div><d=
iv>
<font face=3D"courier new, monospace"> (do-that-thing [this event] (h=
andle-event {:me this} event)))</font></div><div><br></div><div>... in my r=
eal code there's a lot of repetition concerning building that context map; =
in addition, it has to be built all the time, when a single instance could =
be created once and shared. </div>
<div><br></div><div>To address this repetition, i'd like to have some synta=
x for initializing fields of the reified class, perhaps:</div><div><br></di=
v><div><font face=3D"courier new, monospace">(reify</font></div><div>
<font face=3D"courier new, monospace"> [context-map {:me this}]</font=
></div><div><font face=3D"courier new, monospace"><br></font></div><div><fo=
nt face=3D"courier new, monospace"> MyProtocol</font></div><div><font=
face=3D"courier new, monospace"> (do-that-thing [this event] (handle=
-event context-map event)))</font></div>
<div><br></div><div>In other words, a let-style block of field assignments =
that are implicitly part of the generated class' constructor, and with valu=
es that are in lexical scope of the protocol function implementations.</div=
>
<div><br></div><div>I think this is a reasonable thing to want to do ... as=
is, I have several protocol methods that all want to extend a context map =
with a reference back to this reified instance and I don't like the duplica=
tion.</div>
<div><br></div><div>Thoughts?</div><div><br></div><div><br></div><div> =
; </div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
Clojure Dev" group.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/d/msg/clojure-dev/-/oKnRndNNAnQJ" target=3D"_blank">https://groups.googl=
e.com/d/<wbr>msg/clojure-dev/-/oKnRndNNAnQJ</a><wbr>.<br>=20
To post to this group, send email to <a>clojure-dev@googlegroups.com</a>.<b=
r>
To unsubscribe from this group, send email to <a>clojure-dev+unsubscribe@<w=
br>googlegroups.com</a>.<br>
For more options, visit this group at <a href=3D"http://groups.google.com/g=
roup/clojure-dev?hl=3Den" target=3D"_blank">http://groups.google.com/<wbr>g=
roup/clojure-dev?hl=3Den</a>.<br>
</blockquote>
</blockquote>
------=_Part_1604_6371933.1352977014047--
------=_Part_1603_8744855.1352977014047--