You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by freizl <fr...@gmail.com> on 2012/07/02 07:05:55 UTC

Re: Tapestry and Clojure

This sounds a very interesting topic.

Because of clojure Java Interp, getting tapestry work with clojure seems not
difficult.
I have set up a tutorial project at
https://github.com/freizl/clojure-tapestry.

I did not tested all tapestry functionality but I think it should be working
well.

PS: I'm new to both Tapestry and Clojure. 


--
View this message in context: http://tapestry.1045711.n5.nabble.com/Tapestry-and-Clojure-tp5713643p5714226.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Tapestry and Clojure

Posted by Massimo Lusetti <ml...@gmail.com>.
Please no... Scala no ;-)

On Wed, Dec 31, 2014 at 6:08 PM, Ilya Obshadko <il...@gmail.com> wrote:
> Thanks Lance, I've already sorted that out. Actually now I'm experimenting
> with Scala instead of Clojure: looks like it's a better match for my
> requirements.
>
> On Tue, Dec 30, 2014 at 6:07 PM, Lance Java <la...@googlemail.com>
> wrote:
>
>> The logger is not a service and cannot be @Injected into IOC services.
>>
>> You have probably seen that you can @Inject the logger into pages and
>> components. @Inject has been extended (perhaps hijacked) for components and
>> @Injected values can come from contributed InjectionProviders. See
>> CommonResourcesInjectionProvider for the Logger implementation.
>>
>> More info here http://tapestry.apache.org/injection-in-detail.html
>> On 28 Dec 2014 11:16, "Ilya Obshadko" <il...@gmail.com> wrote:
>>
>> > On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
>> > thiagohp@gmail.com> wrote:
>> >
>> > > On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <
>> > ilya.obshadko@gmail.com>
>> > > wrote:
>> > >
>> > >  One more question regarding ObjectLocator.
>> > >> Turns out it cannot resolve services like Logger, complaining that no
>> > >> service implements its interface.
>> > >> Could you suggest how to solve it?
>> > >>
>> > >
>> > > Have you tried getObject() instead of getService()? Logger isn't a
>> > > Tapestry-IoC service (unless you create it, of course), so you cannot
>> use
>> > > getService() to get it.
>> > >
>> >
>> > getObject() on ObjectLocator service instance doesn't work as well. Are
>> > there any other methods to obtain logger service instance?
>> >
>> > --
>> > Ilya Obshadko
>> >
>>
>
>
>
> --
> Ilya Obshadko



-- 
Massimo Lusetti

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
Thanks Lance, I've already sorted that out. Actually now I'm experimenting
with Scala instead of Clojure: looks like it's a better match for my
requirements.

On Tue, Dec 30, 2014 at 6:07 PM, Lance Java <la...@googlemail.com>
wrote:

> The logger is not a service and cannot be @Injected into IOC services.
>
> You have probably seen that you can @Inject the logger into pages and
> components. @Inject has been extended (perhaps hijacked) for components and
> @Injected values can come from contributed InjectionProviders. See
> CommonResourcesInjectionProvider for the Logger implementation.
>
> More info here http://tapestry.apache.org/injection-in-detail.html
> On 28 Dec 2014 11:16, "Ilya Obshadko" <il...@gmail.com> wrote:
>
> > On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
> > thiagohp@gmail.com> wrote:
> >
> > > On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <
> > ilya.obshadko@gmail.com>
> > > wrote:
> > >
> > >  One more question regarding ObjectLocator.
> > >> Turns out it cannot resolve services like Logger, complaining that no
> > >> service implements its interface.
> > >> Could you suggest how to solve it?
> > >>
> > >
> > > Have you tried getObject() instead of getService()? Logger isn't a
> > > Tapestry-IoC service (unless you create it, of course), so you cannot
> use
> > > getService() to get it.
> > >
> >
> > getObject() on ObjectLocator service instance doesn't work as well. Are
> > there any other methods to obtain logger service instance?
> >
> > --
> > Ilya Obshadko
> >
>



-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Lance Java <la...@googlemail.com>.
The logger is not a service and cannot be @Injected into IOC services.

You have probably seen that you can @Inject the logger into pages and
components. @Inject has been extended (perhaps hijacked) for components and
@Injected values can come from contributed InjectionProviders. See
CommonResourcesInjectionProvider for the Logger implementation.

More info here http://tapestry.apache.org/injection-in-detail.html
On 28 Dec 2014 11:16, "Ilya Obshadko" <il...@gmail.com> wrote:

> On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
> thiagohp@gmail.com> wrote:
>
> > On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <
> ilya.obshadko@gmail.com>
> > wrote:
> >
> >  One more question regarding ObjectLocator.
> >> Turns out it cannot resolve services like Logger, complaining that no
> >> service implements its interface.
> >> Could you suggest how to solve it?
> >>
> >
> > Have you tried getObject() instead of getService()? Logger isn't a
> > Tapestry-IoC service (unless you create it, of course), so you cannot use
> > getService() to get it.
> >
>
> getObject() on ObjectLocator service instance doesn't work as well. Are
> there any other methods to obtain logger service instance?
>
> --
> Ilya Obshadko
>

Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>  One more question regarding ObjectLocator.
>> Turns out it cannot resolve services like Logger, complaining that no
>> service implements its interface.
>> Could you suggest how to solve it?
>>
>
> Have you tried getObject() instead of getService()? Logger isn't a
> Tapestry-IoC service (unless you create it, of course), so you cannot use
> getService() to get it.
>

getObject() on ObjectLocator service instance doesn't work as well. Are
there any other methods to obtain logger service instance?

-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
On Wed, Dec 24, 2014 at 9:30 PM, Howard Lewis Ship <hl...@gmail.com> wrote:

> I don't see why you need to make the var dynamic, as it contains a mutable
> value (a promise) itself.
>

Actually it's not needed. Counterclockwise plugin complained about
non-dynamic global var, so I made it dynamic to avoid this warning.


> However, this does bring to mind an idea for 5.5, that Tapestry could
> define a dynamic Var to contain the registry, and bind that Var whenever it
> invokes a Clojure function via the interop.
>

Great idea! That would make a lot of sense to have instant access to
Tapestry services from Clojure runtime.


> On Mon, Dec 22, 2014 at 10:51 AM, Ilya Obshadko <il...@gmail.com>
> wrote:
>
> > No, I didn't try getObject() yet. That means the code for injection would
> > be a little bit more complex, but I'll explain using "simple" version
> from
> > the previous message:
> >
> > https://gist.github.com/xfyre/f6a62b3f63ed01929054
> >
> > Line 4: define dynamic global variable as (promise) - it's not available
> at
> > the time of compilation.
> >
> > Lines 6-8: this is a Tapestry-mapped function that will be called during
> > @Startup phase to "deliver" ObjectLocator instance (after promise was
> > delivered, it becomes immutable and can't be mutated anymore).
> >
> > Lines 10-15: macro that accepts service-bindings in a usual Clojure
> > bindings format, like [hibernate-session Session my-service MyService],
> > when odd entries are variable names and even entries are class names (in
> > Clojure you don't need to use .class). The macro reconstructs this list
> so
> > Class names are
> > converted to getService() calls, and then during let binding (syntax
> > unquote on line 15) those services are finally bound to variables for the
> > later use.
> >
> > Lines 19-23 is an example of using this macro.
> >
> >
> > On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
> > thiagohp@gmail.com> wrote:
> >
> > > On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <
> > ilya.obshadko@gmail.com>
> > > wrote:
> > >
> > >  One more question regarding ObjectLocator.
> > >> Turns out it cannot resolve services like Logger, complaining that no
> > >> service implements its interface.
> > >> Could you suggest how to solve it?
> > >>
> > >
> > > Have you tried getObject() instead of getService()? Logger isn't a
> > > Tapestry-IoC service (unless you create it, of course), so you cannot
> use
> > > getService() to get it.
> > >
> > > By the way, as someone who wants to learn Clojure, could you please
> > > explain your Clojure snippet? :)
> > >
> > >
> > >
> > >> On Thu, Dec 18, 2014 at 11:20 PM, Ilya Obshadko <
> > ilya.obshadko@gmail.com>
> > >> wrote:
> > >>
> > >>  So, my solution for this is actually quite simple:
> > >>>
> > >>> (ns com.xdance.tapestry.serviceregistry
> > >>>
> > >>>   (:import (org.apache.tapestry5.ioc ObjectLocator)))
> > >>>
> > >>>
> > >>> (def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))
> > >>>
> > >>>
> > >>> (defn init-registry [^ObjectLocator registry]
> > >>>
> > >>>   "Must be called during service initialization to set up Tapestry
> > >>> registry object"
> > >>>
> > >>>   (deliver *tapestry-registry-ref* registry))
> > >>>
> > >>>
> > >>> (defmacro with-tapestry-services [service-bindings & body]
> > >>>
> > >>>   "Apply service bindings to body"
> > >>>
> > >>>   (let [service-binding-pairs (partition-all 2 service-bindings)
> > >>>
> > >>>         service-binding-exprs (map #(vector (first %1) `(.getService
> (
> > >>> deref *tapestry-registry*) ~(second %1))) service-binding-pairs)
> > >>>
> > >>>         service-binding-final (vec (reduce concat
> > >>> service-binding-exprs))]
> > >>>
> > >>>     `(let ~service-binding-final ~@body)))
> > >>>
> > >>>
> > >>> The only thing I need to do is to bind init-registry function to
> > Tapestry
> > >>> service interface and call it during startup phase. There might be
> > better
> > >>> approaches probably.
> > >>>
> > >>> On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <
> > ilya.obshadko@gmail.com>
> > >>> wrote:
> > >>>
> > >>>  Thanks Howard, that's making a lot of sense.
> > >>>>
> > >>>> However my initial though was about injecting Clojure globals
> > >>>> (specifically, one global containing service registry) during the
> call
> > >>>> to
> > >>>> "require" IFn. I still couldn't find any ways to manipulate initial
> > >>>> Clojure
> > >>>> environment, although there are obvious workarounds (for example I
> > could
> > >>>> have a specific function inside Clojure namespace that could be used
> > to
> > >>>> inject necessary objects using mutable globals). I'm still looking
> for
> > >>>> more
> > >>>> concise and accurate way to do that.
> > >>>>
> > >>>> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <
> hlship@gmail.com>
> > >>>> wrote:
> > >>>>
> > >>>>  Actually, Clojure interop with Java is very good, so a Clojure
> > function
> > >>>>> could be passed a Java object:
> > >>>>>
> > >>>>> (defn frobnicate-the-request
> > >>>>>   [^Request request]
> > >>>>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
> > >>>>>
> > >>>>> The ^Request part is a type hint, it allows the Clojure compiler to
> > >>>>> generate proper bytecode to access the methods of the request
> without
> > >>>>> using
> > >>>>> reflection.
> > >>>>>
> > >>>>> You quickly get used to the leading dot (which itself is sugar
> syntax
> > >>>>> over
> > >>>>> the more primitive interop special form).
> > >>>>>
> > >>>>> Now, in terms of Clojure interop ... the library I put together ago
> > on
> > >>>>> a
> > >>>>> whim was about efficiently exposing Clojure functions bundled
> > together
> > >>>>> as
> > >>>>> an arbitrary Java interface.
> > >>>>>
> > >>>>> If you pass the Registry to a Clojure function, it will be quite
> > >>>>> capable
> > >>>>> of
> > >>>>> pulling out whatever it needs.
> > >>>>>
> > >>>>> A lot of the capabilities of Clojure are very familiar to Tapestry
> > >>>>> users:
> > >>>>> thread bound values (inside Clojure vars) for example.
> > >>>>>
> > >>>>> My primary thought about integrating Clojure would be to allow a
> > >>>>> Tapestry
> > >>>>> app to jump into Clojure to work with the Datomic APIs natively,
> > rather
> > >>>>> than the Java API to Datomic, which is decidedly second class.
> > >>>>>
> > >>>>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
> > >>>>> thiagohp@gmail.com> wrote:
> > >>>>> >
> > >>>>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
> > >>>>> ilya.obshadko@gmail.com>
> > >>>>> > wrote:
> > >>>>> >
> > >>>>> >
> > >>>>> >  How are Java objects usually passed to Clojure code? The
> > recommended
> > >>>>> way?
> > >>>>> >>>
> > >>>>> >>
> > >>>>> >> Java objects are passed to Clojure functions in exactly the same
> > way
> > >>>>> they
> > >>>>> >> are passed to Java method (because internally Clojure function
> is
> > >>>>> just an
> > >>>>> >> implementation of IFn interface, and function call is
> invoke(...)
> > on
> > >>>>> its
> > >>>>> >> instance).
> > >>>>> >>
> > >>>>> >
> > >>>>> > Now I was the one who hasn't made a clear question. :) I'm not
> > asking
> > >>>>> > about how Clojure passes function arguments. I meant when you
> call
> > >>>>> Clojure
> > >>>>> > code from Java code, how do you pass a Java object so it can be
> > used
> > >>>>> inside
> > >>>>> > Clojure code?
> > >>>>> >
> > >>>>> >  But I don't want to pass services to Clojure functions, I'd like
> > to
> > >>>>> >> inject them into Clojure namespace when clojure.core/require is
> > >>>>> executed.
> > >>>>> >>
> > >>>>> >
> > >>>>> > Got it. I have no idea how to do that given my almost no
> knowledge
> > of
> > >>>>> > Clojure. But I guess there's some way of doing that.
> > >>>>> >
> > >>>>> >
> > >>>>> > --
> > >>>>> > Thiago H. de Paula Figueiredo
> > >>>>> > Tapestry, Java and Hibernate consultant and developer
> > >>>>> > http://machina.com.br
> > >>>>> >
> > >>>>> > ------------------------------------------------------------
> > >>>>> ---------
> > >>>>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > >>>>> > For additional commands, e-mail: users-help@tapestry.apache.org
> > >>>>> >
> > >>>>> >
> > >>>>>
> > >>>>> --
> > >>>>> Howard M. Lewis Ship
> > >>>>>
> > >>>>> Creator of Apache Tapestry
> > >>>>>
> > >>>>> The source for Tapestry training, mentoring and support. Contact me
> > to
> > >>>>> learn how I can get you up and productive in Tapestry fast!
> > >>>>>
> > >>>>> (971) 678-5210
> > >>>>> http://howardlewisship.com
> > >>>>> @hlship
> > >>>>>
> > >>>>>
> > >>>>
> > >>>>
> > >>>> --
> > >>>> Ilya Obshadko
> > >>>>
> > >>>>
> > >>>>
> > >>>
> > >>> --
> > >>> Ilya Obshadko
> > >>>
> > >>>
> > >>>
> > >>
> > >>
> > >
> > > --
> > > Thiago H. de Paula Figueiredo
> > > Tapestry, Java and Hibernate consultant and developer
> > > http://machina.com.br
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > > For additional commands, e-mail: users-help@tapestry.apache.org
> > >
> > >
> >
> >
> > --
> > Ilya Obshadko
> >
>
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
> @hlship
>



-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Howard Lewis Ship <hl...@gmail.com>.
I don't see why you need to make the var dynamic, as it contains a mutable
value (a promise) itself.

However, this does bring to mind an idea for 5.5, that Tapestry could
define a dynamic Var to contain the registry, and bind that Var whenever it
invokes a Clojure function via the interop.

On Mon, Dec 22, 2014 at 10:51 AM, Ilya Obshadko <il...@gmail.com>
wrote:

> No, I didn't try getObject() yet. That means the code for injection would
> be a little bit more complex, but I'll explain using "simple" version from
> the previous message:
>
> https://gist.github.com/xfyre/f6a62b3f63ed01929054
>
> Line 4: define dynamic global variable as (promise) - it's not available at
> the time of compilation.
>
> Lines 6-8: this is a Tapestry-mapped function that will be called during
> @Startup phase to "deliver" ObjectLocator instance (after promise was
> delivered, it becomes immutable and can't be mutated anymore).
>
> Lines 10-15: macro that accepts service-bindings in a usual Clojure
> bindings format, like [hibernate-session Session my-service MyService],
> when odd entries are variable names and even entries are class names (in
> Clojure you don't need to use .class). The macro reconstructs this list so
> Class names are
> converted to getService() calls, and then during let binding (syntax
> unquote on line 15) those services are finally bound to variables for the
> later use.
>
> Lines 19-23 is an example of using this macro.
>
>
> On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
> thiagohp@gmail.com> wrote:
>
> > On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <
> ilya.obshadko@gmail.com>
> > wrote:
> >
> >  One more question regarding ObjectLocator.
> >> Turns out it cannot resolve services like Logger, complaining that no
> >> service implements its interface.
> >> Could you suggest how to solve it?
> >>
> >
> > Have you tried getObject() instead of getService()? Logger isn't a
> > Tapestry-IoC service (unless you create it, of course), so you cannot use
> > getService() to get it.
> >
> > By the way, as someone who wants to learn Clojure, could you please
> > explain your Clojure snippet? :)
> >
> >
> >
> >> On Thu, Dec 18, 2014 at 11:20 PM, Ilya Obshadko <
> ilya.obshadko@gmail.com>
> >> wrote:
> >>
> >>  So, my solution for this is actually quite simple:
> >>>
> >>> (ns com.xdance.tapestry.serviceregistry
> >>>
> >>>   (:import (org.apache.tapestry5.ioc ObjectLocator)))
> >>>
> >>>
> >>> (def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))
> >>>
> >>>
> >>> (defn init-registry [^ObjectLocator registry]
> >>>
> >>>   "Must be called during service initialization to set up Tapestry
> >>> registry object"
> >>>
> >>>   (deliver *tapestry-registry-ref* registry))
> >>>
> >>>
> >>> (defmacro with-tapestry-services [service-bindings & body]
> >>>
> >>>   "Apply service bindings to body"
> >>>
> >>>   (let [service-binding-pairs (partition-all 2 service-bindings)
> >>>
> >>>         service-binding-exprs (map #(vector (first %1) `(.getService (
> >>> deref *tapestry-registry*) ~(second %1))) service-binding-pairs)
> >>>
> >>>         service-binding-final (vec (reduce concat
> >>> service-binding-exprs))]
> >>>
> >>>     `(let ~service-binding-final ~@body)))
> >>>
> >>>
> >>> The only thing I need to do is to bind init-registry function to
> Tapestry
> >>> service interface and call it during startup phase. There might be
> better
> >>> approaches probably.
> >>>
> >>> On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <
> ilya.obshadko@gmail.com>
> >>> wrote:
> >>>
> >>>  Thanks Howard, that's making a lot of sense.
> >>>>
> >>>> However my initial though was about injecting Clojure globals
> >>>> (specifically, one global containing service registry) during the call
> >>>> to
> >>>> "require" IFn. I still couldn't find any ways to manipulate initial
> >>>> Clojure
> >>>> environment, although there are obvious workarounds (for example I
> could
> >>>> have a specific function inside Clojure namespace that could be used
> to
> >>>> inject necessary objects using mutable globals). I'm still looking for
> >>>> more
> >>>> concise and accurate way to do that.
> >>>>
> >>>> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hl...@gmail.com>
> >>>> wrote:
> >>>>
> >>>>  Actually, Clojure interop with Java is very good, so a Clojure
> function
> >>>>> could be passed a Java object:
> >>>>>
> >>>>> (defn frobnicate-the-request
> >>>>>   [^Request request]
> >>>>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
> >>>>>
> >>>>> The ^Request part is a type hint, it allows the Clojure compiler to
> >>>>> generate proper bytecode to access the methods of the request without
> >>>>> using
> >>>>> reflection.
> >>>>>
> >>>>> You quickly get used to the leading dot (which itself is sugar syntax
> >>>>> over
> >>>>> the more primitive interop special form).
> >>>>>
> >>>>> Now, in terms of Clojure interop ... the library I put together ago
> on
> >>>>> a
> >>>>> whim was about efficiently exposing Clojure functions bundled
> together
> >>>>> as
> >>>>> an arbitrary Java interface.
> >>>>>
> >>>>> If you pass the Registry to a Clojure function, it will be quite
> >>>>> capable
> >>>>> of
> >>>>> pulling out whatever it needs.
> >>>>>
> >>>>> A lot of the capabilities of Clojure are very familiar to Tapestry
> >>>>> users:
> >>>>> thread bound values (inside Clojure vars) for example.
> >>>>>
> >>>>> My primary thought about integrating Clojure would be to allow a
> >>>>> Tapestry
> >>>>> app to jump into Clojure to work with the Datomic APIs natively,
> rather
> >>>>> than the Java API to Datomic, which is decidedly second class.
> >>>>>
> >>>>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
> >>>>> thiagohp@gmail.com> wrote:
> >>>>> >
> >>>>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
> >>>>> ilya.obshadko@gmail.com>
> >>>>> > wrote:
> >>>>> >
> >>>>> >
> >>>>> >  How are Java objects usually passed to Clojure code? The
> recommended
> >>>>> way?
> >>>>> >>>
> >>>>> >>
> >>>>> >> Java objects are passed to Clojure functions in exactly the same
> way
> >>>>> they
> >>>>> >> are passed to Java method (because internally Clojure function is
> >>>>> just an
> >>>>> >> implementation of IFn interface, and function call is invoke(...)
> on
> >>>>> its
> >>>>> >> instance).
> >>>>> >>
> >>>>> >
> >>>>> > Now I was the one who hasn't made a clear question. :) I'm not
> asking
> >>>>> > about how Clojure passes function arguments. I meant when you call
> >>>>> Clojure
> >>>>> > code from Java code, how do you pass a Java object so it can be
> used
> >>>>> inside
> >>>>> > Clojure code?
> >>>>> >
> >>>>> >  But I don't want to pass services to Clojure functions, I'd like
> to
> >>>>> >> inject them into Clojure namespace when clojure.core/require is
> >>>>> executed.
> >>>>> >>
> >>>>> >
> >>>>> > Got it. I have no idea how to do that given my almost no knowledge
> of
> >>>>> > Clojure. But I guess there's some way of doing that.
> >>>>> >
> >>>>> >
> >>>>> > --
> >>>>> > Thiago H. de Paula Figueiredo
> >>>>> > Tapestry, Java and Hibernate consultant and developer
> >>>>> > http://machina.com.br
> >>>>> >
> >>>>> > ------------------------------------------------------------
> >>>>> ---------
> >>>>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> >>>>> > For additional commands, e-mail: users-help@tapestry.apache.org
> >>>>> >
> >>>>> >
> >>>>>
> >>>>> --
> >>>>> Howard M. Lewis Ship
> >>>>>
> >>>>> Creator of Apache Tapestry
> >>>>>
> >>>>> The source for Tapestry training, mentoring and support. Contact me
> to
> >>>>> learn how I can get you up and productive in Tapestry fast!
> >>>>>
> >>>>> (971) 678-5210
> >>>>> http://howardlewisship.com
> >>>>> @hlship
> >>>>>
> >>>>>
> >>>>
> >>>>
> >>>> --
> >>>> Ilya Obshadko
> >>>>
> >>>>
> >>>>
> >>>
> >>> --
> >>> Ilya Obshadko
> >>>
> >>>
> >>>
> >>
> >>
> >
> > --
> > Thiago H. de Paula Figueiredo
> > Tapestry, Java and Hibernate consultant and developer
> > http://machina.com.br
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
>
> --
> Ilya Obshadko
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com
@hlship

Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
No, I didn't try getObject() yet. That means the code for injection would
be a little bit more complex, but I'll explain using "simple" version from
the previous message:

https://gist.github.com/xfyre/f6a62b3f63ed01929054

Line 4: define dynamic global variable as (promise) - it's not available at
the time of compilation.

Lines 6-8: this is a Tapestry-mapped function that will be called during
@Startup phase to "deliver" ObjectLocator instance (after promise was
delivered, it becomes immutable and can't be mutated anymore).

Lines 10-15: macro that accepts service-bindings in a usual Clojure
bindings format, like [hibernate-session Session my-service MyService],
when odd entries are variable names and even entries are class names (in
Clojure you don't need to use .class). The macro reconstructs this list so
Class names are
converted to getService() calls, and then during let binding (syntax
unquote on line 15) those services are finally bound to variables for the
later use.

Lines 19-23 is an example of using this macro.


On Sun, Dec 21, 2014 at 10:22 PM, Thiago H de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>  One more question regarding ObjectLocator.
>> Turns out it cannot resolve services like Logger, complaining that no
>> service implements its interface.
>> Could you suggest how to solve it?
>>
>
> Have you tried getObject() instead of getService()? Logger isn't a
> Tapestry-IoC service (unless you create it, of course), so you cannot use
> getService() to get it.
>
> By the way, as someone who wants to learn Clojure, could you please
> explain your Clojure snippet? :)
>
>
>
>> On Thu, Dec 18, 2014 at 11:20 PM, Ilya Obshadko <il...@gmail.com>
>> wrote:
>>
>>  So, my solution for this is actually quite simple:
>>>
>>> (ns com.xdance.tapestry.serviceregistry
>>>
>>>   (:import (org.apache.tapestry5.ioc ObjectLocator)))
>>>
>>>
>>> (def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))
>>>
>>>
>>> (defn init-registry [^ObjectLocator registry]
>>>
>>>   "Must be called during service initialization to set up Tapestry
>>> registry object"
>>>
>>>   (deliver *tapestry-registry-ref* registry))
>>>
>>>
>>> (defmacro with-tapestry-services [service-bindings & body]
>>>
>>>   "Apply service bindings to body"
>>>
>>>   (let [service-binding-pairs (partition-all 2 service-bindings)
>>>
>>>         service-binding-exprs (map #(vector (first %1) `(.getService (
>>> deref *tapestry-registry*) ~(second %1))) service-binding-pairs)
>>>
>>>         service-binding-final (vec (reduce concat
>>> service-binding-exprs))]
>>>
>>>     `(let ~service-binding-final ~@body)))
>>>
>>>
>>> The only thing I need to do is to bind init-registry function to Tapestry
>>> service interface and call it during startup phase. There might be better
>>> approaches probably.
>>>
>>> On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <il...@gmail.com>
>>> wrote:
>>>
>>>  Thanks Howard, that's making a lot of sense.
>>>>
>>>> However my initial though was about injecting Clojure globals
>>>> (specifically, one global containing service registry) during the call
>>>> to
>>>> "require" IFn. I still couldn't find any ways to manipulate initial
>>>> Clojure
>>>> environment, although there are obvious workarounds (for example I could
>>>> have a specific function inside Clojure namespace that could be used to
>>>> inject necessary objects using mutable globals). I'm still looking for
>>>> more
>>>> concise and accurate way to do that.
>>>>
>>>> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hl...@gmail.com>
>>>> wrote:
>>>>
>>>>  Actually, Clojure interop with Java is very good, so a Clojure function
>>>>> could be passed a Java object:
>>>>>
>>>>> (defn frobnicate-the-request
>>>>>   [^Request request]
>>>>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
>>>>>
>>>>> The ^Request part is a type hint, it allows the Clojure compiler to
>>>>> generate proper bytecode to access the methods of the request without
>>>>> using
>>>>> reflection.
>>>>>
>>>>> You quickly get used to the leading dot (which itself is sugar syntax
>>>>> over
>>>>> the more primitive interop special form).
>>>>>
>>>>> Now, in terms of Clojure interop ... the library I put together ago on
>>>>> a
>>>>> whim was about efficiently exposing Clojure functions bundled together
>>>>> as
>>>>> an arbitrary Java interface.
>>>>>
>>>>> If you pass the Registry to a Clojure function, it will be quite
>>>>> capable
>>>>> of
>>>>> pulling out whatever it needs.
>>>>>
>>>>> A lot of the capabilities of Clojure are very familiar to Tapestry
>>>>> users:
>>>>> thread bound values (inside Clojure vars) for example.
>>>>>
>>>>> My primary thought about integrating Clojure would be to allow a
>>>>> Tapestry
>>>>> app to jump into Clojure to work with the Datomic APIs natively, rather
>>>>> than the Java API to Datomic, which is decidedly second class.
>>>>>
>>>>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
>>>>> thiagohp@gmail.com> wrote:
>>>>> >
>>>>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
>>>>> ilya.obshadko@gmail.com>
>>>>> > wrote:
>>>>> >
>>>>> >
>>>>> >  How are Java objects usually passed to Clojure code? The recommended
>>>>> way?
>>>>> >>>
>>>>> >>
>>>>> >> Java objects are passed to Clojure functions in exactly the same way
>>>>> they
>>>>> >> are passed to Java method (because internally Clojure function is
>>>>> just an
>>>>> >> implementation of IFn interface, and function call is invoke(...) on
>>>>> its
>>>>> >> instance).
>>>>> >>
>>>>> >
>>>>> > Now I was the one who hasn't made a clear question. :) I'm not asking
>>>>> > about how Clojure passes function arguments. I meant when you call
>>>>> Clojure
>>>>> > code from Java code, how do you pass a Java object so it can be used
>>>>> inside
>>>>> > Clojure code?
>>>>> >
>>>>> >  But I don't want to pass services to Clojure functions, I'd like to
>>>>> >> inject them into Clojure namespace when clojure.core/require is
>>>>> executed.
>>>>> >>
>>>>> >
>>>>> > Got it. I have no idea how to do that given my almost no knowledge of
>>>>> > Clojure. But I guess there's some way of doing that.
>>>>> >
>>>>> >
>>>>> > --
>>>>> > Thiago H. de Paula Figueiredo
>>>>> > Tapestry, Java and Hibernate consultant and developer
>>>>> > http://machina.com.br
>>>>> >
>>>>> > ------------------------------------------------------------
>>>>> ---------
>>>>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>>>> > For additional commands, e-mail: users-help@tapestry.apache.org
>>>>> >
>>>>> >
>>>>>
>>>>> --
>>>>> Howard M. Lewis Ship
>>>>>
>>>>> Creator of Apache Tapestry
>>>>>
>>>>> The source for Tapestry training, mentoring and support. Contact me to
>>>>> learn how I can get you up and productive in Tapestry fast!
>>>>>
>>>>> (971) 678-5210
>>>>> http://howardlewisship.com
>>>>> @hlship
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Ilya Obshadko
>>>>
>>>>
>>>>
>>>
>>> --
>>> Ilya Obshadko
>>>
>>>
>>>
>>
>>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Thu, 18 Dec 2014 20:01:11 -0200, Ilya Obshadko  
<il...@gmail.com> wrote:

> One more question regarding ObjectLocator.
> Turns out it cannot resolve services like Logger, complaining that no
> service implements its interface.
> Could you suggest how to solve it?

Have you tried getObject() instead of getService()? Logger isn't a  
Tapestry-IoC service (unless you create it, of course), so you cannot use  
getService() to get it.

By the way, as someone who wants to learn Clojure, could you please  
explain your Clojure snippet? :)

>
> On Thu, Dec 18, 2014 at 11:20 PM, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>> So, my solution for this is actually quite simple:
>>
>> (ns com.xdance.tapestry.serviceregistry
>>
>>   (:import (org.apache.tapestry5.ioc ObjectLocator)))
>>
>>
>> (def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))
>>
>>
>> (defn init-registry [^ObjectLocator registry]
>>
>>   "Must be called during service initialization to set up Tapestry
>> registry object"
>>
>>   (deliver *tapestry-registry-ref* registry))
>>
>>
>> (defmacro with-tapestry-services [service-bindings & body]
>>
>>   "Apply service bindings to body"
>>
>>   (let [service-binding-pairs (partition-all 2 service-bindings)
>>
>>         service-binding-exprs (map #(vector (first %1) `(.getService (
>> deref *tapestry-registry*) ~(second %1))) service-binding-pairs)
>>
>>         service-binding-final (vec (reduce concat  
>> service-binding-exprs))]
>>
>>     `(let ~service-binding-final ~@body)))
>>
>>
>> The only thing I need to do is to bind init-registry function to  
>> Tapestry
>> service interface and call it during startup phase. There might be  
>> better
>> approaches probably.
>>
>> On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <il...@gmail.com>
>> wrote:
>>
>>> Thanks Howard, that's making a lot of sense.
>>>
>>> However my initial though was about injecting Clojure globals
>>> (specifically, one global containing service registry) during the call  
>>> to
>>> "require" IFn. I still couldn't find any ways to manipulate initial  
>>> Clojure
>>> environment, although there are obvious workarounds (for example I  
>>> could
>>> have a specific function inside Clojure namespace that could be used to
>>> inject necessary objects using mutable globals). I'm still looking for  
>>> more
>>> concise and accurate way to do that.
>>>
>>> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hl...@gmail.com>
>>> wrote:
>>>
>>>> Actually, Clojure interop with Java is very good, so a Clojure  
>>>> function
>>>> could be passed a Java object:
>>>>
>>>> (defn frobnicate-the-request
>>>>   [^Request request]
>>>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
>>>>
>>>> The ^Request part is a type hint, it allows the Clojure compiler to
>>>> generate proper bytecode to access the methods of the request without
>>>> using
>>>> reflection.
>>>>
>>>> You quickly get used to the leading dot (which itself is sugar syntax
>>>> over
>>>> the more primitive interop special form).
>>>>
>>>> Now, in terms of Clojure interop ... the library I put together ago  
>>>> on a
>>>> whim was about efficiently exposing Clojure functions bundled  
>>>> together as
>>>> an arbitrary Java interface.
>>>>
>>>> If you pass the Registry to a Clojure function, it will be quite  
>>>> capable
>>>> of
>>>> pulling out whatever it needs.
>>>>
>>>> A lot of the capabilities of Clojure are very familiar to Tapestry  
>>>> users:
>>>> thread bound values (inside Clojure vars) for example.
>>>>
>>>> My primary thought about integrating Clojure would be to allow a  
>>>> Tapestry
>>>> app to jump into Clojure to work with the Datomic APIs natively,  
>>>> rather
>>>> than the Java API to Datomic, which is decidedly second class.
>>>>
>>>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
>>>> thiagohp@gmail.com> wrote:
>>>> >
>>>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
>>>> ilya.obshadko@gmail.com>
>>>> > wrote:
>>>> >
>>>> >
>>>> >  How are Java objects usually passed to Clojure code? The  
>>>> recommended
>>>> way?
>>>> >>>
>>>> >>
>>>> >> Java objects are passed to Clojure functions in exactly the same  
>>>> way
>>>> they
>>>> >> are passed to Java method (because internally Clojure function is
>>>> just an
>>>> >> implementation of IFn interface, and function call is invoke(...)  
>>>> on
>>>> its
>>>> >> instance).
>>>> >>
>>>> >
>>>> > Now I was the one who hasn't made a clear question. :) I'm not  
>>>> asking
>>>> > about how Clojure passes function arguments. I meant when you call
>>>> Clojure
>>>> > code from Java code, how do you pass a Java object so it can be used
>>>> inside
>>>> > Clojure code?
>>>> >
>>>> >  But I don't want to pass services to Clojure functions, I'd like to
>>>> >> inject them into Clojure namespace when clojure.core/require is
>>>> executed.
>>>> >>
>>>> >
>>>> > Got it. I have no idea how to do that given my almost no knowledge  
>>>> of
>>>> > Clojure. But I guess there's some way of doing that.
>>>> >
>>>> >
>>>> > --
>>>> > Thiago H. de Paula Figueiredo
>>>> > Tapestry, Java and Hibernate consultant and developer
>>>> > http://machina.com.br
>>>> >
>>>> >  
>>>> ---------------------------------------------------------------------
>>>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>>> > For additional commands, e-mail: users-help@tapestry.apache.org
>>>> >
>>>> >
>>>>
>>>> --
>>>> Howard M. Lewis Ship
>>>>
>>>> Creator of Apache Tapestry
>>>>
>>>> The source for Tapestry training, mentoring and support. Contact me to
>>>> learn how I can get you up and productive in Tapestry fast!
>>>>
>>>> (971) 678-5210
>>>> http://howardlewisship.com
>>>> @hlship
>>>>
>>>
>>>
>>>
>>> --
>>> Ilya Obshadko
>>>
>>>
>>
>>
>> --
>> Ilya Obshadko
>>
>>
>
>


-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
One more question regarding ObjectLocator.
Turns out it cannot resolve services like Logger, complaining that no
service implements its interface.
Could you suggest how to solve it?

On Thu, Dec 18, 2014 at 11:20 PM, Ilya Obshadko <il...@gmail.com>
wrote:

> So, my solution for this is actually quite simple:
>
> (ns com.xdance.tapestry.serviceregistry
>
>   (:import (org.apache.tapestry5.ioc ObjectLocator)))
>
>
> (def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))
>
>
> (defn init-registry [^ObjectLocator registry]
>
>   "Must be called during service initialization to set up Tapestry
> registry object"
>
>   (deliver *tapestry-registry-ref* registry))
>
>
> (defmacro with-tapestry-services [service-bindings & body]
>
>   "Apply service bindings to body"
>
>   (let [service-binding-pairs (partition-all 2 service-bindings)
>
>         service-binding-exprs (map #(vector (first %1) `(.getService (
> deref *tapestry-registry*) ~(second %1))) service-binding-pairs)
>
>         service-binding-final (vec (reduce concat service-binding-exprs))]
>
>     `(let ~service-binding-final ~@body)))
>
>
> The only thing I need to do is to bind init-registry function to Tapestry
> service interface and call it during startup phase. There might be better
> approaches probably.
>
> On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>> Thanks Howard, that's making a lot of sense.
>>
>> However my initial though was about injecting Clojure globals
>> (specifically, one global containing service registry) during the call to
>> "require" IFn. I still couldn't find any ways to manipulate initial Clojure
>> environment, although there are obvious workarounds (for example I could
>> have a specific function inside Clojure namespace that could be used to
>> inject necessary objects using mutable globals). I'm still looking for more
>> concise and accurate way to do that.
>>
>> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hl...@gmail.com>
>> wrote:
>>
>>> Actually, Clojure interop with Java is very good, so a Clojure function
>>> could be passed a Java object:
>>>
>>> (defn frobnicate-the-request
>>>   [^Request request]
>>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
>>>
>>> The ^Request part is a type hint, it allows the Clojure compiler to
>>> generate proper bytecode to access the methods of the request without
>>> using
>>> reflection.
>>>
>>> You quickly get used to the leading dot (which itself is sugar syntax
>>> over
>>> the more primitive interop special form).
>>>
>>> Now, in terms of Clojure interop ... the library I put together ago on a
>>> whim was about efficiently exposing Clojure functions bundled together as
>>> an arbitrary Java interface.
>>>
>>> If you pass the Registry to a Clojure function, it will be quite capable
>>> of
>>> pulling out whatever it needs.
>>>
>>> A lot of the capabilities of Clojure are very familiar to Tapestry users:
>>> thread bound values (inside Clojure vars) for example.
>>>
>>> My primary thought about integrating Clojure would be to allow a Tapestry
>>> app to jump into Clojure to work with the Datomic APIs natively, rather
>>> than the Java API to Datomic, which is decidedly second class.
>>>
>>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
>>> thiagohp@gmail.com> wrote:
>>> >
>>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
>>> ilya.obshadko@gmail.com>
>>> > wrote:
>>> >
>>> >
>>> >  How are Java objects usually passed to Clojure code? The recommended
>>> way?
>>> >>>
>>> >>
>>> >> Java objects are passed to Clojure functions in exactly the same way
>>> they
>>> >> are passed to Java method (because internally Clojure function is
>>> just an
>>> >> implementation of IFn interface, and function call is invoke(...) on
>>> its
>>> >> instance).
>>> >>
>>> >
>>> > Now I was the one who hasn't made a clear question. :) I'm not asking
>>> > about how Clojure passes function arguments. I meant when you call
>>> Clojure
>>> > code from Java code, how do you pass a Java object so it can be used
>>> inside
>>> > Clojure code?
>>> >
>>> >  But I don't want to pass services to Clojure functions, I'd like to
>>> >> inject them into Clojure namespace when clojure.core/require is
>>> executed.
>>> >>
>>> >
>>> > Got it. I have no idea how to do that given my almost no knowledge of
>>> > Clojure. But I guess there's some way of doing that.
>>> >
>>> >
>>> > --
>>> > Thiago H. de Paula Figueiredo
>>> > Tapestry, Java and Hibernate consultant and developer
>>> > http://machina.com.br
>>> >
>>> > ---------------------------------------------------------------------
>>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> > For additional commands, e-mail: users-help@tapestry.apache.org
>>> >
>>> >
>>>
>>> --
>>> Howard M. Lewis Ship
>>>
>>> Creator of Apache Tapestry
>>>
>>> The source for Tapestry training, mentoring and support. Contact me to
>>> learn how I can get you up and productive in Tapestry fast!
>>>
>>> (971) 678-5210
>>> http://howardlewisship.com
>>> @hlship
>>>
>>
>>
>>
>> --
>> Ilya Obshadko
>>
>>
>
>
> --
> Ilya Obshadko
>
>


-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
So, my solution for this is actually quite simple:

(ns com.xdance.tapestry.serviceregistry

  (:import (org.apache.tapestry5.ioc ObjectLocator)))


(def ^:dynamic ^ObjectLocator *tapestry-registry-ref* (promise))


(defn init-registry [^ObjectLocator registry]

  "Must be called during service initialization to set up Tapestry registry
object"

  (deliver *tapestry-registry-ref* registry))


(defmacro with-tapestry-services [service-bindings & body]

  "Apply service bindings to body"

  (let [service-binding-pairs (partition-all 2 service-bindings)

        service-binding-exprs (map #(vector (first %1) `(.getService (deref
*tapestry-registry*) ~(second %1))) service-binding-pairs)

        service-binding-final (vec (reduce concat service-binding-exprs))]

    `(let ~service-binding-final ~@body)))


The only thing I need to do is to bind init-registry function to Tapestry
service interface and call it during startup phase. There might be better
approaches probably.

On Thu, Dec 18, 2014 at 6:49 PM, Ilya Obshadko <il...@gmail.com>
wrote:

> Thanks Howard, that's making a lot of sense.
>
> However my initial though was about injecting Clojure globals
> (specifically, one global containing service registry) during the call to
> "require" IFn. I still couldn't find any ways to manipulate initial Clojure
> environment, although there are obvious workarounds (for example I could
> have a specific function inside Clojure namespace that could be used to
> inject necessary objects using mutable globals). I'm still looking for more
> concise and accurate way to do that.
>
> On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hl...@gmail.com>
> wrote:
>
>> Actually, Clojure interop with Java is very good, so a Clojure function
>> could be passed a Java object:
>>
>> (defn frobnicate-the-request
>>   [^Request request]
>>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
>>
>> The ^Request part is a type hint, it allows the Clojure compiler to
>> generate proper bytecode to access the methods of the request without
>> using
>> reflection.
>>
>> You quickly get used to the leading dot (which itself is sugar syntax over
>> the more primitive interop special form).
>>
>> Now, in terms of Clojure interop ... the library I put together ago on a
>> whim was about efficiently exposing Clojure functions bundled together as
>> an arbitrary Java interface.
>>
>> If you pass the Registry to a Clojure function, it will be quite capable
>> of
>> pulling out whatever it needs.
>>
>> A lot of the capabilities of Clojure are very familiar to Tapestry users:
>> thread bound values (inside Clojure vars) for example.
>>
>> My primary thought about integrating Clojure would be to allow a Tapestry
>> app to jump into Clojure to work with the Datomic APIs natively, rather
>> than the Java API to Datomic, which is decidedly second class.
>>
>> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
>> thiagohp@gmail.com> wrote:
>> >
>> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
>> ilya.obshadko@gmail.com>
>> > wrote:
>> >
>> >
>> >  How are Java objects usually passed to Clojure code? The recommended
>> way?
>> >>>
>> >>
>> >> Java objects are passed to Clojure functions in exactly the same way
>> they
>> >> are passed to Java method (because internally Clojure function is just
>> an
>> >> implementation of IFn interface, and function call is invoke(...) on
>> its
>> >> instance).
>> >>
>> >
>> > Now I was the one who hasn't made a clear question. :) I'm not asking
>> > about how Clojure passes function arguments. I meant when you call
>> Clojure
>> > code from Java code, how do you pass a Java object so it can be used
>> inside
>> > Clojure code?
>> >
>> >  But I don't want to pass services to Clojure functions, I'd like to
>> >> inject them into Clojure namespace when clojure.core/require is
>> executed.
>> >>
>> >
>> > Got it. I have no idea how to do that given my almost no knowledge of
>> > Clojure. But I guess there's some way of doing that.
>> >
>> >
>> > --
>> > Thiago H. de Paula Figueiredo
>> > Tapestry, Java and Hibernate consultant and developer
>> > http://machina.com.br
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> > For additional commands, e-mail: users-help@tapestry.apache.org
>> >
>> >
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator of Apache Tapestry
>>
>> The source for Tapestry training, mentoring and support. Contact me to
>> learn how I can get you up and productive in Tapestry fast!
>>
>> (971) 678-5210
>> http://howardlewisship.com
>> @hlship
>>
>
>
>
> --
> Ilya Obshadko
>
>


-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
Thanks Howard, that's making a lot of sense.

However my initial though was about injecting Clojure globals
(specifically, one global containing service registry) during the call to
"require" IFn. I still couldn't find any ways to manipulate initial Clojure
environment, although there are obvious workarounds (for example I could
have a specific function inside Clojure namespace that could be used to
inject necessary objects using mutable globals). I'm still looking for more
concise and accurate way to do that.

On Thu, Dec 18, 2014 at 7:35 AM, Howard Lewis Ship <hl...@gmail.com> wrote:

> Actually, Clojure interop with Java is very good, so a Clojure function
> could be passed a Java object:
>
> (defn frobnicate-the-request
>   [^Request request]
>   (.setAttribute request "xyzzyx" (compute-the-magic-name)))
>
> The ^Request part is a type hint, it allows the Clojure compiler to
> generate proper bytecode to access the methods of the request without using
> reflection.
>
> You quickly get used to the leading dot (which itself is sugar syntax over
> the more primitive interop special form).
>
> Now, in terms of Clojure interop ... the library I put together ago on a
> whim was about efficiently exposing Clojure functions bundled together as
> an arbitrary Java interface.
>
> If you pass the Registry to a Clojure function, it will be quite capable of
> pulling out whatever it needs.
>
> A lot of the capabilities of Clojure are very familiar to Tapestry users:
> thread bound values (inside Clojure vars) for example.
>
> My primary thought about integrating Clojure would be to allow a Tapestry
> app to jump into Clojure to work with the Datomic APIs natively, rather
> than the Java API to Datomic, which is decidedly second class.
>
> On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
> thiagohp@gmail.com> wrote:
> >
> > On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <
> ilya.obshadko@gmail.com>
> > wrote:
> >
> >
> >  How are Java objects usually passed to Clojure code? The recommended
> way?
> >>>
> >>
> >> Java objects are passed to Clojure functions in exactly the same way
> they
> >> are passed to Java method (because internally Clojure function is just
> an
> >> implementation of IFn interface, and function call is invoke(...) on its
> >> instance).
> >>
> >
> > Now I was the one who hasn't made a clear question. :) I'm not asking
> > about how Clojure passes function arguments. I meant when you call
> Clojure
> > code from Java code, how do you pass a Java object so it can be used
> inside
> > Clojure code?
> >
> >  But I don't want to pass services to Clojure functions, I'd like to
> >> inject them into Clojure namespace when clojure.core/require is
> executed.
> >>
> >
> > Got it. I have no idea how to do that given my almost no knowledge of
> > Clojure. But I guess there's some way of doing that.
> >
> >
> > --
> > Thiago H. de Paula Figueiredo
> > Tapestry, Java and Hibernate consultant and developer
> > http://machina.com.br
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
> @hlship
>



-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Howard Lewis Ship <hl...@gmail.com>.
Actually, Clojure interop with Java is very good, so a Clojure function
could be passed a Java object:

(defn frobnicate-the-request
  [^Request request]
  (.setAttribute request "xyzzyx" (compute-the-magic-name)))

The ^Request part is a type hint, it allows the Clojure compiler to
generate proper bytecode to access the methods of the request without using
reflection.

You quickly get used to the leading dot (which itself is sugar syntax over
the more primitive interop special form).

Now, in terms of Clojure interop ... the library I put together ago on a
whim was about efficiently exposing Clojure functions bundled together as
an arbitrary Java interface.

If you pass the Registry to a Clojure function, it will be quite capable of
pulling out whatever it needs.

A lot of the capabilities of Clojure are very familiar to Tapestry users:
thread bound values (inside Clojure vars) for example.

My primary thought about integrating Clojure would be to allow a Tapestry
app to jump into Clojure to work with the Datomic APIs natively, rather
than the Java API to Datomic, which is decidedly second class.

On Tue, Dec 16, 2014 at 5:24 AM, Thiago H de Paula Figueiredo <
thiagohp@gmail.com> wrote:
>
> On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>
>  How are Java objects usually passed to Clojure code? The recommended way?
>>>
>>
>> Java objects are passed to Clojure functions in exactly the same way they
>> are passed to Java method (because internally Clojure function is just an
>> implementation of IFn interface, and function call is invoke(...) on its
>> instance).
>>
>
> Now I was the one who hasn't made a clear question. :) I'm not asking
> about how Clojure passes function arguments. I meant when you call Clojure
> code from Java code, how do you pass a Java object so it can be used inside
> Clojure code?
>
>  But I don't want to pass services to Clojure functions, I'd like to
>> inject them into Clojure namespace when clojure.core/require is executed.
>>
>
> Got it. I have no idea how to do that given my almost no knowledge of
> Clojure. But I guess there's some way of doing that.
>
>
> --
> Thiago H. de Paula Figueiredo
> Tapestry, Java and Hibernate consultant and developer
> http://machina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com
@hlship

Re: Tapestry and Clojure

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Mon, 15 Dec 2014 18:29:22 -0200, Ilya Obshadko  
<il...@gmail.com> wrote:


>> How are Java objects usually passed to Clojure code? The recommended  
>> way?
>
> Java objects are passed to Clojure functions in exactly the same way they
> are passed to Java method (because internally Clojure function is just an
> implementation of IFn interface, and function call is invoke(...) on its
> instance).

Now I was the one who hasn't made a clear question. :) I'm not asking  
about how Clojure passes function arguments. I meant when you call Clojure  
code from Java code, how do you pass a Java object so it can be used  
inside Clojure code?

> But I don't want to pass services to Clojure functions, I'd like to  
> inject them into Clojure namespace when clojure.core/require is executed.

Got it. I have no idea how to do that given my almost no knowledge of  
Clojure. But I guess there's some way of doing that.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
On Mon, Dec 15, 2014 at 10:12 PM, Thiago H de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Mon, 15 Dec 2014 17:34:10 -0200, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>  ServiceBuilder's buildService() receives a ServiceResources instance as a
>>> parameter. ServiceResources is an ObjectLocator (i.e. Tapestry-IoC
>>> registry).
>>>
>>
>> The wording of my question was not fully correct. tapestry-clojure
>> doesn't use ServiceBuilder, but rather its own ClojureBuilder (which does
>> the job
>> of creating service proxy and binding service interface methods to
>> Clojure> functions in a given namespace).
>>
>
> I also noticed, after sending my answer, that it wasn't very good, due to
> my lack of Clojure knowledge (yet! :)).
>
>  One way to do that is to have special interface method, bound to Clojure
>> function, which can perform necessary injection by using mutable objects
>> in Clojure code. But that doesn't look like a functional way.
>>
>
> How are Java objects usually passed to Clojure code? The recommended way?


Java objects are passed to Clojure functions in exactly the same way they
are passed to Java method (because internally Clojure function is just an
implementation of IFn interface, and function call is invoke(...) on its
instance).

But I don't want to pass services to Clojure functions, I'd like to inject
them into Clojure namespace when clojure.core/require is executed. By
itself, clojure.core/require doesn't allow passing arbitrary arguments that
might be used later inside the namespace.

So I'm not yet sure about correct way to approach this.


I would like Howard to elaborate on this topic, because I'm currently
>> researching various options and yet none of them looks quite right. But I
>> don't have much experience in Clojure, so I might be missing something
>> obvious.
>>
>
> Your suggested code hints at a Clojure function, provided by Tapestry,
> that would somehow provide access to services through the registry. I guess
> you're in the right path.




-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Mon, 15 Dec 2014 17:34:10 -0200, Ilya Obshadko  
<il...@gmail.com> wrote:

>> ServiceBuilder's buildService() receives a ServiceResources instance as  
>> a parameter. ServiceResources is an ObjectLocator (i.e. Tapestry-IoC
>> registry).
>
> The wording of my question was not fully correct. tapestry-clojure  
> doesn't use ServiceBuilder, but rather its own ClojureBuilder (which  
> does the job
> of creating service proxy and binding service interface methods to  
> Clojure> functions in a given namespace).

I also noticed, after sending my answer, that it wasn't very good, due to  
my lack of Clojure knowledge (yet! :)).

> One way to do that is to have special interface method, bound to Clojure
> function, which can perform necessary injection by using mutable objects  
> in Clojure code. But that doesn't look like a functional way.

How are Java objects usually passed to Clojure code? The recommended way?

> I would like Howard to elaborate on this topic, because I'm currently
> researching various options and yet none of them looks quite right. But I
> don't have much experience in Clojure, so I might be missing something
> obvious.

Your suggested code hints at a Clojure function, provided by Tapestry,  
that would somehow provide access to services through the registry. I  
guess you're in the right path.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
On Sun, Dec 14, 2014 at 9:17 PM, Thiago H de Paula Figueiredo <
thiagohp@gmail.com> wrote:

> On Sat, 13 Dec 2014 17:48:09 -0200, Ilya Obshadko <il...@gmail.com>
> wrote:
>
>  I have a question regarding potential Clojure integration in my
>> application
>> service layer. As of now, standard Tapestry mechanism of dependency
>> injection won't work for Clojure-based services, because it's constructed
>> using ServiceBuilder and there is no implementation class.
>>
>
> ServiceBuilder's buildService() receives a ServiceResources instance as a
> parameter. ServiceResources is an ObjectLocator (i.e. Tapestry-IoC
> registry).


The wording of my question was not fully correct. tapestry-clojure doesn't
use ServiceBuilder, but rather its own ClojureBuilder (which does the job
of creating service proxy and binding service interface methods to Clojure
functions in a given namespace).

One way to do that is to have special interface method, bound to Clojure
function, which can perform necessary injection by using mutable objects in
Clojure code. But that doesn't look like a functional way.

I would like Howard to elaborate on this topic, because I'm currently
researching various options and yet none of them looks quite right. But I
don't have much experience in Clojure, so I might be missing something
obvious.


> I understand that it probably cannot be solved directly, but what
>> alternative scenarios do we have at our disposal?
>>
>> One of them is probably a custom service builder. Any others?
>>
>
> You can use builder methods (YourService buildYourService()) or
> bind(Class<T> serviceInterface, ServiceBuilder<T> builder). Pass the
> services you want to your Clojure code as objects.



-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Sat, 13 Dec 2014 17:48:09 -0200, Ilya Obshadko  
<il...@gmail.com> wrote:

> I have a question regarding potential Clojure integration in my  
> application
> service layer. As of now, standard Tapestry mechanism of dependency
> injection won't work for Clojure-based services, because it's constructed
> using ServiceBuilder and there is no implementation class.

ServiceBuilder's buildService() receives a ServiceResources instance as a  
parameter. ServiceResources is an ObjectLocator (i.e. Tapestry-IoC  
registry).

> I understand that it probably cannot be solved directly, but what
> alternative scenarios do we have at our disposal?
>
> One of them is probably a custom service builder. Any others?

You can use builder methods (YourService buildYourService()) or  
bind(Class<T> serviceInterface, ServiceBuilder<T> builder). Pass the  
services you want to your Clojure code as objects.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Tapestry and Clojure

Posted by Ilya Obshadko <il...@gmail.com>.
I have a question regarding potential Clojure integration in my application
service layer. As of now, standard Tapestry mechanism of dependency
injection won't work for Clojure-based services, because it's constructed
using ServiceBuilder and there is no implementation class.

I understand that it probably cannot be solved directly, but what
alternative scenarios do we have at our disposal?

One of them is probably a custom service builder. Any others?

Ideally, I would like to have something like:

(with-tapestry
   (def service1 (tapestry-inject 'com.myapp.Service1))
   (def service2 (tapestry-inject 'com.myapp.Service2))
 ...
)

Thanks for any suggestions.


On Mon, Jul 2, 2012 at 7:31 PM, Howard Lewis Ship <hl...@gmail.com> wrote:

> I see Clojure use with Tapestry as an extension of the (largely
> stateless) services layer; although you can use :gen-class to create
> class-like things with readable/writable properties, that will not
> work very will with Tapestry that expects to be able to read bytecode
> from a .class file and enhance it in multiple ways.
>
> Tapestry pages and components are inherently stateful and mutable;
> trying to implement them in Clojure is a bit off-base.
>
> On Sun, Jul 1, 2012 at 10:05 PM, freizl <fr...@gmail.com> wrote:
> > This sounds a very interesting topic.
> >
> > Because of clojure Java Interp, getting tapestry work with clojure seems
> not
> > difficult.
> > I have set up a tutorial project at
> > https://github.com/freizl/clojure-tapestry.
> >
> > I did not tested all tapestry functionality but I think it should be
> working
> > well.
> >
> > PS: I'm new to both Tapestry and Clojure.
> >
> >
> > --
> > View this message in context:
> http://tapestry.1045711.n5.nabble.com/Tapestry-and-Clojure-tp5713643p5714226.html
> > Sent from the Tapestry - User mailing list archive at Nabble.com.
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
>
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
Ilya Obshadko

Re: Tapestry and Clojure

Posted by Howard Lewis Ship <hl...@gmail.com>.
I see Clojure use with Tapestry as an extension of the (largely
stateless) services layer; although you can use :gen-class to create
class-like things with readable/writable properties, that will not
work very will with Tapestry that expects to be able to read bytecode
from a .class file and enhance it in multiple ways.

Tapestry pages and components are inherently stateful and mutable;
trying to implement them in Clojure is a bit off-base.

On Sun, Jul 1, 2012 at 10:05 PM, freizl <fr...@gmail.com> wrote:
> This sounds a very interesting topic.
>
> Because of clojure Java Interp, getting tapestry work with clojure seems not
> difficult.
> I have set up a tutorial project at
> https://github.com/freizl/clojure-tapestry.
>
> I did not tested all tapestry functionality but I think it should be working
> well.
>
> PS: I'm new to both Tapestry and Clojure.
>
>
> --
> View this message in context: http://tapestry.1045711.n5.nabble.com/Tapestry-and-Clojure-tp5713643p5714226.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org