Implementing Interfaces and calling Java Constants in Clojure (Newbie) - interface

I am trying to write a wrapper for the google adwords api in Clojure but struggle with constants and Interfaces.
The java code looks like this :
CampaignServiceInterface campaignService =
user.getService(AdWordsService.V201109.CAMPAIGN_SERVICE);
Usually you can call constants in Clojure with e.g. (Math/PI) but when I write:
(def user (AdWordsUser. ))
(.getService user (AdWordsService/V201109/CAMPAIGN_SERVICE))
I just get "no such namespace".
Also I am a bit clueless on how to implement the interface correct. I think I should use "reify" but I get stuck.
Link to Interface:
http://google-api-adwords-java.googlecode.com/svn-history/r234/trunk/docs/com/google/api/adwords/v201003/cm/CampaignServiceInterface.html
(defn campaign-service [ ]
(reify
com.google.adwords.api.v201109.cm.CampaignServiceInterface
(get [this] ??))))

If I read it correctly, AdWordsService.V201109.CAMPAIGN_SERVICE is a static constant of an inner class of class AdWordsService.
To access inner classes you need to use java's internal name mangling scheme **; separate the inner class from its outer class with a $ sign:
AdWordsService$V201109/CAMPAIGN_SERVICE
** the JVM doesn't actually have a notion of inner classes, so java "fakes" it by creating a standalone class AdWordsService$V201109

1.About accessing constants. Did you import AdWordsService? If not you either can access AdWordsService with fully qualified name: some.package.name.AdWordsService/V201109/CAMPAIGN_SERVICE, or import it via import macro.
2.Check examples here: http://clojuredocs.org/clojure_core/clojure.core/reify
(defn campaign-service [ ]
(reify
com.google.adwords.api.v201109.cm.CampaignServiceInterface
(get [_ selector] (some-function selector))
(mutate [_ operations] (some-function-2 operations))))

Related

Scheme (Kawa) - How to force macro expansion inside another macro

I want to make a macro, that when used in class definition creates a field, it's public setter, and an annotation. However, it'd seem the macro is not expanding, mostly because it's used inside other (class definition) macro.
Here is an example how to define a class with one field:
(define-simple-class test-class ()
(foo :: java.util.List ))
My macro (only defines field as of now):
(define-syntax autowire
(syntax-rules ()
((autowire class id)
(id :: class))))
However, if I try to use it:
(define-simple-class test-class ()
(autowire java.util.List foo))
and query fields of the new class via reflection, I can see that it creates a field named autowire, and foo is nowhere to be seen. Looks like an issue of the order the macros are expanded.
Yes, macros are expanded “from the outside in”. After expanding define-simple-class, the subform (autowire java.util.List foo) does not exist anymore.
If you want this kind of behaviour modification, you need to define your own define-not-so-simple-class macro, which might expand to a define-simple-class form.
However, please step back before making such a minor tweak to something that is standard, and ask yourself whether it is worth it. The upside might be syntax that is slightly better aligned to the way you think, but the downside is that it might be worse aligned to the way others think (who might need to understand your code). There is a maxim for maintainable and readable coding: “be conventional”.

Class finalization: how to avoid creating dummy instances?

I've run into a problem that a third-party library needs to act on a class as if it was finalized. After some reading I understand the motivation behind this mechanism, but I don't really know how it functions.
Example:
(make-instance 'expression :op '+ :left 'nan :right 'nan)
(defmethod normalize-expression ((this expression))
(optima:match this
((optima::or (expression :left 'nan) (expression :right 'nan)) 'nan)
((expression :op op :left x :right y) (funcall op x y))))
Unless I add the first line, the function will not compile, giving me this error:
; caught ERROR:
; (during macroexpansion of (SB-PCL::%DEFMETHOD-EXPANDER NORMALIZE-EXPRESSION ...))
; SB-MOP:CLASS-SLOTS called on #<STANDARD-CLASS EXPRESSION>, which is not yet finalized.
; See also:
; AMOP, Generic Function SB-MOP:CLASS-SLOTS
optima is a pattern-matching library, the (expression :op op ...) is matching instances of class expression against the given pattern. I don't know in much details, but it looks like it needs to know what are the accessors defined for this class, and it looks like that information is not available until it is finalized. So, is there any way to sidestep the finalization problem?
The class will not be extended (at least not in this project, and it's not being planned). It doesn't hurt that much to create a dummy instance... it is just an ugly solution, so I hoped to find a better one. Also, perhaps, I'd get some more info on finalization, which is good too :)
Forgetting to ensure class finalization seems to be quite common mistake when using MOP.
In lisp, classes are defined in two "phases":
Direct class definition
Effective class definition
Direct class definition is isomorphic to defclass form. It has class name, names of superclasses, list of direct slots (i.e., slots defined on this particular class but on its superclasses).
Effective class definition contains all information needed for compiler/interpreter. It contains list of all class slots (including those defined on superclasses), class instance layout, references to accessor methods, etc.
Process of transforming direct class definition to effective class definition is called class finalization. Since CLOS supports redefining classes, finalization might be called multiple times for a class. One of the reasons why finalization is delayed is because class may be defined before its superclasses are defined.
Regarding your particular problem: is seems that optima:match should ensure that class is finalized before trying to list its slots. This can be done with two functions: class-finalized-p (to check whether class needs finalization) and finalize-inheritance to actually perform finalization. Or you can use utility function closer-mop:ensure-finalized. (closer-mop is a library for portable usage of CLOS MOP).
E.g.,:
(c2mop:ensure-finalized (find-class 'expression))

How do I deal with required Clojurescript code from Clojurescript macros?

Let us say I have a X.clojurescript and a X.clojure namespace. Everything in X.clojurescript is Clojurescript code, everything in X.clojure is Clojure code. Unfortunately, I cannot define macros directly in Clojurescript, I have to define them in Clojure and then bring them into a Clojurescript namespace using
(ns X.clojurescript.abc
(:require-macros [X.clojure.def :as clj]))
This is fine. However, what if the macro (defined in X.clojure) is going to need to reference something defined in a Clojurescript namespace (X.clojurescript)? The problem is that the Clojure compiler does not look in my Clojurescript namespace (a separate directory) when resolving other namespaces.
I have gotten around this problem by simply creating a namespace in my Clojure code that has the same namespace and needed definition as exist in Clojurescript, but this seems kind of stupid. So, for instance, if I need X.clojurescript.abc.y in my macro, I will just create an additional namespace on the Clojure side that defs a dummy y in my Clojure version of X.clojurescript.abc; kind of dumb.
How do I deal with a macro that needs to refer to something on the Clojurescript side?
The only time a macro needs a specific namespace at the time of definition is if the macro is using code from said namespace to generate the list of symbols it will return.
you can follow along with these examples in the repl:
(defmacro foo
[a]
`(bar/bar ~a))
the definition of foo will compile even though bar is not a defined namespace
(foo :a)
calling foo will now fail because you have not defined the bar namespace, or the function bar yet
(ns bar)
(defn bar
[x]
[x x])
defines bar in the bar namespace
(ns user)
(foo :a)
=> [:a :a]
Notice that bar does not need to exist at the time of foo's definition. In fact the namespace does not even need to exist at the time of foo's definition.

Clojure ISeq from Scala classes

I have a bunch of Scala classes (like Lift's Box, Scala's Option, etc.) that I'd like to
use in Clojure as a Clojure ISeq.
How do I tell Clojure how to make these classes into an ISeq so that all the various sequence
related functions "just work"?
To build on Arthur's answer, you can provide a generic wrapper class in Scala along these lines:
class WrapCollection(repr: TraversableOnce[_]) extends clojure.lang.Seqable { ... }
If the classes implement the Iterable interface then you can just call seq on them to get a seqeuence. Most of the functions in the sequence library will do this for you though so in almost all normal cases you can just pass them to seq functions like first and count as is.

Clojure: Implementing Seqable for an existing java class

I am trying to make a core java class implement an interface.
I am trying something along the lines of:
(extend-protocol clojure.lang.Seqable
java.lang.Integer
(seq [this] (seq (str this))))
but this does not seem to work because Seqable is just an interface and not a protocol.
Is it possible to make (seq 123) work? how was seq implemented for java.lang.Strings?
proxy also does not seem capable of doing this.
I know I must be missing somethnig really obvious here.
Not possible. clojure.lang.RT/seqFrom has special cases for a number of java builtin types, like Collection and String, and you can't add your own for classes that don't implement Seqable directly.
If the java class implements Iterable, and is wrapped in seq, you could use it as a sequence, with certain restrictions.