52// * var??; # name::name::name3::var или $name::name::name3::var - 3
53// * name::var??; # name::name::var или \\name::name::var - 2
54// * name::name::var??; # name::var или \\name::name::var - 2
55// * ::name::var??; # name::var или $name::var - 1
56// * ::var??; # ::var или $var - 0
57// * }
58// * }
59// * }
60// * Предположим, что: <<<<<<<<<<<<<<< НЕ АКТУАЛЬНО после изменения ситаксиса мароксов !!!!!!!!!!!!!!!!!!!!!!!!!! >>>>>>>>>>>
61// * :: - глобальный корень. Может быть заменен на @ или $
62// * @@ — родительская функция после её переопределния
63// * $$ — родительский объект
64// * тогда:
65// * $$.field - поле родительского класса
66// * @@() - вызов переопределенной функции текущего класса или области видимости
67// * @func() []= {@@() + 10}; # @func - 10
68// * ::name::name@func
69// * \\name::name::func - такая запись ненравится, но будет самой правильной и логичной, так как все остальные еще хуже для понимания и разбора
70// * @::name::name::func
71// * @::name::name@func
72// * ::name::name::func@@
73// *
74// * <<<<<<<<<<<<<<<<<< НОВАЯ КОНЦЕПЦИЯ >>>>>>>>>>>>>>>>>>
75// *
76// * Все объекты физически размещаюится в куче, но время их жизни определяется областью видимости.
77// * Объекты с декораторами $ обозначают локальные объекты (аналог "на стеке") и они удаляются по мере выхода из текущей области видимости.
78// * Объекты с декораторами @ являются модулями или его объектами, доступны из других частй программы и сохраняют состояние при выходе из текущей области видимости.
79// *
80// * Указание модуля (имя файла) @file или @dir.file или @dir1.dir2.file
81// * Указание объекта в модуле @file::var или @dir.file::ns::func() или @dir.file::ns::obj.field; @file::ns:type @file::ns$local ???
82// *
83// * Файл модуля загружается однократно при первом обращении и не выгружается до явной команды???
84// * @module <*>;
85// * @dir.module2 <*>; # Импорт всех функций модуля (кроме начинающихся на подчерк)
86// * @dir.module2 <ns::name::*>; # Импорт всех функций из указанной области имен (кроме начинающихся на подчерк)
87// * @dir.module2 <map=ns::name::*>; # Импорт всех функций из указанной области имен с переименованием (кроме начинающихся на подчерк)
88// * @dir.module2 <func1, func2=::module2::ns::name::func2>; # Импорт только конкретных функций + переименование
89// * @dir.module2 <_>; # Выгрузить модуль?????
90// *
91// * \\ns ::name::space::long@\
92// * \ns::name;
93// *
94// * @dsl{}; # Загрузка модуля с определниями макросов для DSL в самом начале любой программы?
95// *
96// * @@ - главный модуль
97// * @$ - текущий модуль
98// * $$ - родительский объект (базовый объект или переопределяемая функция)
99// * $0 - текущий объект (this)
100// *
101// * [@$.__main__] --> { # 1 или 0
102// *
103// * }
104// * @$.__@@__ := {}; # Деструктор модуля
105// * __@@__ := {}; # Деструктор модуля
106// *
107// * \destructor() { // _____ ::=
108// * }
109// *
110// *
111// * Дектораторы имен ($ и @) импользуютсядля указания области видимости и времени жизни объектов.
112// * $ - локальные объекты, размещаемые "условно" на стеке. Удаляются по мере выхода из текущей области видимости.
113// * Локальный объект скрывает другие локальные и глобальные объекты с таким же именем.
114// * @ - глобальные объекты, размещаемые "условно" в куче и их время жизни не зависит от текущей области видимости.
115// * Глобальный объект заменяет другой глобальный объект с таким же именем.
116// *
117// * Namespace позволяют использовать одинаковые имена объектов разделяя для них области видимости,
118// * но можно ли совместить и использовтаь namespace и дектораторы одновременно?
119// *
120// *
121// * Наследование
122// * Часто композиция класса более подходяща, чем наследование. Когда используйте наследование, делайте его открытым (public).
123// * Когда дочерний класс наследуется от базового, он включает определения всех данных и операций от базового. "Наследование интерфейса" - это наследование от чистого абстрактного базового класса (в нём не определены состояние или методы). Всё остальное - это "наследование реализации".
124// * Наследование реализации уменьшает размер кода благодаря повторному использованию частей базового класса (который становится частью нового класса). Т.к. наследование является декларацией времени компиляции, это позволяет компилятору понимать структуру и находить ошибки. Наследование интерфейса может быть использовано чтобы класс поддерживал требуемый API. И также, компилятор может находить ошибки, если класс не определяет требуемый метод наследуемого API.
125// * В случае наследования реализации, код начинает размазываться между базовым и дочерним классом и это может усложнить понимание кода. Также, дочерний класс не может переопределять код невиртуальных функций (не может менять их реализацию).
126// * Множественное наследование ещё более проблемное, а также иногда приводит к уменьшению производительности. Часто просадка производительности при переходе от одиночного наследования к множественному может быть больше, чем переход от обычных функций к виртуальным. Также от множественного наследования один шаг до ромбического, а это уже ведёт к неопределённости, путанице и, конечно же, багам.
127// * Любое наследование должно быть открытым (public). Если хочется сделать закрытое (private), то лучше добавить новый член с экземпляром базового класса.
128// * Не злоупотребляйте наследованием реализации. Композиция классов часто более предпочтительна. Попытайтесь ограничить использование наследования семантикой "Является": Bar можно наследовать от Foo, если можно сказать, что Bar "Является" Foo (т.е. там, где используется Foo, можно также использовать и Bar).
129// * Защищёнными (protected) делайте лишь те функции, которые должны быть доступны для дочерних классов. Заметьте, что данные должны быть закрытыми (private).
130// * Явно декларируйте переопределение виртуальных функций/деструктора с помошью спецификаторов: либо override, либо (если требуется) final. Не используйте спецификатор virtual при переопределении функций. Объяснение: функция или деструктор, помеченные override или final, но не являющиеся виртуальными просто не скомпилируются (что помогает обнаружить общие ошибки). Также спецификаторы работают как документация; а если спецификаторов нет, то программист будет вынужден проверить всю иерархию, чтобы уточнить виртуальность функции.
131// * Множественное наследование <интерфейсов> допустимо, однако множественное наследование реализации не рекомендуется от слова совсем.
132// *
133// * Для замены множественного наследования можно исопльзовать оператор утиной типизации (сравнения интерфейсов)
134// *
135// * Конструкторы и деструкторы классов
136// *
137// * Конструктор у класса может быть только один - и это обычная функция с именем класса.
138// * Конструктор должен вернуть созданный экземпляр класса, который ему передается в $0 аргументе.
139// * Другие аргументы соотетствуют передаваемым при вызове конструктора.
140// * Конструктор по умолчанию принимает произвольное количество аргументов (для переопределения значения у
141// * свойств по время вызова конструтокра) и возвращает аргумент $0, т.е. constructor(...) :- {$0($*)};
142// * Пользователський конструтор лучше переопреелять в теле класса через оператор присвоения значения,
143// * аналог override, т.е. constructor(...) **=** {...}; (чтобы исключить ошибки в написании имени функции).
144// * Конструторы базовых классов автоматически не вызываются, и если это требуется по логике работы,
145// * то вызовы конструторов базовых классов необходимо выполнять вручную, например так: $0 = $$.base_constructor();
146// *
147// * Деструктор класса определяется в теле класса анонимной функицей (имя функци подчерк),
148// * т.е. _() :- {} и по умолчанию отсутствует. Деструткоры базовых классов вызываются автоматически?????