Original in Russian: http://programmingmindstream.blogspot.ru/2015/07/blog-post_28.html
Briefly. I’ve made a wonderful thing – words redefining.
It allows Duck-Typing of a kind, though based on static type-checking, if possible.
Let us have:
Function A works with object of TObjectA type.
Function B works with object of TObjectB type.
Therefore, we can write as follows:
Thus, we can call in this way:
We can also write symmetrically:
In this case, we can write:
The examples given are in Run-Time.
However, setting the IMMEDIATE attribute to the words redefined and CompileValue instead of direct calls results in statistic overriding which depends on the parameters types and it is compilable.
Why do we need it?
We need it in order to adapt the object model for those people who are not eager to know details about specific object model.
For example, it can be used by testers.
For them TEdit, TvgEdit and TsomeOtherEdit look as like as peas in a pod.
There are also other people who understand the system in terms of GUI and there are other “generic objects” that are not classified similarly to the project classification.
The issue relates to the primitive types like INTEGER and STRING or interfaces as well.
Quite understandable is the fact that this “mapping” can be done in different ways in various “specific axiomatics”. It is not viewed by the testers similarly to the way other people see it.
It depends on the set of used dictionaries.
Moreover, mapping differs for various system layers.
Even more so since the layers of the system are separated on the principle: “we can only see our neighbours at a lower or a peer layer”.
It is obvious that REDEFINE controls “generic signatures” for covariation.
Notice that REDEFINE is not OVERRIDE.
REDEFINE is not integrated inside the classes but keeps “on the side” for “outside users”.
It is like a helper or categories in Objective-C.
Let me remind you that each abstraction layer can have different REDEFINE.
These people aim to develop a pre-processing program - Link. Why can't an interface have class methods? (most of the links are in Russian)
I quote:
"Yes, I get that, I guess I was stuck in the mindset of the Java default method and the static method. This is sort of a mix between the two.
The default methods are way cool.
Interface helpers and interface operator overloading would go a long way towards achieving these goals.
(Then there's virtual methods for records, method inheritance for records, allowing multiple class helpers in scope, allowing
inheritance for record helpers).
I'm temped to write a pre-processor to add these things myself (borrow some syntax from oxygene or SMS and transparantly alter the sourcecode before compilation)."
Too bad, I am not able to get my opinion out to these guys which is they should work with models and “script extensions” instead of dealing with “pre-processors”. They are compilable at least into a “threaded code”.
I would also advise to integrate “diferent axiomatics transformations” at a higher level compared to the “target language code”.
P.S. It is clear that using these “tricks” can result in an “extraordinary messed” code, but i do not focus on people who love to “shoot off their own legs”.
You can shoot off your legs using Delphi or C++ or Haskel as well.
Not to mention Python and the slots...
It is important to understand what you do and be reluctant to “shoot”.
It is also obvious that all REDEFINES are found considering all USES and EXPORTS - Briefly. I exported the dictionaries.
If it is not possible to define the word PRECISELY (you can not choose one), the error message is popped up.
In this case we classify it as UNIT :: WORD.
It is totally equal to namespace in C++.
Oops..
Real life example:
Briefly. I made axiomatic description partly on Delphi, partly on scripts
Briefly. I’ve made a wonderful thing – words redefining.
It allows Duck-Typing of a kind, though based on static type-checking, if possible.
Let us have:
UNIT TObjectA // - defines a unit for TObjectA USES axiom:TObjectA // - uses TObjectA axiomatics ; EXPORTS axiom:TObjectA // - exports axiomatics of TObjectA to units that use it INTEGER FUNCTION A TObjectA IN anObj // - object of TObjectA type ... Result := anObj SomeCodeA // - calls SomeCodeA method on anObj instance ; // A ... UNIT TObjectB // - defines a unit for TObjectB USES axiom:TObjectB // - uses of TObjectB axiomatics ; EXPORTS axiom:TObjectB // - exports axiomatics of TObjectB to units that use it INTEGER FUNCTION B TObjectA IN anObj // - object of TObjectB type ... Result := anObj SomeCodeB // - calls SomeCodeB на экземпляре anObj ; // A
Function A works with object of TObjectA type.
Function B works with object of TObjectB type.
Therefore, we can write as follows:
USES TObjectA // - uses axiomatic of TObjectA and axiom:TObjectA TObjectB // - uses axiomatic of TObjectB and axiom:TObjectB ; REDEFINE : A OBJECT IN anObj // - abstract object if ( anObj Is TObjectB ) then // - object of TObjectB type ( anObj B ) // - calls method B else ( anObj inherited ) // - calls the "MAIN" method of TObjectA::A ; // A
Thus, we can call in this way:
TObjectA VAR x1 TObjectB VAR x2 ... x1 A // - calling of TObjectA::A method x2 A // - calling of TObjectB::B method
We can also write symmetrically:
USES TObjectA // - uses axiomatic of TObjectA and axiom:TObjectA TObjectB // - uses axiomatic of TObjectB and axiom:TObjectB ; REDEFINE : B OBJECT IN anObj // - abstract object if ( anObj Is TObjectA ) then // - object of TObjectA type ( anObj A ) // - calls method B else ( anObj inherited ) // - calls the "MAIN" method of TObjectB::B ; // B
In this case, we can write:
TObjectA VAR x1 TObjectB VAR x2 TObjectA VAR x3 TObjectB VAR x4 ... x1 B // - calling of TObjectA::A method x2 B // - calling of TObjectB::B method x3 B // - calling of TObjectA::A method x4 B // - calling of TObjectB::B method
The examples given are in Run-Time.
However, setting the IMMEDIATE attribute to the words redefined and CompileValue instead of direct calls results in statistic overriding which depends on the parameters types and it is compilable.
Why do we need it?
We need it in order to adapt the object model for those people who are not eager to know details about specific object model.
For example, it can be used by testers.
For them TEdit, TvgEdit and TsomeOtherEdit look as like as peas in a pod.
There are also other people who understand the system in terms of GUI and there are other “generic objects” that are not classified similarly to the project classification.
The issue relates to the primitive types like INTEGER and STRING or interfaces as well.
Quite understandable is the fact that this “mapping” can be done in different ways in various “specific axiomatics”. It is not viewed by the testers similarly to the way other people see it.
It depends on the set of used dictionaries.
Moreover, mapping differs for various system layers.
Even more so since the layers of the system are separated on the principle: “we can only see our neighbours at a lower or a peer layer”.
It is obvious that REDEFINE controls “generic signatures” for covariation.
Notice that REDEFINE is not OVERRIDE.
REDEFINE is not integrated inside the classes but keeps “on the side” for “outside users”.
It is like a helper or categories in Objective-C.
Let me remind you that each abstraction layer can have different REDEFINE.
These people aim to develop a pre-processing program - Link. Why can't an interface have class methods? (most of the links are in Russian)
I quote:
"Yes, I get that, I guess I was stuck in the mindset of the Java default method and the static method. This is sort of a mix between the two.
The default methods are way cool.
Interface helpers and interface operator overloading would go a long way towards achieving these goals.
(Then there's virtual methods for records, method inheritance for records, allowing multiple class helpers in scope, allowing
inheritance for record helpers).
I'm temped to write a pre-processor to add these things myself (borrow some syntax from oxygene or SMS and transparantly alter the sourcecode before compilation)."
Too bad, I am not able to get my opinion out to these guys which is they should work with models and “script extensions” instead of dealing with “pre-processors”. They are compilable at least into a “threaded code”.
I would also advise to integrate “diferent axiomatics transformations” at a higher level compared to the “target language code”.
P.S. It is clear that using these “tricks” can result in an “extraordinary messed” code, but i do not focus on people who love to “shoot off their own legs”.
You can shoot off your legs using Delphi or C++ or Haskel as well.
Not to mention Python and the slots...
It is important to understand what you do and be reluctant to “shoot”.
It is also obvious that all REDEFINES are found considering all USES and EXPORTS - Briefly. I exported the dictionaries.
If it is not possible to define the word PRECISELY (you can not choose one), the error message is popped up.
In this case we classify it as UNIT :: WORD.
It is totally equal to namespace in C++.
Oops..
Real life example:
Briefly. I made axiomatic description partly on Delphi, partly on scripts
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Library "ScriptEngine$VT" // Unit: "vtComboBoxWordsPack.rc.script" // Resource scripts (.rc.script) // Generated from UML model, root element: ScriptKeywordsPack::Class Shared Delphi::ScriptEngine$VT::vtComboBoxWords::vtComboBoxWordsPack // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //#UC START# *54EC8C7C011Eimpl* // Decorators of words that work with combo USES axiom:ComboBox axiom:ComboTree ; REDEFINITION : pop:ComboBox:DropDown OBJECT IN aCombo if ( aCombo Is class::TvtComboTree ) then ( aCombo pop:ComboTree:DropDown ) else ( aCombo inherited ) ; // pop:ComboBox:DropDown REDEFINITION : pop:ComboBox:GetItemIndex OBJECT IN aCombo if ( aCombo Is class::TvtComboTree ) then ( aCombo pop:ComboTree:GetItemIndex ) else ( aCombo inherited ) ; // pop:ComboBox:DropDown REDEFINITION : pop:ComboBox:IndexOf OBJECT IN aCombo if ( aCombo Is class::TvtComboTree ) then ( aCombo pop:ComboTree:IndexOf ) else ( aCombo inherited ) ; // pop:ComboBox:DropDown REDEFINITION : pop:ComboBox:SaveItems OBJECT IN aCombo if ( aCombo Is class::TvtComboTree ) then ( aCombo pop:ComboTree:SaveItems ) else ( aCombo inherited ) ; // pop:ComboBox:SelectItem REDEFINITION : pop:ComboBox:SelectItem OBJECT IN aCombo if ( aCombo Is class::TvtComboTree ) then ( aCombo pop:ComboTree:SelectItem ) else ( aCombo inherited ) ; // pop:ComboBox:SelectItem REDEFINITION : pop:ComboBox:SetItemIndex OBJECT IN aCombo if ( aCombo Is class::TvtComboTree ) then ( aCombo pop:ComboTree:SetItemIndex ) else ( aCombo inherited ) ; // pop:ComboBox:SetItemIndex //#UC END# *54EC8C7C011Eimpl*And some other example:
// Decorators USES axiom:DocEditorWindow ; : IsNeedSaveDocument OBJECT IN aWnd if ( aWnd Is class::TDocEditorWindow ) then ( aWnd DocEditorWindow:IsNeedSaveDocument ) else ( false ) ; // pop:ComboBox:DropDown
По мне - хороший перевод.
ОтветитьУдалитьА людям то - нравится.. Плюсы ставят...
ОтветитьУдалить@Ingword а что там в G+? Опять ругают поди?
Дайте ссылку на публикацию.
УдалитьIt seems to me that people like it.
ОтветитьУдалитьIt's pity that I don't know English to discuss this matter.
https://plus.google.com/u/0/113567376800896602748/posts/Lppb28z3oaD
Stefan Glienke29 июля 2015 г.+2
1
2
I thought about extending the Delphi language by preprocessing as well. And we even had such things already (like DLangExtensions). Getting something like that running is not the issue.
What's an issue though unfortunately is getting such code work inside the IDE. Nothing will work: no code completion nor refactoring (or completely messing up the code), nor proper tooltips or code navigation.
Перевести
Lars Fosdal29 июля 2015 г.+3
4
3
preprocessors are more trouble than they're worth. doubly so if not actually supported.
Перевести
David MillingtonВчера в 13:50+1
0
1
It's a sign of how much language development we as a community want, though. Perhaps we can get some of these improvements if we ask loudly enough?
Перевести
Johan BontesВчера в 23:02
1
Ответить
+Stefan Glienke
The refactoring we can get working using DelphiAST. Ditto for code completion. That still leaves the huge issue of debugging though. I wonder if it's possible to manipulate the MAP file.
Unfortunatly by that time you've almost rebuilt the IDE.