Page 1 of 1

Compiler warning/Calling from a parent class to a child class

Posted: 11 Feb 2015 15:52
by Peter Muraya
Do you know of any coding method that would help the compiler to warn me if I might have forgotten to implement some EXPECTED predicate or fact -- rather than wait until run time to report a message to that effect?
Consider the following code:-

Code: Select all

interface reproduction      properties           type:string.      predicates           perform:(). end interface reproduction   class reproduction:reproduction end class   implement reproduction      facts           type:string:="UNDEFINED".      clauses           /*           The use of This keyword allows the general method of reproduction to behave differently for           ford different stages of reproduction -- which is great*/           perform():- stdio::write("The process being performed is ", This:type). end implement reproduction   /* ***************************************************************/ interface fertilization supports reproduction end interface   class fertilization:fertilization end class   implement fertilization inherits reproduction      facts           type:string:="FERTILIZATION".      clauses           new():-reproduction::new(). end implement fertilization   /* ***************************************************************/ interface incubation supports reproduction end interface   class incubation:incubation end class   implement incubation inherits reproduction      facts           /*           I HAVE FORGOTTEN TO IMPLEMENT THE PROPERTY reproduction::type:string FOR THE           INCUBATION CLASS*/      clauses           new():-reproduction::new(). end implement incubation   /* ***************************************************************/   implement main      clauses           run():-                console::init(),                Process = incubation::new(),                Process:perform(),                console::readchar()=_. end implement main   goal     mainExe::run(main::run).
The code will run correctly but with the message that "The process being performed is UNDEFINED" and no warning at all. I understand the behavior, resulting from inheritance. However, I would like some sort of warning as early as compile time. Any help?

Posted: 11 Feb 2015 21:16
by Martin Meyer
Hi Peter,

in below code the compiler will throw errors, when implementing the property type in class reproduction is forgotten.

Regards,
Martin

Code: Select all

interface reproduction_support      predicates           perform:(). end interface reproduction_support   class reproduction_support:reproduction_support end class   implement reproduction_support     clauses           perform():-             Reproduction = convert(reproduction, This),             stdio::write("The process being performed is ", Reproduction:type). end implement reproduction_support   /* ***************************************************************/ interface reproduction     supports reproduction_support     properties           type:string. end interface reproduction   /* ***************************************************************/ interface fertilization supports reproduction end interface   class fertilization:fertilization end class   implement fertilization inherits reproduction_support     facts         type:string:="FERTILIZATION".     /* below clause can be omitted.     clauses         new():-             reproduction_support::new().     */ end implement fertilization   /* ***************************************************************/ interface incubation supports reproduction end interface   class incubation:incubation end class   implement incubation inherits reproduction_support      facts         type:string:="INCUBATION".  % When this line is commented out, compiler throws errors.     /* below clause can be omitted.      clauses           new() :-             reproduction_support::new().     */ end implement incubation   /* ***************************************************************/   implement main      clauses           run():-                console::init(),                Process = incubation::new(),                Process:perform(),                console::readchar()=_. end implement main   goal     console::runUtf8(main::run).

Compiler warning/Calling from a parent class to a child class

Posted: 12 Feb 2015 11:48
by Peter Muraya
Thanks Martin; your input has helped me to code the following situation (which is part of a large project).....

Expressions of all types must be able to make copies of themselves, i.e., all must implement predicated copy()->expression. A secondary expression is made of children, which are expressions too. To make a copy of a secondary expression, you first make copies of the children; then use the children to make a copy of the secondary. So, all secondary expressions must implement these 2 predicates:-
children()->expression* and
copy(expression*)->expression.
Here is the code, including the magic statement I learnt from Martin.

Code: Select all

interface expression      predicates           copy:()->expression. end interface expression   class expression : expression end class expression   implement expression      clauses           copy()=_:-errorexit(0). end implement expression   interface secondary supports expression      /*      All classes that support the secondary interface must implement these predicates*/      predicates           children:()->expression*.           copy:(expression*)->expression. end interface secondary   class secondary : secondary end class secondary   implement secondary inherits secondary_support      clauses            children()=_:-errorexit(0).            copy(_)=_:-errorexit(0). end implement secondary   interface range supports expression end interface range   class range : range end class range   implement range      clauses           copy()=range::new(). end implement range     interface function supports secondary end interface function   class function : function end class function   implement function inherits secondary_support /* You will get a compile error if you forget to implement any of the secondary predicates here*/ end implement function     interface secondary_support  supports expression end interface secondary_support   class secondary_support : secondary_support end class secondary_support   implement secondary_support      clauses           copy()=Copy:-                /*                This conversion is the magic I have learnt from Martin*/                Secondary = convert(secondary, This),                  Children = list::map(Secondary:children(), {(Child)=Child:copy()}),                Copy = Secondary:copy(Children).   end implement secondary_support

Posted: 13 Feb 2015 10:01
by Thomas Linder Puls
I think all this code (in all 3 posts) contains peculiar constructions.

I think you use the Support pattern (which you have now made me document ;-)).

Posted: 13 Feb 2015 20:46
by Martin Meyer
So, applying the (perfectly explained!) support pattern to Peter's example, the code would look like below. Correct?

Regards
Martin

Code: Select all

interface reproduction      predicates           perform : ().     properties           type : string. end interface reproduction   /****************************************************************/   interface reproductionSite      properties from reproduction           type end interface reproductionSite   /****************************************************************/   interface reproductionSupport      predicates from reproduction           perform/0 end interface reproductionSupport   class reproductionSupport:reproductionSupport     constructors         new : (reproductionSite Site). end class   implement reproductionSupport     facts         site : reproductionSite.     clauses         new(Site) :-             site := Site.     clauses         perform() :-             stdio::write("The process being performed is ", site:type). end implement reproductionSupport   /****************************************************************/   interface fertilization     supports reproduction end interface   class fertilization:fertilization end class   implement fertilization     supports reproductionSite     inherits reproductionSupport     facts         type:string := "FERTILIZATION".     clauses         new() :-             reproductionSupport::new(This). end implement fertilization   /****************************************************************/   interface incubation     supports reproduction end interface   class incubation:incubation end class   implement incubation     supports reproductionSite     inherits reproductionSupport     facts         type:string := "INCUBATION".  % When this line is commented out, compiler throws errors.     clauses         new() :-             reproductionSupport::new(This). end implement incubation   /****************************************************************/   implement main      clauses           run() :-                Reproduction = incubation::new(),                Reproduction:perform(),                _ = console::readchar(). end implement main   goal     console::runUtf8(main::run).

Posted: 13 Feb 2015 23:47
by Thomas Linder Puls
Yes, very good. You have got the pattern absolutely correct.

I have taken this mail as a discussion of principles. Because actually the "reproduction" example is far to simple to require such a complex solution at all: You may notice that you can also move the type fact into the support class, and once you have done that the only thing left in the "fertilization" and "incubation" classes is the different initialization of the base class.

All in all, this example is better solved with a single class having two different constructors:

Code: Select all

interface reproduction predicates     perform : (). properties     type : string. end interface reproduction   class reproduction : reproduction constructors     newFertilization : ().     newIncubation : (). end class reproduction   implement reproduction facts     type : string.   clauses     newFertilization() :-         type := "FERTILIZATION".   clauses     newIncubation() :-         type := "INCUBATION".   clauses     perform() :-         stdio::write("The process being performed is ", type). end implement reproduction

Compiler warning/Calling from a parent class to a child class

Posted: 23 Feb 2015 10:21
by Peter Muraya
I now appreciate the value of "predicates from xxx" for implementing the Support pattern, but I don't understand the use of "supports" as used by Martin in the following code.

Code: Select all

implement incubation     supports reproductionSite %What does this do?     inherits reproductionSupport     facts         type:string := "INCUBATION".  % When this line is commented out, compiler throws errors.     clauses         new() :-             reproductionSupport::new(This). end implement incubation

Posted: 23 Feb 2015 12:52
by Thomas Linder Puls
It means that the incubation class (privately) supports the reproductionSite, and therefore
  • the implementation must implement the predicates, etc in reproductionSite, and
  • This is subsequently a reproductionSite
Due to the last bullet we can use This as site in the call reproductionSupport::new(This).

It is a fundamental part of the pattern that This is the site of the support class.