<-- back

Object oriented Programming

OOP in NAL shall be single inheritance.

Basic class/struct definition

NAL: // Example uses a base type (just for example purposes): BaseType = module; .drink = f32 (mutable this, f32 percentage); // pure virtual Bottle = module : BaseType; volume = f32(1.); // auto initialized value fluid = string; // uninitialized value broken = bool(false); // auto initialized value .constructor = (mutable this, fluid string) { // public method .fluid = fluid; // dot operator, same as this.fluid } .create (string fluid) { // public static function return new Bottle(fluid); } .destructor = (mutable Bottle) { // do destructor stuff. } .drink = f32 (mutable this, f32 percentage) { BaseType.drink(percentage); volume *= 1. - percentage; return volume; } dropOnTheFloor = (mutable this) { broken = true; volume = 0.; } ... implementation part { bottle1 = Bottle("orange juice"); // using constructor bottle2 = Bottle.create("orange juice"); // using static method fluidLeft = bottle1.drink(0.44); } C: struct Bottle { BaseType _base; float volume; const char* fluid; bool broken; }; float _nal_Bottle_constructor(Bottle* this, const char* fluid) { this->volume = 1.; strncpy(this->fluid, fluid, strlen(fluid)); // todo: compiler must check for const. this->broken = false; } float _nal_Bottle_destructor(Bottle* this) { // do destructor stuff. } float _nal_Bottle_drink(Bottle* this, float percentage) { _nal_BaseType_drink((BaseType*)this); this->volume *= 1. - percentage; return this->volume; } float _nal_Bottle_dropOnTheFloor(Bottle* this) { this->broken = true; this->volume = 0.; } { Bottle bottle; _nal_Bottle_constructor(bottle, "orange juice"); float fluidLeft = _nal_Bottle_drink(&bottle, 4.44f); }

Discussion

Extensions

All types shall be extensible by allowing the programmer to define Extensions and implement them. When implementing an extension inside of the implementation file where the type is declared, one has access to its private properties. Outside, only the public properties are available.

Advantage: An extension can be added at any place from anybody. It allows for rapid development of new features. A class which is not accessible privately can at least be molded into an interface which supports the methods of the extension. This is as easy as defining a method with a specific type for the this pointer:

NAL: Refillable = module; .refill (mutable this); // no implementation = pure virtual ... extension if in the same file as definition of module Bottle: .refill(mutable Bottle this) { // this now refers to a Bottle if(broken) // access to private member printf("Cannot refill."); else volume = 1.; // access to private member } ... implementation part { bottle = Bottle("IceTea"); bottle.drink(.5); bottle.refill(); } C: float _nal_Refillable_extends_Bottle_refill(Bottle* this) { if(this->broken) printf("Cannot refill."); else this->volume = 1.; } { Bottle bottle; ... // instantiation as above + calling drink _nal_Refillable_extends_Bottle_refill(&bottle); }