Re: An alternative to possreps

From: David BL <davidbl_at_iinet.net.au>
Date: Tue, 7 Jun 2011 01:05:12 -0700 (PDT)
Message-ID: <7aad0e35-fddf-4445-b7af-7bf9554ca5e3_at_z7g2000prh.googlegroups.com>


On Jun 6, 9:26 pm, Erwin <e.sm..._at_myonline.be> wrote:
> On 31 mei, 11:54, David BL <davi..._at_iinet.net.au> wrote:
>
>
>
> > Is there anything in TTM that prohibits one from making every type a
> > dummy type? Would that make it essentially the same approach which
> > I've described?
>
> Not "in TTM". What prohibits this is "reality", I'd rather say.
>
> If you're interested in a subset of T, then you can't define this
> subset by means of UNIONs involving T.

Yes, but that is not a problem. Let Ellipse be a "dummy type". If you're interested in a subtype Circle of Ellipse then you can simply declare Circle as another dummy type. I'm assuming you can declare subtype relationships between dummy types. In my approach you use these declarations:

    type Ellipse;
    type Circle;
    Circle isa Ellipse;

I consider types like Circle and Ellipse to be defined by their operators. In that sense there is no problem treating all types as "dummy types".

> And if you're interested in UNIONing things together because that
> union somehow is of interest to you, then you still must be given some
> things to union. Somewhere down the line, some non-dummy types must
> be just given.

That might be true in D&D, but I see no reason for that in principle. Operators are sufficient for allowing (logical) representations of values (using nested expressions of operator invocations). E.g. the operator

    Circle <--- circle(Point centre, Real radius) on radius >= 0;

allows for circle values to be (logically) represented without any POSSREP.
> I didn't look at the details of your proposed approach because you
> said yourself that it is neither more nor less powerful than TTM
> possreps.

As a minimum I'm suggesting POSSREPS are unnecessary and don't add anything useful. But I'm now thinking my approach is more powerful (see below on algebraic types).

> > > > 4. Can preconditions be declared on operators? If so would it be true
> > > > to say it seems to overlap in purpose with CONSTRAINT declarations?
>
> > > Preconditions such as "the argument value for any LN(FLOAT) invocation
> > > must be >=0" ?
>
> > Yes. Eiffel uses that term. I think "domain" would be a more
> > conventional term, but the database community has often used 'domain'
> > for 'type'. I would treat ln(0) as undefined.
>
> > > D&D's position here can be summarized, I think, as "this issue must be
> > > addressed by defining the proper type".
>
> > > (And note that this approach does not require type inheritance ! Even
> > > without type inheritance, it is not impossible to define a (distinct)
> > > type STRICTLYPOSITIVEFLOAT. If you can _prove_ to them that this
> > > approach is unacceptably impractical, please please do !)
>
> > I agree it seems impractical, and selectors are treated differently to
> > other operators (only selectors have constraints).
>
> Not quite accurate. Selectors do not "have constraints". Possreps
> do. As a consequence, of course whenever a selector invocation is
> made, the arguments given must satisfy that constraint, or an
> exception results. But I don't see how this is different from "non-
> selector" operators such as LN(FLOAT) ! There too, the arguments
> effectively passed must satisfy a certain predicate. I find it only a
> psychological difference that in the case of selectors, the arguments'
> predicate is declared as part of the construct that gave rise to the
> existence of the selector operator, whereas in the case of "regular"
> operators, that predicate is declared in the documentation, or in the
> metadata, or in the worst case, it is merely implied by the operator's
> implementing code.

You appear to be contradicting yourself in saying both:

(a) "this issue must be addressed by defining the proper type"; and

(b) the arguments to LS(FLOAT) must satisfy a certain predicate.

I took (a) to mean that at the logical level of discourse, the argument to the natural logarithm operator would be something like POSITIVEREAL instead of REAL and therefore there is no need to express additional constraints on the operator, or the concept of exceptions (which should be obvious anyway because that is an implementation concept).

I'm not sure what distinction you're making when saying POSSREPS have constraints whereas selectors don't. Either way some selectors have conditions on their arguments that are not simply implied by the types of the arguments. This is different from the case of the natural logarithm operator that takes a POSITIVEREAL.

> > Also, what happens with non-separable constraints on operators with
> > multiple arguments? E.g. foo(x,y) is defined on x+y > 0. Is one
> > forced to make it into a unary operator on a type which can express
> > that constraint on its POSSREP?
>
> No, one is not forced to do that.
>
> OPERATOR FOO(X INT, Y INT) RETURNS ... ;
> IF (X+Y)<=0 RAISE ILLEGALARGUMENTEXCEPTION("...");
> /* note that dealing with exceptions, or how to raise them, is not
> part of TTM */
> ...
> END OPERATOR;
I take that to mean that one can choose to ignore explicit specification of the constraint at the logical level of discourse. I agree it is possible to do that.

> > > > 5. Can additional POSSREPS be added to a type without modifying the
> > > > original declaration of that type? Can a new supertype be added to
> > > > the type system without needing to modify the definitions of all its
> > > > subtypes?
>
> > > No and No.
>
> > > As for the first "No" : I don't see an impractical difference between
> > > "just adding an extra possrep", and "re-issuing the entire type
> > > declaration which now includes the extra possrep".
>
> > > As for the second "No" here, this has been discussed on TTM and nobody
> > > changed positions.
>
> > A type system could be so large that these restrictions create
> > difficulties.
>
> Completely agreed. But **Tutorial** D is for tutoring purposes
> exclusively.
>
> I've made this mistake dozens of times myself : so beware that you
> DON'T take certain "properties" of the **Tutorial** D language, to be
> prescribed properties of the Manifesto **per se**. Other D languages
> can be totally different from **Tutorial** D, and still be a D (all
> THAT takes is to conform to the RM (+IM) prescriptions+proscriptions
> PER SE).
>
> (I probably even made this mistake once again where I said that
> "declaring a UNION type requires re-declaration of the constituent
> subtypes". This is so in Tutorial D. But I don't think there is an
> explicit prescription to this effect in the manifesto per se. Mea
> culpa.)
>
> Hence, the freedoms an implementer has to _deviate_ from **Tutorial**
> D, really go quite far.

Ok, good point.

> > > > 8. Is it possible to add super-types to the built-in types?
>
> > > All types are first-class citizens. No distinctions between built-in
> > > and user-defined types.
>
> > I would say it may be impractical if the answers to Q5 are no. The
> > built-in types are probably analogous to a third party library which
> > users have no control over.
>
> > For example, if the system provides a built-in type INTEGER but not
> > RATIONAL, then when someone implements the latter in terms of a pair
> > of INTEGER they also want to declare RATIONAL to be a supertype of
> > INTEGER, so that integers can be passed into all their operators that
> > take RATIONAL. This is awkward if they have to edit the system
> > provided definition of INTEGER.
>
> In the most recent book, "Database Explorations", Date argues that
> integer numbers are not rational numbers. You should not take the
> existence of a certain kind of correspondance between the _algebraic
> structures_ "Z,+,*" and "Q,+,*" (the former is a 'subgroup' of the
> latter, it is said) to imply that "the members of Z must be a subset
> of the members of Q".

I see many advantages in assuming the integers are a subset of the rationals. What are the disadvantages?

> At any rate, the whole idea is also problematic in that :
>
> - if you set up the super/subtype relationship without using a UNION
> type, then declaring RATIONAL requires the existence of INTEGER
> (otherwise RATIONAL's possrep cannot be defined), and INTEGER requires
> the existence of type RATIONAL (_and_ the existence of operators for
> RATIONAL, otherwise the type constraint for INTEGER in terms of
> RATIONAL cannot be defined, but that type constraint will have to
> involve INTEGER factoring, which requires the existence of type
> INTEGER, etc. etc.)
> - if you set up the super/subtype relationship by declaring an extra
> type NONINTEGERRATIONAL (with a constraint that numerator is not a
> perfect multiple of denominator), and then declare RATIONAL to be a
> UNION type of INTEGER and NONINTEGERRATIONAL, then you'd still be in
> trouble once you start defining operators such as rational division,
> which is not the same operator as integer division, while the IM
> prescriptions requires, essentially, that operators such as, e.g.
> "DIVIDE(RATIONAL,RATIONAL)" and "DIVIDE(INT,INT)", are effectively the
> very same operator if INT is effectively a subtype of RATIONAL.

These problems don't exist in the approach I outlined. E.g. assuming Integer is already defined, one can define Rational like this:

    type Rational;
    Integer isa Rational;
    Rational <--- rational(Integer n, Integer n) on d != 0;
    Rational <--- divide(Rational q, Rational d) on d != 0;     etc

I don't specify the order in which declarations like "Integer isa Rational" shall appear. Therefore a "new" type can declare itself to be a supertype of an "existing" type. I also allow for covariant return types on operators like divide as discussed in the original post.

This leads me to think about recursive types. E.g. a binary tree containing integers at the leaf nodes:

    type Tree;

    Tree <--- empty;
    Tree <--- leafnode(Integer);
    Tree <--- internalnode(Tree left, Tree right);

I don't think POSSREPS allow for expressing "algebraic data types" (as they are sometimes called in functional programming). It appears my approach is inherently more powerful than POSSREPS.

> > From an implementation perspective I cannot see a good reason to
> > outlaw adding supertypes to pre-existing types. E.g. it is easy to
> > emulate in C++
>
> Are they "outlawed" ? Did I say that in those words ?

No on the contrary you suggested otherwise when saying "No distinctions between built-in and user-defined types". My point is that I think the ability to add supertypes to pre-existing types should be one of the objectives of the language design. If D&D added it as a prescription then it appears Tutorial D would fail that prescription. Received on Tue Jun 07 2011 - 10:05:12 CEST

Original text of this message