I'd like to ask the following feature for MonkeyC, in Perl we call them Roles, in Java it is called Interface and Rust calls them Traits. I will refer to them as roles as I'm using Perl on a daily basis and thus is my preferred word for them. Maybe in MonkeyC we can call them bananas, and instead of implementing a banana we call it eat (its a joke btw). The thing I miss the most from the OO system of MonkeyC is a composition API. Roles allows us to not only depend on inheritance but also on composition, which IMO is a very powerful tool. It makes things easier if you don't want to keep extending existing classes and promotes code reuse across your classes. You don't need to extend a class just to get some nice features. Since MonkeyC is ducktyped, it seems that we also need a bigger pond so we can also have the ducks on our classes. Roles, interfaces or traits, whatever we name them, they are fun!
## in resources-fenix6/AppStorage.mc
using Toybox.Application.Storage as st;
(:fenix6)
role AppStorage {
function save(key, value) {
st.setValue(key, value);
}
function get(key) {
var val = st.getValue(key);
if (val == null) {
return 'I cannot be found';
}
return val;
}
}
## in resource-fenix5/AppStorage.mc
using Toybox.Application.AppBase as st;
(:fenix5)
role AppStorage {
function save(key, value) {
st.saveProperty(key, value);
}
function get(key) {
var val = st.getProperty(key);
if (val == null) {
return 'I cannot be found';
}
return val;
}
}
## In your config class
class Config extends DeviceConfig does AppStorage {
// logic here
}
## But AppStorage isn't always for Configuration
class SomethingNeedsToBeStored does AppStorage {
function someMethodNeedsStoringData() {
save("mykey", "Some data");
}
}
## Or as proposed with banana's:
banana Bar {
function foo();
}
class Monkey eats Bar {
function foo() {
Sys.println("I'm implementing Bar");
}
}
* Classes can implement more than one role.
In Perl Moo and Moose have access to everything and everyone from the consuming class, and they are writing a new OO system called Cor(inna). With that new OO system they don't think roles should have access to the instance variables. MoneyC knows private/protected and public. I think this makes it easier to shield off things from roles. A point for discussion I think.
* Roles don't have access to private variables of a class
* Roles don't have access to protected variables of a class(?)
* Roles have access to public variables of a class(?)
* Roles should be able to "require" methods for classes that implement them, eg.
role Foo {
// Perl style
requires bar;
// or java style
function bar();
// This allows us to do this:
public function foo() {
var jaja = bar();
return baz(jaja);
}
function baz(arg) {
return true;
}
}
// Now the impementing class can use foo, baz
class Thing does Foo {
// a whole lot of logic here
}
// Somewhere else
var thing = new Thing();
thing.foo()