Posted on Mar 24, 2023
I pushed to the public repositories the mbfl changes that implement data structures; it is nothing flashy; I have enough features that I can start to use it and see how it goes.
I already know that I will probably change the identifiers in the api, but for now that is the
way it is: I started with the idea of implementing a bit of metaobject protocol, with data
structures representing slots (their type, how to access values) but then I did nothing of it; but
it looked fun to call the core object class mbfl_standard_object
and its metaclass
mbfl_standard_class
. Ha! Ha!
I will probably change them to mbfl_default_object
and mbfl_default_class
and leave
mop ambitions to an external library.
The way it is now, it feels similar to the r6rs records syntactic layer, but simpler; we can define a class and we get: a constructor function, a predicate function, accessor and mutator functions for each field. There is no composition of object constructors: if we want a constructor that calls its superclass constructor and so on, we have to implement it ourselves.
Here is how it looks:
mbfl_standard_class_declare(color) mbfl_standard_object_declare(dark_slate_blue) mbfl_standard_class_define _(color) _(mbfl_standard_object) 'color' red green blue color_define _(dark_slate_blue) 72 61 139 declare RED color_red_var RED _(dark_slate_blue) "$RED" ⇒ 72
Notice the fancy underscore syntax:
_(dark_slate_blue) → mbfl_datavar(dark_slate_blue)
it makes the code so much more readable! I love it! Use with care!
All the accessors store the field value in a given Bash variable; there is no dot–syntax or similar.
Both the class constructor mbfl_standard_class_define
and the instance constructors like
color_define
accept positional parameters; the “rest” parameters are, respectively, field
names and field values. I’m not happy with it: in my experience with Scheme languages, rest
parameters make it harder to maintain an api2. I could use an index
array:
mbfl_declare_index_array_varref(color_field_names, (red green blue)) mbfl_standard_class_define _(color) _(mbfl_standard_object) 'color' _(color_field_names)
but there would be more to type; I could define an m4 macro to make it a bit more descriptive and take away some characters:
mbfl_standard_field_specs_declare(color_field_names, red, green, blue) mbfl_standard_class_define _(color) _(mbfl_standard_object) 'color' _(color_field_names)
this looks similar to what one would code in the C language: if we want to pass a list to a function, we have to define an array. I do not like having more to type, but I also want better maintainability. I will think of it.
Single inheritance is supported:
mbfl_standard_class_declare(transparent_color) mbfl_standard_object_declare(trans_dark_slate_blue) mbfl_standard_class_define _(transparent_color) _(color) 'transparent_color' transparency transparent_color_define _(trans_dark_slate_blue) 72 61 139 50 declare RED TRANSPARENCY transparent_color_red_var RED _(trans_dark_slate_blue) transparent_color_transparency_var TRANSPARENCY _(trans_dark_slate_blue) "$RED" ⇒ 72 "$TRANSPARENCY" ⇒ 50
Right now there are no class attributes, but I want them. For example: some classes are not meant to be instantiated; some classes are not meant to be subclassed.
For quite some time now I’ve had an Emacs file which adds to shell-script
mode some font
locking of mbfl functions and macros; I cannot live without it anymore; I have not distributed
it. It all amounts to prepare a call to font-lock-add-keywords
at the top–level.
I have been using gnu Emacs for 25+ years, but I am still a beginner when it comes to Emacs Lisp coding; I am sure the code is not of great quality.
I am at a point in which including this code in mbfl’s package makes sense. I will do it.
The code grows complex and I feel the need to have some sort of error descriptor; it is impossible
to have exceptions in Bash; in some situations we can just print an error message to stderr
and
hope to catch it when running a test suite.
I don’t know what to do.
While developing, the api is still unstable and we may change frequently the parameters to function calls.