Re: Liskov Substitution Principle and Abstract Factories

From: Mark Nicholls (nicholls.mark_at_mtvne.com)
Date: 01/14/05


Date: Fri, 14 Jan 2005 13:38:40 -0000


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:sgrzhmyjkxej$.1705lg184pkh2.dlg@40tude.net...
> On Thu, 13 Jan 2005 15:52:20 -0000, Mark Nicholls wrote:
>
> > "smilemac" <smilemac88@yahoo.com> wrote in message
> > news:cs63m2$o221@imsp212.netvigator.com...
> >>
> >> "Mark Nicholls" <nicholls.mark@mtvne.com> ׫Œ
> > ‘ì¶à]¼þЄ:34n9jgF4br4hbU1@individual.net...
>
> >>> OK, I suppose what I'm doing (which I accept is probably dubious i.e.
> >>> wrong)
> >>> is assuming the contract for A is pretty much fully defined i.e. for
all
> >>> possible inputs into a method in A, there is a specifically defined
> >>> output.
> >>>
> >>> i.e.
> >>>
> >>> f(x) = x*x given X>0
> >>> f(x) = -x*x given X<= 0
> >>>
> >>> rather than
> >>>
> >>> g(x) = x*x : X>0
> >>> g(x) = undefined:else
> >>>
> >>> it's pretty easy to create a substitutable function for g, finding one
for f
> >>> is a bit harder,
> >>
> >> Maybe we can also get a substitute function like below,
> >>
> >> s(x) = x*x : x>0
> >> s(x) = a*a + b*b : x=a+bi (a complex number)
> >> s(x) = -x*x : x<=0
> >>
> >> (NOTE: the postcondtion, x*x or -x*x is not possible to have any
subset.)
> >
> > yes....interesting.....subtyping at work in something more well defined
(or
> > at least concensual understandable)...some pennies are dropping.
> >
> > note if a precondition of f(x) was that x member real numbers, this
> > precondition does not exist on s(x).
> >
> >>> now add reflection
> >>>
> >>> f(x) = x*x given X>0
> >>> f(x) = my function name : given X<= 0
> >>>
> >>> i.e. f(0) = 'f'
> >>>
> >>> try the same trick......
> >>>
> >>> h(x) = x*x given X>0
> >>> h(x) = my function name : given X<= 0
> >>>
> >>> i.e. h(0) = ' h'
> >>>
> >>> oh dear.
> >>>
> >>> so there can be no substitutable objects that expose specific type
> >>> information (given my error).
> >>
> >> It depends on what your postcondition is, fixed character 'f'or
"function
> >> name"? If latter, the above code ir correct.
> >
> > I meant the function name.
> >
> > If I can get Dmitry to talk in the above terms I may understand him.
>
> I don't understand your example. But I'll try.

It's probably too informal.

>
> When you define f you have:
>
> 1. to define the type domain set. Say R, the set of real numbers.

yep.

>
> 2. to define the operations on the type. That would be "*", ">", "<=", "-"
> (unary) and 0. Note that 0 is a literal it could also be a function. For
> example real 0.0 is not integer 0 is not complex 0.0+i0.0 is not an empty
> set etc. So 0 is a function: "const R 0 () const".

? why is it a function ?
Can we say it isn't, it isn't in maths, it's constructed in exactly the same
way as all other numbers (though it is special).

>
> Doing 2 we have to decide which parameters and results are covariant vs.
> contravariant. For example, does "*" return contravariant R or covariant
> derived type? Same with "-".

you'll have to define terms, contravariant and covariant in this context.

>
> Only now you could formulate the contract of f in the terms above, and
> remember the covariance issue. Basically it controls in which of its
> parameters and results f will be a method (dispatching) of R. There are
> four variants!

OK, you'll have to explain terms and above...in a 'type theory for dummy's
sort of way'.

>
> It is not substitutability yet. So you define another type, say Q,
> rational.
>
> 1. The domain set is Q
>
> 2. The type is a subtype of R. For this we define the mappings between the
> domain sets.

We can defined mappings, some obvious, some not, lets go with the obvious
one i.e. 0.25 => 1/4

it's a subset (in the sense of a injective isomorphism exists one way, *but
not the other*).......I question subtype...because I no longer know what it
means.

the set of R is constructed logically from the set of Q......so to make Q a
subtype of R is actually logically dangerous........I am so confused by this
whole thing that I am now incapable of seeing if Q should be a subtype of R
or vice verca.....or neither.

>
> 2.a. Q->R, this mapping allows us to substitute a q where r is expected.

this down not work...... I cannot substitute a member of Q for root 2.

>
> 2.b. R->Q, this mapping allows us to acquire a result of q where r
> returned.

and neither does this! if I expect root 2 as a result, I cannot substitute a
Q.

>
> With 2.b we have problems to expect.

I have problems with both.

But maybe I am confusing implementation with specification again!?!

>
> 3. We have to see which operations of R we can inherit, redefine etc. This
> depends on covariance/contravariance. In case of "*" and "-" there are no
> problems to expect with covariance. As for f, it will be substitutable in
> any form except for:

unfortunately I don't understand these terms.

>
> Q f (R) // f is a method in the result and a non-method in the parameter
>
> i..e. covariant result, contravariant parameter. With this f, Q is not an
> LSP-subtype of R. Or equivalently: Q is not substitutable for R in f.
>
> --

We'll have to go back to basics....or you can give up on me.

I like the domain though as mathematics is unambigious, and we can talk
rigourously as to what makes Q a subtype of R or not.