Programmatic reification

2015-04-24 Thread Brian Guthrie
Hi all,

Is there a good way to reify protocols programmatically, i.e., by passing
data structures rather than dropping down into a macro? reify bottoms out
in reify*, which doesn't help much.

Thanks,

Brian

-- 
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/d/optout.


Re: Programmatic reification

2015-04-24 Thread Steven Deobald
Okay, Brian. I'll bite. :)

I don't have the answer for you, but I'm definitely curious what your use
case is. Whatcha upto?

Steven Deobald -- ⌀ -- nilenso.com

On Fri, Apr 24, 2015 at 7:18 PM, Brian Guthrie btguth...@gmail.com wrote:

 Hi all,

 Is there a good way to reify protocols programmatically, i.e., by passing
 data structures rather than dropping down into a macro? reify bottoms out
 in reify*, which doesn't help much.

 Thanks,

 Brian

 --
 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/d/optout.


-- 
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/d/optout.


Re: Programmatic reification

2015-04-24 Thread Timothy Baldridge
This is a situation where I reach for eval. Construct your reify call as if
you were inside a macro, but instead of returning data from the macro, call
(eval form). The call to reify will be slow (and could cause permgen
problems), but if you wrap the form in a function you can cache the
function and avoid that problem. Something like:


(let [cache (atom {})]
  (defn implement-at-runtime [interface-name method-name  body]
(if-let [result (@cache [interface-name method-name body])]
  (result)
  (let [f (eval `(fn []
   (reify
 ~interface-name
 (~method-name ~@body]
(swap! cache assoc [interface-name  method-name body] f)
(f)

@(implement-at-runtime 'clojure.lang.IDeref 'deref '[this] 42)
;; returns 42

Timothy

On Fri, Apr 24, 2015 at 8:14 AM, Steven Deobald ste...@nilenso.com wrote:

 Okay, Brian. I'll bite. :)

 I don't have the answer for you, but I'm definitely curious what your use
 case is. Whatcha upto?

 Steven Deobald -- ⌀ -- nilenso.com

 On Fri, Apr 24, 2015 at 7:18 PM, Brian Guthrie btguth...@gmail.com
 wrote:

 Hi all,

 Is there a good way to reify protocols programmatically, i.e., by passing
 data structures rather than dropping down into a macro? reify bottoms out
 in reify*, which doesn't help much.

 Thanks,

 Brian

 --
 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/d/optout.


  --
 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/d/optout.




-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

-- 
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/d/optout.


Re: Programmatic reification

2015-04-24 Thread Brian Guthrie
On Fri, Apr 24, 2015 at 10:14 AM, Steven Deobald ste...@nilenso.com wrote:

 I don't have the answer for you, but I'm definitely curious what your use
 case is. Whatcha upto?


I've become a firm believer in using protocols to encapsulate operations
with side effects, but I don't know of any good test-framework-agnostic
mocking or stubbing frameworks that work with them. I don't care much for
interaction-based (mocking) tests anyway, really, and reification is simple
enough that I don't think sugar for stubs buys you much. But it seemed like
an open niche and a fun project. If I'm wrong and such a library does
exist, please let me know.

The library I'm working on doesn't attempt to perform any var replacements,
and it doesn't introduce any new syntax; it's simply a mechanism for
building fake versions of protocols, with full or partial implementations,
that can be passed into functions that require them, and whose state (e.g.,
the set of calls they've received) can be subsequently inspected. I'd
prefer to avoid macros entirely, except that I don't know of any other way
to reify on demand.

Release coming shortly.

Cheers,

Brian

-- 
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/d/optout.


Re: Programmatic reification

2015-04-24 Thread Timothy Baldridge
This is why I like component (https://github.com/stuartsierra/component).
The nice thing about using this library is that it encourages you to break
your application into self-contained components. Those components must then
communicate via protocols, and the result is a modular system that's much
simpler to test.

Timothy

On Fri, Apr 24, 2015 at 1:37 PM, Brian Guthrie btguth...@gmail.com wrote:


 On Fri, Apr 24, 2015 at 10:14 AM, Steven Deobald ste...@nilenso.com
 wrote:

 I don't have the answer for you, but I'm definitely curious what your use
 case is. Whatcha upto?


 I've become a firm believer in using protocols to encapsulate operations
 with side effects, but I don't know of any good test-framework-agnostic
 mocking or stubbing frameworks that work with them. I don't care much for
 interaction-based (mocking) tests anyway, really, and reification is simple
 enough that I don't think sugar for stubs buys you much. But it seemed like
 an open niche and a fun project. If I'm wrong and such a library does
 exist, please let me know.

 The library I'm working on doesn't attempt to perform any var
 replacements, and it doesn't introduce any new syntax; it's simply a
 mechanism for building fake versions of protocols, with full or partial
 implementations, that can be passed into functions that require them, and
 whose state (e.g., the set of calls they've received) can be subsequently
 inspected. I'd prefer to avoid macros entirely, except that I don't know of
 any other way to reify on demand.

 Release coming shortly.

 Cheers,

 Brian


  --
 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/d/optout.




-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

-- 
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/d/optout.


Re: Programmatic reification

2015-04-24 Thread Timothy Baldridge
Correction on my original response: The call to eval will be slow...

Reify doesn't take up permgen space with each invocation, but eval will (at
least on  JVM 8).

Timothy

On Fri, Apr 24, 2015 at 2:14 PM, Brian Guthrie btguth...@gmail.com wrote:

 Thanks for the advice, Timothy. I think this is probably much cleaner than
 where I ended up, and good advice. I'll let you know how it goes.

 On Fri, Apr 24, 2015 at 10:45 AM, Timothy Baldridge tbaldri...@gmail.com
 wrote:

 This is a situation where I reach for eval. Construct your reify call as
 if you were inside a macro, but instead of returning data from the macro,
 call (eval form). The call to reify will be slow (and could cause permgen
 problems), but if you wrap the form in a function you can cache the
 function and avoid that problem. Something like:


 (let [cache (atom {})]
   (defn implement-at-runtime [interface-name method-name  body]
 (if-let [result (@cache [interface-name method-name body])]
   (result)
   (let [f (eval `(fn []
(reify
  ~interface-name
  (~method-name ~@body]
 (swap! cache assoc [interface-name  method-name body] f)
 (f)

 @(implement-at-runtime 'clojure.lang.IDeref 'deref '[this] 42)
 ;; returns 42

 Timothy

 On Fri, Apr 24, 2015 at 8:14 AM, Steven Deobald ste...@nilenso.com
 wrote:

 Okay, Brian. I'll bite. :)

 I don't have the answer for you, but I'm definitely curious what your
 use case is. Whatcha upto?

 Steven Deobald -- ⌀ -- nilenso.com

 On Fri, Apr 24, 2015 at 7:18 PM, Brian Guthrie btguth...@gmail.com
 wrote:

 Hi all,

 Is there a good way to reify protocols programmatically, i.e., by
 passing data structures rather than dropping down into a macro? reify
 bottoms out in reify*, which doesn't help much.

 Thanks,

 Brian

 --
 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/d/optout.


  --
 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/d/optout.




 --
 “One of the main causes of the fall of the Roman Empire was that–lacking
 zero–they had no way to indicate successful termination of their C
 programs.”
 (Robert Firth)

 --
 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/d/optout.


  --
 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/d/optout.




-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”

Re: Programmatic reification

2015-04-24 Thread Brian Guthrie
On Fri, Apr 24, 2015 at 3:51 PM, Timothy Baldridge tbaldri...@gmail.com
wrote:

 This is why I like component (https://github.com/stuartsierra/component).
 The nice thing about using this library is that it encourages you to break
 your application into self-contained components. Those components must then
 communicate via protocols, and the result is a modular system that's much
 simpler to test.


Strongly agree. I've been making much greater use of protocols since
adopting Component on a wider scale, and that's sort of the motivation here.

Brian

-- 
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/d/optout.


Re: Programmatic reification

2015-04-24 Thread Brian Guthrie
Thanks for the advice, Timothy. I think this is probably much cleaner than
where I ended up, and good advice. I'll let you know how it goes.

On Fri, Apr 24, 2015 at 10:45 AM, Timothy Baldridge tbaldri...@gmail.com
wrote:

 This is a situation where I reach for eval. Construct your reify call as
 if you were inside a macro, but instead of returning data from the macro,
 call (eval form). The call to reify will be slow (and could cause permgen
 problems), but if you wrap the form in a function you can cache the
 function and avoid that problem. Something like:


 (let [cache (atom {})]
   (defn implement-at-runtime [interface-name method-name  body]
 (if-let [result (@cache [interface-name method-name body])]
   (result)
   (let [f (eval `(fn []
(reify
  ~interface-name
  (~method-name ~@body]
 (swap! cache assoc [interface-name  method-name body] f)
 (f)

 @(implement-at-runtime 'clojure.lang.IDeref 'deref '[this] 42)
 ;; returns 42

 Timothy

 On Fri, Apr 24, 2015 at 8:14 AM, Steven Deobald ste...@nilenso.com
 wrote:

 Okay, Brian. I'll bite. :)

 I don't have the answer for you, but I'm definitely curious what your use
 case is. Whatcha upto?

 Steven Deobald -- ⌀ -- nilenso.com

 On Fri, Apr 24, 2015 at 7:18 PM, Brian Guthrie btguth...@gmail.com
 wrote:

 Hi all,

 Is there a good way to reify protocols programmatically, i.e., by
 passing data structures rather than dropping down into a macro? reify
 bottoms out in reify*, which doesn't help much.

 Thanks,

 Brian

 --
 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/d/optout.


  --
 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/d/optout.




 --
 “One of the main causes of the fall of the Roman Empire was that–lacking
 zero–they had no way to indicate successful termination of their C
 programs.”
 (Robert Firth)

 --
 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/d/optout.


-- 
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/d/optout.