For making the idea clear, we now can define the base node type (class), and provide some code for the minimal node implementation:
class Object:
tag = "object"
def __init__(self, V):
## type/class tag
self.tag = self.__class__.tag
## scalar value: object name, string, number,..
self.val = V
## slots = attributes = associative array = env (var bindings)
self.slot = {}
## nested AST = vector = stack = queue = any ordered container
self.nest = []
## parent nodes references
self.par = []
## unique global storage identifier (can be fast 32-bit hash over *content*)
self.gid = id(self) # self.sync() | [xx]hash(self)
Elixir: A primer for object-oriented programmers
As a functional programming language, Elixir doesn’t have a concept of classes, objects or instances.
defmodule MetaL do
@spec object(any, any) :: %{tag: any, val: any, slot: %{}, nest: []}
def object(tag \\\\ :object, val) do
%{tag: tag, val: val, slot: %{}, nest: []}
end
end
This variant of object representation too verbose as the Map
structure provides named addressing to its field and an ability to have multiple fields. Elixir runs over the Erlang's BEAM machine which has the property that Map
runs slower than other data containers.
def object(val) do
{:object,val,%{},[]}
end
iex(3)> M.object(:xxx)
{:object, :xxx, %{}, []}
While BEAM-based languages do not have any support for OOP and programming in objects, we should select the proper way to implement this concept ourselves.
Links section in README · Issue #8 · wojtekmach/oop
more:
Elixir: A primer for object-oriented programmers
Erlang: Dispatching closures (OOP style object implementation in FP)