Object Orientif
Jargon Show-off
Strictly speaking, Jaskell is a lazy, dynamically typed, impure functional language.
By "lazy", we mean that function calls in Jaskell are call-by-need.
By "dynamically typed", well, it basically means to me that this language is easy enough even I can write it.
By "impure", we mean that side-effect is allowed. (which is different than Haskell)
By "functional", we mean that we have functions, higher-order functions.
Now, as our functional camp's revenge for Ruby's, Python's stealing of our precious functional idea, Jaskell also steals the idea of Object-Orientif from the enemy.
By "Object-Orientif", I mean it is not exactly what you would expect from a Object-Oriented language. To name a few, you cannot create class in Jaskell (you can call Java class from within Jaskell though). It is a functionalized version of OO.
Object-Orientif
Although not exactly the same as the Java OO, Jaskell does provide most of the essenses of OO. Let's enumerate:
- Encapsulation
Using tuple, jaskell allows information to be encapsulated in a tuple and hidden from the outside world. In the following Java version encapsulation, an underlying array, the begin index and the length are encapsulated in the SafeArray class and hidden from the outside:
class SafeArray{
private final Object[] arr;
private final int begin;
private final int len;
public SafeArray(Object[] arr, int len){
this.arr = arr;
this.begin = begin;
this.len = len;
}
public Object at(int i){
if(i<0 || i>=len){
throw new ArrayIndexOutOfBoundsException(i);
}
return arr[begin+i];
}
public int length(){
return len;
}
}
The same idea can be implemented using tuple as:
newSafeArray arr begin len = {
length = len;
at i = if i<begin || i>=len then throw $ ArrayIndexOutOfBoundsException.new[i] else arr[begin+i];
}
Just shorter.
- Inheritance
In Java, we can extend SafeArray to add a new method:
class TypeSafeArray extends SafeArray{
private Class element_type;
public String getElementType(){return element_type;}
public MySafeArray(Object[] arr, int begin, int len, Class type){
super(arr, begin, len);
this.element_type = type;
}
}
This can be done using tuple as:
newTypeSafeArray arr begin len type = newSafeArray(arr,begin,len).{getElementType=type}
Shorter too.
- Polymorphism
In Java, we could override "at" method by checking the return value's type:
class TypeSafeArray extends SafeArray{
private Class element_type;
public String getElementType(){return element_type;}
public MySafeArray(Object[] arr, int begin, int len, Class type){
super(arr, begin, len);
this.element_type = type;
}
public Object at(int i){
return checkType(super.at(i));
}
private Object checkType(Object r){
if(element_type.isInstance(r)) return r;
else throw new ClassCastException();
}
}
Using tuple, this is also doable:
newTypeSafeArray arr begin len type = let
super = newSafeArray(arr,begin,len);
checkType r = if r `instanceof type then r else throw $ ClassCastException.new[];
super.{
getElementType=type;
at i = checkType(super.at i);
};
end
- Mixin
In Java, it is not supported to mix the members of two independent classes together. It is doable in other OO languages such as Ruby. Jaskell allows mixin with two simple functions located in the "jaskell.tuple" namespace. The 'includes' function simply combines members from two tuples with the 'this' variable for each member pointing to their original tuple:
mixin = namespace1 `includes namespace2
The 'extends' function combines members from two tuples and adjust the 'this' variable to the mixin'ed tuple:
mixin = namespace1 `extends namespace2
Well. I guess that's all about object-orientif. 