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.