There are Primitives and then there are Primitives
The Heron specification confuses some people at first glance because it only mentions a small
set of rather awkward looking literal primitive types: _bool, _int, _float, _char,
_string, _stream and _array. These types are not intended
for general use by a programmer hence the ugly naming convention. These are extremely basic types that don't even have any operators,
not even for assignment! These are the types of literal constants, such as: true, 5, 3.141, 'a', "Hello!". They
exist so that the standard library primitives can be compatible with the compiler's representation of literal constants. In other words
they exist so that programmers can write their own primitives.
The Heron standard library defines a set of primitive types for general purpose use such as:
Int, Float, Char, Bool, String, Array<type>. These types are compatible with the literal primitives, in that they
support implicit casting to and from the literal primitives, but they are objects like any other, with constructors, destructors, operators,
inheritance, etc. It is very important to note for those from a Java background, in Heron all objects are instantiatiable by value, just like Java primitive.
These means that the primitive types from the library do not have the overhead of dynamic allocation and deallocation that similarly named types
in Java have. This also means that there aren't two versions of the primitives.
This represents a real break from tradition for modern imperative programming languages. Typically primitives are not first class
objects, and follow their own special set of rules which are not applicable to types defined by the programmer. These kinds of restrictions
are purely artificial, and limit the versatility of a language severely.
Taking a Peek Under the Hood
The Heron standard library is no big mystery. It is easy to understand, adapt and modify.
Unlike other standard libraries I could name (*cough* STL *cough*).
I designed Heron so that it wouldn't take a team of gurus to write an efficient and useful
standard library. I expect that over time, multiple
standard libraries will appear with different characteristics, which make them more or less suitable
for different kinds of application domains. This is what I mean when I describe Heron as being
general purpose.
In order to demystify the primitives take a look at the current version of the Heron Bool class from the Heron Standard Library:
class Bool
{
public {
_init() {
// fdefault constructor
bool_assign(@m, false);
}
_op_assign(self x) {
// = operator
bool_assign(@m, x);
}
_op_assign(_bool x) {
// = operator
bool_assign(@m, x);
}
const _cast() : _bool {
// implicit type-cast operator
return m;
}
const And(self x) : self {
_bool ret;
bool_and(@ret, m, x);
return ret;
}
const Or(self x) : self {
_bool ret;
bool_or(@ret, m, x);
return ret;
}
const Not() : self {
_bool ret;
bool_not(@ret, m);
return ret;
}
}
fields {
_bool m;
}
}
Notice how Bool type interacts with literal _bool primitives (i.e. the true and false literal constants)
by supporting assignment from _bool and providing an implicit cast operator to _bool.
The only thing missing here are the the unary operator ! and the binary operators || and &&. These are defined outside of
the class as follows:
_op_and(Bool x, Bool y) : Bool { return x.And(y); }
_op_or(Bool x, Bool y) : Bool { return x.Or(y); }
_op_not(Bool x) : Bool { return x.Not(); }
For more examples, I recommend those interested to download the
latest Heron standard library and poke around. They aren't documented yet, but reading code is the best way
to learn and understand what Heron is all about.
|
|