interface I1 { ... }
interface I2 { ... }
struct List(T) { ... }
How do I specialize my List to operate only on classes that implement both I1 and I2? One interface is easy:
struct List(T : I1)
Other languages. In C# it's:
struct List<T> where T : I1, I2
And in Java I'd say:
class List<T extends I1 & I2>
One catch: I don't want an if template constraint because I want reasonable auto-completion from a non-state-of-the-art IDEs. I think it'll be long before IDEs for D do things like reverse-engineering template constraints to deduce a list possible T's methods. And even if, that doesn't sound like cheap performance-wise.
If you don't want to constrain template by if statement, only way is this:
struct List(T : I1, U : I2 = T) { }
that means that you can instantiate List with one or two arguments, if you instantiate only with one - List!(C), then the U will be by default assigned value C, and checked if it implements I2. You can then ignore parameter U in the struct. The problem with this method is that you instantiate the List with two parameters - List!(C1, C2)...
Here is version with if constraint, which doesn't have this problem:
struct List2(T) if ( is(T : I1) && is(T : I2)) { }
There is no practical performance overhead in using if template constraint - or any compile time technique - if you are not calculating lot of data (like ct raytracer or look-up tables)
I would really suggest you to not limit your code to what the IDE supports - there sure will be many things that your IDE is not supporting well and you may find yourself having much less fun than using simple text editor with only sintax highlight, but with full potential of D.
In D2, you can use template constraints and the is expression.
struct List(T)
if (is(T : I1) && is(T : I2))
{
...
}
Here, the is expressions checks whether T is implicitly convertible to I1 and I2 (which is only possible if T implements them).
Related
I am planning to port our server to Go from c++ and I have a question with regards to handling a list of objects based from derived classes.
What I meant is, say if I have a base class (or an interface) called A, and it has child classes B and C, and I want to have a generic list that can handle a list of Type A and it's derived.
In object oriented languages, I can just create a list of (pointer) A and that's it, I can add objects B and C to the list because they are indeed of type A. But since Go does not have inheritance, I am confused on how to effectively handle this.
As noted before, you can do this using interfaces. You can create a list of type []Intf where Intf is an interface common to your types, and then you can put any type that implements that interface into your list.
type A struct{}
type B struct{}
type Intf interface {
// common methods of A and B
}
func f(a Intf) {
// Here, a is A or B
}
You have to be careful about whether you're dealing with copies, or pointers. For instance:
a:=A{}
b:=B{}
x:=[]Intf{&a,&b}
f(x)
is different from:
x:=[]Intf{a,b}
f(x)
With the first one, if f modified the array elements, the variables a and b are modified because the interface contains a pointer. With the second one, if f modifies the array elements, a and b are not affected because the interfaces in the array contain pointers to copies of those variables.
If, say, A has a method included in the interface Intf that takes a pointer receiver, then you have to use the address of all A instances in the array.
Go's type system is explicit, and strict. So, for instance, you implemented your polymorphic list via interfaces, and you have functions:
func f(input []Intf) {
}
func g(input Intf) {
}
And let's say you have these variables:
var a []A
var b A
where A implements Intf. Then:
g(b) // This is valid
f(a) // This is *not* valid
This is because f gets a []Intf, but a is an []A, not []Intf. To call f, you have to build a []Intf:
fInput:=make([]Intf,0,len(a))
for _,x:=range a {
fInput=append(fInput,x)
}
f(fInput)
So if you're dealing with polymorphic lists, then it makes sense to always work with the interface list, not the concrete type list.
You can also work with type assertions if you need direct access to fields depending on type:
func f(in []Intf) {
for _,x:=range in {
if a, ok:=x.(*A); ok {
a.Field=1
}
}
}
Before Java 8, we implemented Comparable.compareTo(...) like this:
public int compare(Person a, Person b) {
return new CompareToBuilder()
.append(a.getLastName(), b.getLastName())
.append(a.getFirstName(), b.getFirstName())
.toComparison();
}
As of Java 8, we can do it like this:
public int compare(Person a, Person b) {
return Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.compare(a, b);
}
The new Java 8 way might allow us to drop the commons-lang3 dependency. Is that new Java 8 way faster? Is there a way to automatically migrate? I didn't find an IntelliJ intention for it.
Notice that it becomes a bit more complex when there are reverse orders and non natural comparison is involved:
public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) {
return new CompareToBuilder()
.append(b.hasAnyFailure(), a.hasAnyFailure()) // Reverse
.append(a.getAverageScore(), b.getAverageScore(), resilientScoreComparator)
.toComparison();
}
becomes
public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) {
return Comparator
.comparing(SingleBenchmarkResult::hasAnyFailure, Comparator.reverseOrder()) // Reverse
.thenComparing(SingleBenchmarkResult::getAverageScore, resilientScoreComparator)
.compare(a, b);
}
If you write it this way
public int compare(Person a, Person b) {
return Comparator
.comparing(Person::getLastName)
.thenComparing(Person::getFirstName)
.compare(a, b);
}
you are wasting performance by constructing a new Comparator for each comparison. And it should be obviously nonsensical when looking at the surrounding code. The compare(Person a, Person b) method surely is part of a class implementing Comparator<Person>, which you instantiate at some place to get the desired comparator. You should replace that instance by a sole Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName) instance instead, used throughout the entire operation.
E.g.
// reusable
static final Comparator<Person> By_NAME = Comparator
.comparing(Person::getLastName).thenComparing(Person::getFirstName);
or ad hoc
listOfPersons.sort(Comparator.comparing(Person::getLastName)
.thenComparing(Person::getFirstName));
If you use it that way, it’s very likely to be faster. However, you should see, that there is no simple pattern-based replacement possible. You have to replace the use sites of the class with that simple declarative construct and make a decision whether to use a shared comparator instance for multiple use sites or create it ad-hoc. Then, you can remove the entire old implementation class or at least, remove the comparator functionality from it if it still serves other purposes.
I don't think there is any pre-defined inspection for that. You might try to use IntelliJ's structural-search, although I think it might by quite tricky to do that for every possible case. One possibility for a simple case with two comparisons might be the following:
search template (occurence count of $TYPE$ and $z$ is 2):
$ReturnType$ $MethodName$($TYPE$ $z$) {
return new CompareToBuilder()
.append($A$.$m$(), $B$.$m$())
.append($A$.$m1$(), $B$.$m1$())
.toComparison();
}
replacement template:
$ReturnType$ $MethodName$($TYPE$ $z$) {
return java.util.Comparator
.comparing($TYPE$::$m$)
.thenComparing($TYPE$::$m1$)
.compare($A$, $B$);
}
I am not an expert on structural search, but I guess you would have to make another pattern for calls with more or less comparisons.
Is there any construct that allows all classes which implemented a set of functions to be considered as a certain interface, even when the classes themselves do not explicitly implement the interface?
To make the question clearer, I'll make an example. Suppose we want to implement LinearSearch, which look through the whole array and search for certain key, and return the index of the key upon discovery. Essentially, the psudeocode might look something like this:
LinearSearch(A, key)
for (k = 0; k < A.length(); k++)
if (A.get(k) == key)
return k
return NULL
In that case, any classes which implemented length and get will be able to search through the structure. We could implement this on DynamicArray, which acts the same as ArrayList in Java. We could implement this on a LinkedList, ignoring the fact the get takes linear time per query. Similarly for other structures that implement these 2 functions. However, such classes might not have explicitly implemented a common interface, even though it is favorable to have them being in one.
While writing this question, I feel a sense of insecurity tinkering within me about such a construct, but I cannot put it into words. So, is there any reason you think that this might not be a good construct in actual languages?
It's called "duck typing". Message-based object models like Smalltalk allow sending any message to an object as long as its name and parameters match.
In languages like C++, you can emulate this using "signals" and "slots", which, at their most primitive, can be implemented by writing a little template adapter class like
class CallGetLengthAdapterBase
{
public:
int length() = 0;
key_type key() = 0;
};
template<class N>
class CallGetLengthAdapter : public CallGetLengthAdapterBase
{
public:
CallGetLengthAdapter( N* obj ) { mObject = obj; };
int length() { return mObject->length(); };
key_type key() { return mObject->key(); };
protected:
N* mObject;
};
So the LinearSearch would just know about CallGetLengthAdapterBase, and would take a pointer to an object of this type. Whoever owns and connects both of these objects would call them like:
LinearSearch( CallGetLengthAdapter<A_type>(&A), key );
That's all.
From Wikipedia:
Go has "interface" types that are compatible with any type that supports a given set of methods (the type does not need to explicitly implement the interface). The empty interface, interface{}, is compatible with all types.
It sounds like this is what you mean, so it is another sense of interface than we might be used to from Java or such. This is a structural typing kind of interface, where the structure of methods involved are the important part, not a name given to the interface.
More formally, it seems that this is called a type class.
Up-front: I am aware that R is a functional language, so please don't bite ;-)
I've had great experiences with using an OOP approach for a lot of my programs.
Now, I'm wondering if there's a way to make a distinction between public and private methods when using S4 Reference Classes in R?
Example
Class Definitions
setRefClass("B",
field=list(
b.1="numeric",
b.2="logical"
),
methods=list(
thisIsPublic=function(...) {
thisIsPublic_ref(.self=.self, ...)
},
thisIsPrivate=function(...) {
thisIsPrivate_ref(.self=.self, ...)
}
)
)
setRefClass("A",
field=list(
a.1="B"
)
)
NOTE
I usually do not place the actual method definition within the class def but separate it to a S4 method (i.e. thisIsPublic_ref) for the following reasons:
That way the class def stays clearly arranged and is easier to read in cases when the individual method defs grow quite large.
It allows you to switch to a functional execution of methods at any time. Be x an instance of a certain class, you are able to call foo_ref(.self=x) instead of x$foo().
It allows you to byte-compile the methods via compiler::cmpfun() which I think is not possible if you have "plain" Reference Class methods.
It sure does not really make sense to make it that complicated for this specific example, but I thought I'd nevertheless illustrate that approach.
Method Definitions
setGeneric(
name="thisIsPublic_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPublic_ref")
}
)
setGeneric(
name="thisIsPrivate_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPrivate_ref")
}
)
require(compiler)
setMethod(
f="thisIsPublic_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.1 * 1000
})
)
setMethod(
f="thisIsPrivate_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.2
})
)
Instances
x.b <- new("B", b.1=10, b.2=TRUE)
x.a <- new("A", a.1=x.b, a.2="hello world")
Public vs. private
Instances of class A (i.e. x.a) should be allowed to use class B's public methods:
> x.a$a.1$thisIsPublic()
[1] 10000
Instances of class A (i.e. x.a) should not be allowed to use class B's private methods. So I would want this not to work, i.e. result in an error:
> x.a$a.1$thisIsPrivate()
[1] TRUE
Any idea how one could specify this?
The only thing I came up with so far:
Adding a sender argument to each method, explicitly specify it for each method call and check if class(.self) == class(sender). But that seems a bit “explicit“.
As functions are first-class objects in R, you can embed one inside the other, as follows:
hello <- function() {
print_ <- function() {
return ('hello world')
}
print_()
}
Yes, it's cheeky, probably not the cleanest way, but it does work... Invoke using 'hello()'.
The short answer is to make a package. R's object systems and it's means of partitioning code (namespaces) are more separate than their equivalents in Java-like languages.
When you make a package, you specify what gets exported in a file called NAMESPACE using directives export and exportMethods. You can choose not to export methods and other R objects that you wish to be package private (to use Java terminology). See the Namespaces with S4 classes and methods section of the Writing R Extensions manual
Making a package is tricky the first time you do it, but there's lot's of help. See the docs for package.skeleton and the Writing R Extensions manual linked above.
Make sure Reference classes are really what you want. Regular S4 classes are usually the more R-ish way, for whatever that's worth. A great source of information about R's many OO constructs (and about packaging, too) is on Hadley Wickham's devtools wiki.
Object slicing is some thing that object looses some of its attributes or functions when a child class is assigned to base class.
Some thing like
Class A{
}
Class B extends A{
}
Class SomeClass{
A a = new A();
B b = new B();
// Some where if might happen like this */
a = b; (Object slicing happens)
}
Do we say Object slicing is any beneficial in any ways?
If yes, can any one please tell me how object slicing be a helpful in development and where it might be helpful?
In C++, you should think of an object slice as a conversion from the derived type to the base type[*]. A brand new object is created, which is "inspired by a true story".
Sometimes this is something that you would want to do, but the result is not in any sense the same object as the original. When object slicing goes wrong is when people aren't paying attention, and think it is the same object or a copy of it.
It's normally not beneficial. In fact it's normally done accidentally when someone passes by value when they meant to pass by reference.
It's quite hard to come up with an example of when slicing is definitively the right thing to do, because it's quite hard (especially in C++) to come up with an example where a non-abstract base class is definitively the right thing to do. This is an important design point, and not one to pass over lightly - if you find yourself slicing an object, either deliberately or accidentally, quite likely your object hierarchy is wrong to start with. Either the base class shouldn't be used as a base class, or else it should have at least one pure virtual function and hence not be sliceable or passable by value.
So, any example I gave where an object is converted to an object of its base class, would rightly provoke the objection, "hang on a minute, what are you doing inheriting from a concrete class in the first place?". If slicing is accidental then it's probably a bug, and if it's deliberate then it's probably "code smell".
But the answer might be "yes, OK, this shouldn't really be how things are structured, but given that they are structured that way, I need to convert from the derived class to the base class, and that by definition is a slice". In that spirit, here's an example:
struct Soldier {
string name;
string rank;
string serialNumber;
};
struct ActiveSoldier : Soldier {
string currentUnit;
ActiveSoldier *commandingOfficer; // the design errors multiply!
int yearsService;
};
template <typename InputIterator>
void takePrisoners(InputIterator first, InputIterator last) {
while (first != last) {
Soldier s(*first);
// do some stuff with name, rank and serialNumber
++first;
}
}
Now, the requirement of the takePrisoners function template is that its parameter be an iterator for a type convertible to Soldier. It doesn't have to be a derived class, and we don't directly access the members "name", etc, so takePrisoners has tried to offer the easiest possible interface to implement given the restrictions (a) should work with Soldier, and (b) should be possible to write other types that it also works with.
ActiveSoldier is one such other type. For reasons best known only to the author of that class, it has opted to publicly inherit from Soldier rather than providing an overloaded conversion operator. We can argue whether that's ever a good idea, but let's suppose we're stuck with it. Because it's a derived class, it is convertible to Soldier. That conversion is called a slice. Hence, if we call takePrisoners passing in the begin() and end() iterators for a vector of ActiveSoldiers, then we will slice them.
You could probably come up with similar examples for an OutputIterator, where the recipient only cares about the base class part of the objects being delivered, and so allows them to be sliced as they're written to the iterator.
The reason it's "code smell" is that we should consider (a) rewriting ActiveSoldier, and (b) changing Soldier so that it can be accessed using functions instead of member access, so that we can abstract that set of functions as an interface that other types can implement independently, so that takePrisoners doesn't have to convert to Soldier. Either of those would remove the need for a slice, and would have potential benefits for the ease with which our code can be extended in future.
[*] because it is one. The last two lines below are doing the same thing:
struct A {
int value;
A(int v) : value(v) {}
};
struct B : A {
int quantity;
B(int v, int q) : A(v), quantity(q) {}
};
int main() {
int i = 12; // an integer
B b(12, 3); // an instance of B
A a1 = b; // (1) convert B to A, also known as "slicing"
A a2 = i; // (2) convert int to A, not known as "slicing"
}
The only difference is that (1) calls A's copy constructor (that the compiler provides even though the code doesn't), whereas (2) calls A's int constructor.
As someone else said, Java doesn't do object slicing. If the code you provide were turned into Java, then no kind of object slicing would happen. Java variables are references, not objects, so the postcondition of a = b is just that the variable "a" refers to the same object as the variable "b" - changes via one reference can be seen via the other reference, and so on. They just refer to it by a different type, which is part of polymorphism. A typical analogy for this is that I might think of a person as "my brother"[**], and someone else might think of the same person as "my vicar". Same object, different interface.
You can get the Java-like effect in C++ using pointers or references:
B b(24,7);
A *a3 = &b; // No slicing - a3 is a pointer to the object b
A &a4 = b; // No slicing - a4 is a reference to (pseudonym for) the object b
[**] In point of fact, my brother is not a vicar.