I want to use a Java constructor as a first-class Clojure function. My use-case is to transform a sequence of strings into a sequence of Java objects that have a constructor with a single string:
Simple Java object:
public class Foo {
public Foo(String aString){
// initialize the Foo object from aString
}
}
And in Clojure I want to do this:
(defn make-foo (memfn Foo. a-string))
(apply make-foo '("one" "two" "shoe"))
The apply should return a list of Foo objects created from Strings, but I'm getting this:
IllegalArgumentException No matching method found: org.apache.hadoop.io.Text. for class java.lang.String clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)
Don't bother. memfn is practically deprecated in favor of the anonymous function literal, with which you can also invoke constructors, e.g., #(Foo. %).
Also, your apply call is going to try to invoke make-foo once with three string args. You probably instead want:
(map #(Foo. %) ["one" "two" "three"])
Related
I have a child class that is derived from a parent class. I need to use conditional logic to figure out which arguments to pass to the parent class constructor. I am doing this as follows:
Child::Child(const std::string & foo)
:Parent(foo=="x"?someClassPtr(new someClass()):someClassPtr(new someOtherClass()))
{
}
But what if I want to pass a different argument for foo=="y" and foo=="z"? Is there some way to do this without using the ternary operator?
Although you can definitely do it with nested conditional expressions, I would recommend against it: the expression borders on non-readable even with a single conditional, let alone two or three nested ones.
Using a private static member function would be a good choice for this task: the function could "parse" the value of foo, and decide on the proper object to return:
Child::Child(const std::string & foo)
: Parent(constructParentArgs(foo)) {
}
private static someClassPtr *constructParentArgs(const std::string& foo) {
if (foo == "x") return someClassPtr(new someClass());
if (foo == "y") return someClassPtr(new someOtherClass());
if (foo == "z") return someSubClassPtr(new yetAnotherClass());
// provide a default value here
return someClassPtr(new defaultClass());
}
The advantage of this approach for the readers of your code is that they do not have to bother themselves with the details of calling the parent constructor, unless they want to see what is going on. When they read the header, all they know that your code somehow creates parent argument. If they want to learn how exactly the argument gets constructed, they can always go straight to the private member function.
I have a protocol called IExample and I define a record type A that implements it:
(defprotocol IExample
(foo [this] "do something")
(bar [this] "do something else"))
(defrecord A [field1 field2]
IExample
(foo [this]
(+ field1 field2))
(bar [this]
(- field1 field2)))
Let's say I want to extend another (basic) type B to implement this protocol, but I know how to convert from B to A:
(defn B-to-A
"converts a B object to an A object"
[Bobj] ...)
because I have this conversion, I can delegate all calls of the IExample protocol
on a B to the IExample protocol on an A by delegating them:
(extend B
IExample {
:foo (fn [this] (foo (B-to-A this)))
:bar (fn [this] (bar (B-to-A this)))})
This, however, seems as an awful lot of boilerplate (especially for bigger protocols)
that is not clojure-idiomatic.
How can I tell clojure just to implicitly convert B to A every time
an IExample function is called on a B object, using the B-to-A function?
As far as the boilerplate is concerned, you can write some macro to write all that boilerplate for you. On the other hand, you could have a second look at your design here.
What we have here is 3 things (types): A, B and IExample. And then we have 2 relationships between these things: 1) a-to-example : A -> IExample 2) b-to-a : B -> A and from this we can get 3rd relationship by using composition i.e compose b-to-a with a-to-example : B -> IExample. Now if we try to move this design to protocols we will find that it is not a simple translation because protocols won't directly compose as discussed in the above design, instead we can use an intermediate protocol IToExample like shown below:
(defprotocol IExample
(foo [this] "do something")
(bar [this] "do something else"))
(defprotocol IToExample
(to-example [this] "convert to IExample"))
(defrecord A [field1 field2]
IExample
(foo [this]
(+ field1 field2))
(bar [this]
(- field1 field2))
IToExample
(to-example [this] this))
(deftype B [])
(defn b-to-a [b] (A. ....))
(extend B
IToExample {:to-example b-to-a})
What we did that we represented the -> IExample in our design as the IToExample protocol with one function. So we got:
a-to-example : A -> IExample by implementing IToExample for A
b-to-a : B -> A by a normal function
compose b-to-a with a-to-example : B -> IExample by implementing IToExample for B and using b-to-a.
It depends. If you look at the clojure core seq functions, you may notice that the ISec interface is only 4 methods, and that the whole "public" sequence library is defined by (many more) functions that call (some-internal-function (seq argument)) - and they tend to be explicitly documented as doing that too. Conceptually, there's an protocol like your IExample interface, and an additional protocol that describes the seq function to convert from some type to something implementing ISeq.
This is an especially useful strategy if the datatype only needs to implement a couple of methods (so IExample can be small) and the number of algorithms acting on the protocol is large (since you can write all of those in terms of regular functions).
Referring to the answer of the following question:
List.empty vs. List() vs. new List()
How did the developers of Scala map the method apply[A](xs: A*) defined in the List object, to be usable as List[A](cs: A*)?
Also how did they translate aListInstance(n: Int) to the method apply(n: Int) (which returns the n'th element of the list) defined in the List class?
In both cases I'm calling the apply() methods without writing .apply() in my code. How does that work?
It works because the Scala Language Specification says so.
foo(bar)
is translated to
foo.apply(bar)
just like
foo.bar = baz
is translated to
foo.bar_=(baz)
and
foo(bar) = baz
is translated to
foo.update(bar, baz)
and
foo bar baz
is translated to
foo.bar(baz)
and
foo bar_: baz
is translated to
baz.bar_:(foo)
and so on and so forth.
E.g.,
(defprotocol P
(foo [x])
(bar [x]))
(extend-protocol P
Superclass ;; a java abstract class
(foo [x]
(println "superclass"))
Subclass ;; a concrete java class implementing the above abstract class
(foo [x]
(foo (cast Superclass x))))
If calling
(foo subclass-instance)
I would get a stack overflow obviously, but is there some way to accomplish what I'm trying to do here, i.e., call the same function but masquerade as the generic superclass/interface?
Update: A clearer example demonstrating a use case for what I'm asking:
(defprotocol P
(extract-properties-into-map [self]))
(extend-protocol P
PropertyContainer ;; abstract class
(extract-properties-into-map
[this]
(into {} (for [[k v] (.getProperties this)] [(keyword k) (read-string v)])))
Foo
(extract-properties-into-map
[this]
(assoc {:properties (extract-properties-into-map
^PropertyContainer this)} ;; this is where it falls apart
:foo-type (.getFooType this)
:foo-permissions (.getPermissions this)
:foo-whatever (.getWhatever this))))
The problem with cast is that it works like a type assertion, just throwing an exception if your object does not satisfy the is-a relationship.
(defn cast
"Throws a ClassCastException if x is not a c, else returns x."
{:added "1.0"
:static true}
[^Class c x]
(. c (cast x)))
There is no new interface being returned to dispatch in a different function, i.e. you have a stack overflow.
I'm not sure what it means to be extending a protocol for an Interface? Since you're providing an implementation I guess you should define a type first and extend the protocol on that super-type.
EDIT: A slightly better answer based on delegating-proxy from https://gist.github.com/michalmarczyk/1715851
(defprotocol P
(foo [x])
(bar [x]))
(extend-protocol P
Number ;; a java abstract class
(foo [x]
(println "superclass:" x))
Integer ;; a concrete java class implementing the above abstract class
(foo [x]
(foo (delegating-proxy x [Number] []))))
Called with
(foo (Integer. 1))
=> superclass: 1
While it does as the question asked and it now wraps the original x. Depending on the requirements, it might be better to delegate foo to a function not included in the protocol, maybe superfoo
(defn superfoo [x] { :byte (.byteValue x) })
(defprotocol P
(foo [x])
(bar [x]))
(extend-protocol P
Number ;; a java abstract class
(foo [x]
(superfoo x))
Integer ;; a concrete java class implementing the above abstract class
(foo [x]
(merge (superfoo x) { :f (.floatValue x)})))
I think the underlying issue is Protocols do not know about class inheritance. Also, seems like Clojure should have a wait to coerce an object to a type. Type hints do not work in this case.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can overloading operator “function call” in C++ be useful?
I see often where the parenthesis operator, operator(), is overloaded on a class or struct. I have never run into such a need myself, and wonder what is the typical use/need of this operator?
For instance, overloading operator== is accepted as returning true or false based on some equality made with the argument provided. This has a certain accepted and anticipated behavior.
It's used a lot for the hashes, sets and algorithms component of STL to construct things called 'functors'. For example:
using stl::map ;
map<string, string> myMap ;
but if you look at the specification for map it also includes a 'Compare' entry which defaults to less. The Compare is the 'functor' you want map to use when comparing two keys. It looks something like this:
template<class Key>
class less<Key> {
public:
boolean operator()(const Key& a, const Key& b) { return a < b ;}
} ;
so what you have is:
map<string, string, less<string> > myMap ;
and evertime you put something in the map or try to find something in the map it will use the less::operator() to do the comparisons.
You can use this to acchieve other effects such as when using 'sort' you can get sort to yield items in reverse order by using a different functor.
You can use operator(), also known as the 'function call operator', to make an object behave like (and be usable as) a function.
These objects are often referred to as 'functors', but that shouldn't be confused with the same term from mathematics. I believe a more proper term is 'function object'.
Imagine you have a function that takes a callback. But suppose you need to store some state in that callback.
[note: I haven't compiled this code, but you get the idea]
void DoStuffAndCallBack(MyCallbackType Callback)
{
...
Callback(args)
...
}
In C, or in 'C-with-classes'-style C++, you would pass a static callback function to this method, and store results in some global or class-static variable.
But in C++, the function could be written like so:
template<CallbackType>
void DoStuffAndCallBack(CallbackType Callback)
{
...
Callback(args)
...
}
Now you can define a functor object that overloads operator() and pass an instance of that object to the function. That instance will get the callback, and any intermediate results you want to store can be stored in that instance.
In other words, it's a nice way to avoid globals (:
I'm sure there are other uses, but that's one good one, IMO.
The canonical example is for a smart pointer class returning whether or not it is null, so you can do things like:
SmartPointer p = someOtherThing;
if (p)
{
// do something
}
In this case, the return type of the () operator should be bool, and the code will work as written. It creates a functor that allows the instance of the class to be called like a function.