comp.lang.ada
 help / color / mirror / Atom feed
* Discriminants of tagged types
@ 2010-10-27 12:16 Maciej Sobczak
  2010-10-27 12:34 ` Ludovic Brenta
                   ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-27 12:16 UTC (permalink / raw)


Hi,

I'm not sure if I have already complatined about it, but as I have hit
that problem again, here it goes:

GNAT says that discriminants of tagged types cannot have default
values.
So this is OK:

   type T (A : Integer := 0) is null record;

but this is an error:

   type T (A : Integer := 0) is tagged null record;

I find it disturbing and artificial, but perhaps I don't see the big
picture. What is the rationale for this limitation?

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 12:16 Discriminants of tagged types Maciej Sobczak
@ 2010-10-27 12:34 ` Ludovic Brenta
  2010-10-27 13:19   ` Dmitry A. Kazakov
  2010-10-27 13:44 ` Robert A Duff
  2010-10-27 13:54 ` J-P. Rosen
  2 siblings, 1 reply; 41+ messages in thread
From: Ludovic Brenta @ 2010-10-27 12:34 UTC (permalink / raw)


Maciej Sobczak wrote on comp.lang.ada:
> I'm not sure if I have already complatined about it, but as I have hit
> that problem again, here it goes:
>
> GNAT says that discriminants of tagged types cannot have default
> values.
> So this is OK:
>
>    type T (A : Integer := 0) is null record;
>
> but this is an error:
>
>    type T (A : Integer := 0) is tagged null record;
>
> I find it disturbing and artificial, but perhaps I don't see the big
> picture. What is the rationale for this limitation?

If one discriminant has a default value, then all discriminants must
have default values (ARM 3.7(9.1/2)).  The reason is explained in the
Annotated Ada Reference Manual[1].

http://www.adaic.com/standards/05aarm/html/AA-3-7.html

Tagged types have, by definition, a hidden discriminant which is the
tag.  The tag has no default value and cannot have one, for that would
allow changing the type of an object at run time (through assignment
of an aggregate).  Therefore, *additional* discriminants cannot have
default values either.

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 12:34 ` Ludovic Brenta
@ 2010-10-27 13:19   ` Dmitry A. Kazakov
  2010-10-27 13:52     ` Robert A Duff
  0 siblings, 1 reply; 41+ messages in thread
From: Dmitry A. Kazakov @ 2010-10-27 13:19 UTC (permalink / raw)


On Wed, 27 Oct 2010 05:34:26 -0700 (PDT), Ludovic Brenta wrote:

> The tag has no default value and cannot have one, for that would
> allow changing the type of an object at run time (through assignment
> of an aggregate).

No, it would not because you cannot assign a value of another type.

> Therefore, *additional* discriminants cannot have default values either.

I think there were concerns about implementation difficulties when the
derived type adds new discriminants and/or defines some inherited ones.

Anyway the limitation is indeed annoying.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 12:16 Discriminants of tagged types Maciej Sobczak
  2010-10-27 12:34 ` Ludovic Brenta
@ 2010-10-27 13:44 ` Robert A Duff
  2010-10-27 15:06   ` Adam Beneschan
  2010-10-27 15:13   ` Maciej Sobczak
  2010-10-27 13:54 ` J-P. Rosen
  2 siblings, 2 replies; 41+ messages in thread
From: Robert A Duff @ 2010-10-27 13:44 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> GNAT says that discriminants of tagged types cannot have default
> values.

Well, Ada says that.  GNAT is just following orders.  ;-)

> but this is an error:
>
>    type T (A : Integer := 0) is tagged null record;

We tried very hard during Ada 9X to allow this, but
we kept running into semantic difficulties, which required
more and more complicated rules to fix.  One day,
Tucker said to me (or I said to Tucker -- I don't
remember which), let's just outlaw this.  We both
agreed it was a big simplification.

Sorry, I don't remember in detail what the semantic
difficulties were.  Ludovic's explanation seems
as good as any.

I believe Ada 2012 will allow defaults for LIMITED
tagged types, and I think (not sure) it's already
implemented in GNAT under -gnat2012 mode.  The limited case
is easy, because the weird rule that says "defaulted
discriminants can change" isn't true for limited
types, because assignment statements are forbidden.

- Bob



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 13:19   ` Dmitry A. Kazakov
@ 2010-10-27 13:52     ` Robert A Duff
  2010-10-27 14:12       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 41+ messages in thread
From: Robert A Duff @ 2010-10-27 13:52 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Wed, 27 Oct 2010 05:34:26 -0700 (PDT), Ludovic Brenta wrote:
>
>> The tag has no default value and cannot have one, for that would
>> allow changing the type of an object at run time (through assignment
>> of an aggregate).
>
> No, it would not because you cannot assign a value of another type.

I think Ludovic means that the Tag could change.  That is, tags
are sort of like discriminants, so if Tags could have defaults,
then we can guess that they would inherit the strange rule "can change
if defaulted".  So this would work:

    A : T1;
    B : T'Class := A;
    C : T2;
    
    B := C; -- Raises an exception.

>> Therefore, *additional* discriminants cannot have default values either.
>
> I think there were concerns about implementation difficulties when the
> derived type adds new discriminants and/or defines some inherited ones.
>
> Anyway the limitation is indeed annoying.

Then you won't like my opinion, which is that this feature should
never have existed even for untagged types.  It's useful, but
it's just not worth the trouble, in terms of programmer confusion,
and implementation difficulty.  Also nonportability:

    type T(Length: Natural := 0) is
        record
            S: String(1..Length);
        end record;

This works on some implementations, and not others.

- Bob



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 12:16 Discriminants of tagged types Maciej Sobczak
  2010-10-27 12:34 ` Ludovic Brenta
  2010-10-27 13:44 ` Robert A Duff
@ 2010-10-27 13:54 ` J-P. Rosen
  2 siblings, 0 replies; 41+ messages in thread
From: J-P. Rosen @ 2010-10-27 13:54 UTC (permalink / raw)


Le 27/10/2010 14:16, Maciej Sobczak a �crit :
[...]
> GNAT says that discriminants of tagged types cannot have default
> values.
and it is right.

> I find it disturbing and artificial, but perhaps I don't see the big
> picture. What is the rationale for this limitation?
Default values of discriminants are not "just" default values: they
define another form of record, the polymorphic record.

Tagged types define a different kind of polymorphism, through inheritance.

Having two orthogonal kinds of polymorphism in the same data structure
would be difficult to manage, both from a design and an implementation
point of view.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Adalog a d�m�nag� / Adalog has moved:
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 13:52     ` Robert A Duff
@ 2010-10-27 14:12       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 41+ messages in thread
From: Dmitry A. Kazakov @ 2010-10-27 14:12 UTC (permalink / raw)


On Wed, 27 Oct 2010 09:52:48 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Wed, 27 Oct 2010 05:34:26 -0700 (PDT), Ludovic Brenta wrote:
>>
>>> The tag has no default value and cannot have one, for that would
>>> allow changing the type of an object at run time (through assignment
>>> of an aggregate).
>>
>> No, it would not because you cannot assign a value of another type.
> 
> I think Ludovic means that the Tag could change. That is, tags
> are sort of like discriminants, so if Tags could have defaults,
> then we can guess that they would inherit the strange rule "can change
> if defaulted".  So this would work:
> 
>     A : T1;
>     B : T'Class := A;
>     C : T2;
>     
>     B := C; -- Raises an exception.

But this is an unrelated case. The tag of a specific type cannot be changed
regardless its view as a discriminant.

Considering the class-wide type, its discriminants are unknown, it is an
open set. So the standard rules here do not apply anyway. BTW, if we
considered class-wide assigment dispatchng, we would come to the case of a
specific type when the tags are same, or to Constraint_Error when they
differ.

And independently on defaults:

   A : T1;
   B : T2;
   C : T'Class := A;
   D : T'Class := B;

   C := D;

>>> Therefore, *additional* discriminants cannot have default values either.
>>
>> I think there were concerns about implementation difficulties when the
>> derived type adds new discriminants and/or defines some inherited ones.
>>
>> Anyway the limitation is indeed annoying.
> 
> Then you won't like my opinion, which is that this feature should
> never have existed even for untagged types.  It's useful, but
> it's just not worth the trouble, in terms of programmer confusion,
> and implementation difficulty.  Also nonportability:
> 
>     type T(Length: Natural := 0) is
>         record
>             S: String(1..Length);
>         end record;
> 
> This works on some implementations, and not others.

It might wonder you, but I wholeheartedly agree with you, but for another
reason. The problem default values are supposed to solve IMO, should be
solved by constructors and user-defined aggregates. If they existed and for
any type, the programmer could provide variable list of arguments passed to
the constructor.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 13:44 ` Robert A Duff
@ 2010-10-27 15:06   ` Adam Beneschan
  2010-10-27 15:58     ` Yannick Duchêne (Hibou57)
  2010-10-27 15:13   ` Maciej Sobczak
  1 sibling, 1 reply; 41+ messages in thread
From: Adam Beneschan @ 2010-10-27 15:06 UTC (permalink / raw)


On Oct 27, 6:44 am, Robert A Duff <bobd...@shell01.TheWorld.com>
wrote:
> Maciej Sobczak <see.my.homep...@gmail.com> writes:
> > GNAT says that discriminants of tagged types cannot have default
> > values.
>
> Well, Ada says that.  GNAT is just following orders.  ;-)
>
> > but this is an error:
>
> >    type T (A : Integer := 0) is tagged null record;
>
> We tried very hard during Ada 9X to allow this, but
> we kept running into semantic difficulties, which required
> more and more complicated rules to fix.  One day,
> Tucker said to me (or I said to Tucker -- I don't
> remember which), let's just outlaw this.  We both
> agreed it was a big simplification.
>
> Sorry, I don't remember in detail what the semantic
> difficulties were.  Ludovic's explanation seems
> as good as any.

AARM 3.7(9.d): "Defaults for discriminants of tagged types are
disallowed so that every object of a tagged type is constrained,
either by an explicit constraint, or by its initial discriminant
values. This substantially simplifies the semantic rules and the
implementation of inherited dispatching operations. For generic formal
types, the restriction simplifies the type matching rules. If one
simply wants a 'default' value for the discriminants, a constrained
subtype can be declared for future use."

One issue with untagged types with default discriminants is that if
you define a type like that:

   type Rec (Discr : Integer := 0) is record ...

and declare a procedure with an IN OUT parameter of that
(unconstrained) type:

   procedure Proc (R : in out Rec) is
   begin
       ...
       R := (Discr => R.Discr + 1, [other components => ...])
          -- whether this is allowed depends on the actual parameter
   end Proc;

you could declare both an unconstrained and constrained object of that
type and pass them both to Proc:

   R1 : Rec;
   R2 : Rec(10);

   Proc (R1);
   Proc (R2);

Proc is allowed to assign a new value to R that changes the
discriminant, but it has to know that if R2 is the actual parameter,
the discriminant is not allowed to change.  This requires additional
information to be passed to Proc so that it knows whether to raise
Constraint_Error when the assignment to R happens.  Apparently it was
felt that where tagged types, class-wide types, and dispatching were
involved, this would make things too complicated.

This may seem "annoying" to those who think that a default
discriminant is *just* a default (rather than creating a different
kind of type that allows the creation of both constrained and
unconstrained objects).  But the last sentence of the AARM note shows
that the workaround is simple enough.  (Personally, I would have
preferred that the two concepts not be mixed, and that there be two
syntaxes---one for specifying a default value for discriminants, and
another to specify that unconstrained objects of the type can be
created.  It's not the only case where having one syntax do "double
duty" ends up causing problems.  I think AI05-154 is a symptom of
this, in which putting a constraint on a nominal array subtype not
only specifies a constraint but also tells the compiler that an
'Access can't be used as an access-to-unconstrained-array value,
causing headaches when you want to include a constraint but *also*
want the ability to have an access-to-unconstrained-array point to the
object; another case, perhaps, where "double duty" may have seemed
like a clever solution to avoid extra syntax, but turned out not to be
such a good idea....   But I'm starting to rant a bit.)

                                     -- Adam



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 13:44 ` Robert A Duff
  2010-10-27 15:06   ` Adam Beneschan
@ 2010-10-27 15:13   ` Maciej Sobczak
  2010-10-27 16:02     ` Yannick Duchêne (Hibou57)
  2010-10-27 16:06     ` Robert A Duff
  1 sibling, 2 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-27 15:13 UTC (permalink / raw)


On 27 Paź, 15:44, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:

> I believe Ada 2012 will allow defaults for LIMITED
> tagged types, and I think (not sure) it's already
> implemented in GNAT under -gnat2012 mode.  The limited case
> is easy

And is actually what I need, as non-limited tagged types are nonsense
anyway.

In the mean time I have solved the problem by realizing that
"taggedness" need not be public - in my case the type was tagged,
because it was controlled (hate to repeat it, but the interaction
between these two unrelated language features is really annoying).
I don't have to expose the controlled nature of the type in the public
view and moved the "tagged" keyword to private part.
Interestingly, this allowed me to use default values for discriminants
*and* have the controlled type.

(and this also shows that your explanation for why it cannot work is
shaky ;-) )

(except that now the "distinguished receiver" notation is gone...)

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 15:06   ` Adam Beneschan
@ 2010-10-27 15:58     ` Yannick Duchêne (Hibou57)
  2010-10-27 16:35       ` Vinzent Hoefler
                         ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-27 15:58 UTC (permalink / raw)


Indeed, this show very well how can default discriminants be a mess (and  
there are other reasons too to add to the ones given here).

A question then come : do someone know something to which default  
discriminants are unavoidable ? I feel default discriminants can simply be  
dropped (kind of sugar?), but I would like to be sure.

The OP asked about the rationale behind the choice to disallow default  
discriminant values in some case. May be to ask about the rationale behind  
the decision to introduce default discriminant values would be worth too.

Le Wed, 27 Oct 2010 17:06:24 +0200, Adam Beneschan <adam@irvine.com> a  
écrit:
> AARM 3.7(9.d): "Defaults for discriminants of tagged types are
> disallowed so that every object of a tagged type is constrained,
> either by an explicit constraint, or by its initial discriminant
> values. This substantially simplifies the semantic rules and the
> implementation of inherited dispatching operations. For generic formal
> types, the restriction simplifies the type matching rules. If one
> simply wants a 'default' value for the discriminants, a constrained
> subtype can be declared for future use."
>
> One issue with untagged types with default discriminants is that if
> you define a type like that:
>
>    type Rec (Discr : Integer := 0) is record ...
>
> and declare a procedure with an IN OUT parameter of that
> (unconstrained) type:
>
>    procedure Proc (R : in out Rec) is
>    begin
>        ...
>        R := (Discr => R.Discr + 1, [other components => ...])
>           -- whether this is allowed depends on the actual parameter
>    end Proc;
>
> you could declare both an unconstrained and constrained object of that
> type and pass them both to Proc:
>
>    R1 : Rec;
>    R2 : Rec(10);
>
>    Proc (R1);
>    Proc (R2);
>
> Proc is allowed to assign a new value to R that changes the
> discriminant, but it has to know that if R2 is the actual parameter,
> the discriminant is not allowed to change.  This requires additional
> information to be passed to Proc so that it knows whether to raise
> Constraint_Error when the assignment to R happens.  Apparently it was
> felt that where tagged types, class-wide types, and dispatching were
> involved, this would make things too complicated.
>
> This may seem "annoying" to those who think that a default
> discriminant is *just* a default (rather than creating a different
> kind of type that allows the creation of both constrained and
> unconstrained objects).  But the last sentence of the AARM note shows
> that the workaround is simple enough.  (Personally, I would have
> preferred that the two concepts not be mixed, and that there be two
> syntaxes---one for specifying a default value for discriminants, and
> another to specify that unconstrained objects of the type can be
> created.  It's not the only case where having one syntax do "double
> duty" ends up causing problems.  I think AI05-154 is a symptom of
> this, in which putting a constraint on a nominal array subtype not
> only specifies a constraint but also tells the compiler that an
> 'Access can't be used as an access-to-unconstrained-array value,
> causing headaches when you want to include a constraint but *also*
> want the ability to have an access-to-unconstrained-array point to the
> object; another case, perhaps, where "double duty" may have seemed
> like a clever solution to avoid extra syntax, but turned out not to be
> such a good idea....   But I'm starting to rant a bit.)
>
>                                      -- Adam


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 15:13   ` Maciej Sobczak
@ 2010-10-27 16:02     ` Yannick Duchêne (Hibou57)
  2010-10-27 21:13       ` Maciej Sobczak
  2010-10-27 16:06     ` Robert A Duff
  1 sibling, 1 reply; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-27 16:02 UTC (permalink / raw)


Le Wed, 27 Oct 2010 17:13:06 +0200, Maciej Sobczak  
<see.my.homepage@gmail.com> a écrit:
> as non-limited tagged types are nonsense anyway.

Why ?

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 15:13   ` Maciej Sobczak
  2010-10-27 16:02     ` Yannick Duchêne (Hibou57)
@ 2010-10-27 16:06     ` Robert A Duff
  2010-10-27 16:34       ` Yannick Duchêne (Hibou57)
                         ` (2 more replies)
  1 sibling, 3 replies; 41+ messages in thread
From: Robert A Duff @ 2010-10-27 16:06 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

> In the mean time I have solved the problem by realizing that
> "taggedness" need not be public - in my case the type was tagged,
> because it was controlled (hate to repeat it, but the interaction
> between these two unrelated language features is really annoying).
> I don't have to expose the controlled nature of the type in the public
> view and moved the "tagged" keyword to private part.
> Interestingly, this allowed me to use default values for discriminants
> *and* have the controlled type.

That doesn't sound right.  What does your example look like,
and what compiler compiled it without error?

The latest GNAT says:

     1. with Ada.Finalization; use Ada.Finalization;
     2. package Eg is
     3.    type T (X: Boolean := False) is private;
     4. private
     5.    type T (X: Boolean := False) is new Controlled with null
     record;
                                 |
        >>> discriminants of tagged type cannot have defaults

     6. end Eg;

 6 lines: 1 error

> (and this also shows that your explanation for why it cannot work is
> shaky ;-) )

Well, it would if it were true.  ;-)

> (except that now the "distinguished receiver" notation is gone...)

I'm not a big fan of that notation.  An awful lot of compiler
work for a little bit of syntactic sugar (or maybe syntactic
salt).

- Bob



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 16:06     ` Robert A Duff
@ 2010-10-27 16:34       ` Yannick Duchêne (Hibou57)
  2010-10-27 21:05       ` Maciej Sobczak
  2010-10-27 21:28       ` Simon Wright
  2 siblings, 0 replies; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-27 16:34 UTC (permalink / raw)


Le Wed, 27 Oct 2010 18:06:52 +0200, Robert A Duff  
<bobduff@shell01.theworld.com> a écrit:
>> (except that now the "distinguished receiver" notation is gone...)
>
> I'm not a big fan of that notation.
Neither I am :p [*] But may this is a bit to be by-the-book (depends on  
the so invoked book though). In the mean time, this is an appealing  
notation for whom coming from the C++ world and other similar-looking  
areas (this help them to feel better at the new home).

[*] Avoid it help traceability I feel (except Randy may argue it is just a  
matter of good Ada tools/editors), and it is also to me a kind or mark of  
“implementation level” (because this is the same-looking notation you have  
when you access components of records… accesses which are suggested to  
exist only at implementation level).

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 15:58     ` Yannick Duchêne (Hibou57)
@ 2010-10-27 16:35       ` Vinzent Hoefler
  2010-10-27 17:58       ` J-P. Rosen
  2010-10-27 20:26       ` Adam Beneschan
  2 siblings, 0 replies; 41+ messages in thread
From: Vinzent Hoefler @ 2010-10-27 16:35 UTC (permalink / raw)


On Wed, 27 Oct 2010 17:58:06 +0200, Yannick Duchêne (Hibou57) <yannick_duchene@yahoo.fr> wrote:

> A question then come : do someone know something to which default
> discriminants are unavoidable ? I feel default discriminants can simply be
> dropped (kind of sugar?), but I would like to be sure.

Well, we heavily use types with default discriminants in the project,
but if the feature wasn't available, I am sure, other solutions would
come up. So I wouldn't count that as "unavoidable".


Vinzent.

-- 
There is no signature.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 15:58     ` Yannick Duchêne (Hibou57)
  2010-10-27 16:35       ` Vinzent Hoefler
@ 2010-10-27 17:58       ` J-P. Rosen
  2010-10-27 20:18         ` Yannick Duchêne (Hibou57)
  2010-10-27 20:26       ` Adam Beneschan
  2 siblings, 1 reply; 41+ messages in thread
From: J-P. Rosen @ 2010-10-27 17:58 UTC (permalink / raw)


Le 27/10/2010 17:58, Yannick Duchêne (Hibou57) a écrit :
> Indeed, this show very well how can default discriminants be a mess (and
> there are other reasons too to add to the ones given here).
> 
> A question then come : do someone know something to which default
> discriminants are unavoidable ? I feel default discriminants can simply
> be dropped (kind of sugar?), but I would like to be sure.
> 
This issue is very simple and understandable if you take it the other
way round.

Reminder:
I1 : Integer;  -- Can take all values of type Integer
I2 : Integer range 1..10; -- Constraint, restricts to value 1..10

with:
type Rec (D: Disc) is ....

I must declare:
R1: Rec (1); -- Constraint, restricts to value 1 of discriminant.

Wouldn't it be nice to have a variable that could hold all values of
type Rec? Naturally, this is written as:
R2: Rec;

But wait a minute. If the discriminant is not specified by the
declaration, what is its value? A discriminant is to serious to leave it
uninitialized. OK, therefore this construct is allowed only if the
discriminant has default values.

QED.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Adalog a déménagé / Adalog has moved:
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 17:58       ` J-P. Rosen
@ 2010-10-27 20:18         ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-27 20:18 UTC (permalink / raw)


Le Wed, 27 Oct 2010 19:58:50 +0200, J-P. Rosen <rosen@adalog.fr> a écrit:
> Reminder:
> I1 : Integer;  -- Can take all values of type Integer
> I2 : Integer range 1..10; -- Constraint, restricts to value 1..10
>
> with:
> type Rec (D: Disc) is ....
>
> I must declare:
> R1: Rec (1); -- Constraint, restricts to value 1 of discriminant.
>
> Wouldn't it be nice to have a variable that could hold all values of
> type Rec? Naturally, this is written as:
> R2: Rec;

This is to be written as “R2: Rec;” only if there is no way to know what  
the discriminant should be. I may lack experiences (which is a never  
ending story… (I like this old-movie's song)), so I may be wrong : R2, as  
it is a variable, will be assigned sooner or later, and this assignment  
will come with discriminant(s). I feel there is a way to infer this  
constraint (possibly using nested blocks to ease, although SPARK does not  
support it) in may be near to all cases.

If ever R2 is assigned to a value which males it change its constraints,  
this isn't any more the same layout, so a bit not the same type. What  
about saying this is no more the same object ?

In

    procedure Any_Name
    is
       R1 : Rec (Expression_1);
       R2 : Rec (Expression_2);
       R  : Rec;
    begin
       R := R1; -- (1)
       R := R2; -- (2)
    end;

I feel the R of (1) terminates at (2) and at (2) a new R is born. Someone  
may argue R is just assigned a new value. I feel there is two R here. But  
this is not so much easy to have a clear idea here, as functional  
programming aficionados will even argue “I := 1; I := 2;” also create two  
different things.

I can easily handle polymorphism in my mind, when it comes with dynamic  
binding like with tagged types (see later for more on this). Here, I have  
difficulties to see polymorphism, as I see two different objects just  
sharing the same storage (like with clumsy optimization).

To me, it is a bit (I say a bit, there is a kind of level here) like doing  
:

    procedure Any_Name_2
    is
       Time : Time_Type;
    begin
       Time := Lunch_Time;
       -- Do something with dinner time (ex. adjust
       -- Time to get a meaningful lunch time).
       -- ...
       -- Let us suppose we never have to do
       -- computation on Lunch_Time interspersed
       -- with computations on Party_Time, so
       -- we decided to “save” a variable and
       -- use one variable for both
       -- ...
       Time := Party_Time;
       -- Do some computation on party time, idem.
    end;

If we are to compute the exact time of lunch and the exact time of party,  
I would prefer to use two variables.

When we do “R := R1; R := R2;”, what about checking we are not doing  
something similar to the above ?

At least, that is like blurring subtypes. If we had :

    procedure Any_Name_3
    is
       Astronomical_Distance : Distance_Type range 1 .. <big value>;
       Every_Day_Distance : Distance_Type range 1 .. <humanized value>;
    begin
       -- Would want to mix Astronomical_Distance and
       -- Every_Day_Distance in a same variable here ?
       null;
    end;

Something similar : would want a parameter of a procedure, which could  
receive either Subtype_1 or Subtype_2 ?

This make sense with dynamic binding and dispatching parameter, because we  
have overloaded methods. But here, can we have a method which is  
specialized for both ?

When I talk about “methods” here, this can means any sequence of  
instructions inside of a method.


TBH, I will have to check if I used this in the past and why (I said all  
the above, while I am not sure I really never did it on my own side).


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 15:58     ` Yannick Duchêne (Hibou57)
  2010-10-27 16:35       ` Vinzent Hoefler
  2010-10-27 17:58       ` J-P. Rosen
@ 2010-10-27 20:26       ` Adam Beneschan
  2010-10-27 22:07         ` Yannick Duchêne (Hibou57)
  2 siblings, 1 reply; 41+ messages in thread
From: Adam Beneschan @ 2010-10-27 20:26 UTC (permalink / raw)


On Oct 27, 8:58 am, Yannick Duchêne (Hibou57)
<yannick_duch...@yahoo.fr> wrote:
> Indeed, this show very well how can default discriminants be a mess (and  
> there are other reasons too to add to the ones given here).
>
> A question then come : do someone know something to which default  
> discriminants are unavoidable ? I feel default discriminants can simply be  
> dropped (kind of sugar?), but I would like to be sure.

I think that *modifiable* discriminants (which means default
discriminants in Ada syntax) would be hard to do without, in variant
record cases.  Suppose, for instance, you were using Ada to write an
interpreter for Perl or some other language that uses variables whose
type could change between an integer, a floating-point value, or a
string.  It seems natural to define a variable's value as a variant
record:

   type Value (Kind : Value_Kinds := None) is record
      case Kind is
         when Integer_Value =>    Int : Long_Integer;  -- or your
choice of integer type
         when Float_Value   =>    Flt : Float;         -- ditto
         when String_Value  =>    Str :
Ada.Strings.Unbounded.Unbounded_String;
      end case;
   end record;

Then, if the program assigns a new value to the variable and the value
has a different Kind, you'd want to be able to rewrite the value
that's stored in the symbol table entry for the variable.  In Ada you
can do this by reassigning the entire record.  Doing this without
modifiable discriminants would be, I believe, impossible without
adding some access types and a level of indirection, adding the
headaches involved with allocation, deallocation, memory leakage,
dangling references, etc.

Variant records are the main reason I use default discriminants in Ada
code.  Another typical use is to allow arrays whose size can change
dynamically:

    MAX_LENGTH : constant := 1000;
    subtype String_Length is 0 .. MAX_LENGTH;
    type Variable_String (Len : String_Length) is record
        Value : String (1 .. Len);
    end record;

                               -- Adam



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 16:06     ` Robert A Duff
  2010-10-27 16:34       ` Yannick Duchêne (Hibou57)
@ 2010-10-27 21:05       ` Maciej Sobczak
  2010-10-28  0:35         ` Robert A Duff
  2010-10-27 21:28       ` Simon Wright
  2 siblings, 1 reply; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-27 21:05 UTC (permalink / raw)


On 27 Paź, 18:06, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:

> > In the mean time I have solved the problem by realizing that
> > "taggedness" need not be public

> That doesn't sound right.

I was surprised, too.

> What does your example look like,

Much more complex, but reproducible with your code.

> and what compiler compiled it without error?

GPL 2009 (20090519)

> The latest GNAT says:
>
>      1. with Ada.Finalization; use Ada.Finalization;
>      2. package Eg is
>      3.    type T (X: Boolean := False) is private;
>      4. private
>      5.    type T (X: Boolean := False) is new Controlled with null
>      record;
>                                  |
>         >>> discriminants of tagged type cannot have defaults
>
>      6. end Eg;

My compiler eats this stuff without even blinking. It complains only
when I add the "tagged" keyword in line 3, between "is" and "private".

> > (except that now the "distinguished receiver" notation is gone...)
>
> I'm not a big fan of that notation.  An awful lot of compiler
> work for a little bit of syntactic sugar (or maybe syntactic
> salt).

Protected objects, tasks and records already supported it. It is not a
new idea, so it wasn't that big deal for compiler writers, I guess.
I treat it as a unification of syntax across these similar features -
quite a valid goal in language design.

This is especially reasonable if you take into account that in Ada
2005 protected types can derive from interfaces. It would be very
inconsistent not to allow the same calling syntax across the whole
hierarchy, including the class-wide type.

type Base is interface;
procedure Do_Something (X : in out Base) is abstract;

protected type Derived is new Base with
   procedure Do_Something;
end Derived;

D : Derived;
B : Base'Class := D;

D.Do_Something;  -- this was always OK, D is protected
B.Do_Something;  -- this *should* be OK as well for consistency

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 16:02     ` Yannick Duchêne (Hibou57)
@ 2010-10-27 21:13       ` Maciej Sobczak
  2010-10-27 21:23         ` Ludovic Brenta
                           ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-27 21:13 UTC (permalink / raw)


On 27 Paź, 18:02, Yannick Duchêne (Hibou57) <yannick_duch...@yahoo.fr>
wrote:

> > as non-limited tagged types are nonsense anyway.
>
> Why ?

Because tagged types usually represent entities that are bound to some
resources and copying them is somewhere between cumbersome and
impossible. Communication channels, database connections, etc.

In Ada the only types I'm aware of which are tagged and which have
justifiable copy semantics are containers - but you might as well
argue that there is no reason whatsoever for them to be tagged, which
only proves my point.

In C++ (which I'm more familiar with) there is a rule of thumb saying
that polymorphic types (anything with a virtual function inside)
should have disallowed copy operations. As a rule of thumb it works
very well and I've yet to see a justifiable counter-example. The same
rule of thumb translated to Ada says: tagged types shall be limited.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 21:13       ` Maciej Sobczak
@ 2010-10-27 21:23         ` Ludovic Brenta
  2010-10-28  8:38           ` Maciej Sobczak
  2010-10-27 21:25         ` Vinzent Hoefler
  2010-10-28  7:53         ` Dmitry A. Kazakov
  2 siblings, 1 reply; 41+ messages in thread
From: Ludovic Brenta @ 2010-10-27 21:23 UTC (permalink / raw)


Maciej Sobczak writes on comp.lang.ada:
> Yannick Duchêne wrote:
>
>> > as non-limited tagged types are nonsense anyway.
>>
>> Why ?
>
> Because tagged types usually represent entities that are bound to some
> resources and copying them is somewhere between cumbersome and
> impossible. Communication channels, database connections, etc.

Funny, I usually do the exact opposite.

I usually represent these things with untagged limited types.  Why would
these objects need to be tagged?  Conversely, my tagged types do not
necessarily (or usually, for that matter) represent resources; they
represent data with behavior or GUI widgets.  They do not always have to
be limited but they have to be tagged.

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 21:13       ` Maciej Sobczak
  2010-10-27 21:23         ` Ludovic Brenta
@ 2010-10-27 21:25         ` Vinzent Hoefler
  2010-10-28  7:53         ` Dmitry A. Kazakov
  2 siblings, 0 replies; 41+ messages in thread
From: Vinzent Hoefler @ 2010-10-27 21:25 UTC (permalink / raw)


On Wed, 27 Oct 2010 23:13:41 +0200, Maciej Sobczak <see.my.homepage@gmail.com> wrote:

> On 27 Paź, 18:02, Yannick Duchêne (Hibou57) <yannick_duch...@yahoo.fr>
> wrote:
>
>> > as non-limited tagged types are nonsense anyway.
>>
>> Why ?
>
> Because tagged types usually represent entities that are bound to some
> resources and copying them is somewhere between cumbersome and
> impossible. Communication channels, database connections, etc.

IBTD:

    ---------------------------------------------------------------------
    --  Clone
    ---------------------------------------------------------------------
    procedure Clone (Individual : in     Gene'Class;
                     Offspring  :    out Gene'Class) is
    begin
       Offspring := Individual;
    end Clone;

The Crossover operation also uses copying, but merely for pre-initialisation,
because this makes mixing in some of the father's genes a bit easier. ;)


Vinzent.

-- 
There is no signature.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 16:06     ` Robert A Duff
  2010-10-27 16:34       ` Yannick Duchêne (Hibou57)
  2010-10-27 21:05       ` Maciej Sobczak
@ 2010-10-27 21:28       ` Simon Wright
  2 siblings, 0 replies; 41+ messages in thread
From: Simon Wright @ 2010-10-27 21:28 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> That doesn't sound right.  What does your example look like, and what
> compiler compiled it without error?

This compiles without complaint with GNAT GPL 2010 & GCC 4.5.0:

   package Privately_Tagged is
      type T (X : Integer := 42) is private;
   private
      type T (X : Integer := 42) is tagged null record;
   end Privately_Tagged;

(and so does your example).



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 20:26       ` Adam Beneschan
@ 2010-10-27 22:07         ` Yannick Duchêne (Hibou57)
  2010-10-27 22:42           ` Adam Beneschan
  0 siblings, 1 reply; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-27 22:07 UTC (permalink / raw)


I see your good point.

I have something similar for Windows API interfacing (ex. for event  
handlers whose parameters may be made of two short integer, a reference, a  
long integer, and so, in the same parameter, depending on a message ID).  
This is a particular case, because I use Unchecked_Union, and  
Unchecked_Union requires a default value for the discriminant.

Otherwise, in your example, I would say what you named Value, is not a  
Value, and rather an Expression, unless you meant an abstract view of what  
a Value is.

As there are Integer_Value, Float_Value, String_Value, I suppose each of  
these three is associated to specific operations. So why not three types ?  
Tagged types derived from a root abstract tagged type ?

And for memory management, a pool of tagged type : a pool of  
Integer_Value, a pool of Float_Value, and so on. You will even save memory  
this way. About saving memory, image you have thousands of  
ASCII_Character_Value, each of them allocating all the space which would  
be required to allocate a Float_Value, that is something between 32 and 64  
bits.

But that is easily said, as I do not know about the whole system where  
this excerpt could come from.

Still not convinced.

Le Wed, 27 Oct 2010 22:26:57 +0200, Adam Beneschan <adam@irvine.com> a  
écrit:
> I think that *modifiable* discriminants (which means default
> discriminants in Ada syntax) would be hard to do without, in variant
> record cases.  Suppose, for instance, you were using Ada to write an
> interpreter for Perl or some other language that uses variables whose
> type could change between an integer, a floating-point value, or a
> string.  It seems natural to define a variable's value as a variant
> record:
>
>    type Value (Kind : Value_Kinds := None) is record
>       case Kind is
>          when Integer_Value =>    Int : Long_Integer;  -- or your
> choice of integer type
>          when Float_Value   =>    Flt : Float;         -- ditto
>          when String_Value  =>    Str :
> Ada.Strings.Unbounded.Unbounded_String;
>       end case;
>    end record;
>
> Then, if the program assigns a new value to the variable and the value
> has a different Kind, you'd want to be able to rewrite the value
> that's stored in the symbol table entry for the variable.  In Ada you
> can do this by reassigning the entire record.  Doing this without
> modifiable discriminants would be, I believe, impossible without
> adding some access types and a level of indirection, adding the
> headaches involved with allocation, deallocation, memory leakage,
> dangling references, etc.
>
> Variant records are the main reason I use default discriminants in Ada
> code.  Another typical use is to allow arrays whose size can change
> dynamically:
>
>     MAX_LENGTH : constant := 1000;
>     subtype String_Length is 0 .. MAX_LENGTH;
>     type Variable_String (Len : String_Length) is record
>         Value : String (1 .. Len);
>     end record;
>
>                                -- Adam


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 22:07         ` Yannick Duchêne (Hibou57)
@ 2010-10-27 22:42           ` Adam Beneschan
  0 siblings, 0 replies; 41+ messages in thread
From: Adam Beneschan @ 2010-10-27 22:42 UTC (permalink / raw)


On Oct 27, 3:07 pm, Yannick Duchêne (Hibou57)
<yannick_duch...@yahoo.fr> wrote:
> I see your good point.
>
> I have something similar for Windows API interfacing (ex. for event  
> handlers whose parameters may be made of two short integer, a reference, a  
> long integer, and so, in the same parameter, depending on a message ID).  
> This is a particular case, because I use Unchecked_Union, and  
> Unchecked_Union requires a default value for the discriminant.
>
> Otherwise, in your example, I would say what you named Value, is not a  
> Value, and rather an Expression, unless you meant an abstract view of what  
> a Value is.

Well, this was just intended to be an example, and it's best not to
get hung up on one example.  The idea was something like: suppose
you're writing an Ada interpreter for the Perl language, which does
not have strong typing.  A Perl program can have a variable named $x,
and the program could, at one point, assign $x=3; to give it an
integer value, and later $x="This is a string"; to give it a string
value, say.  The Ada interpreter would likely have some lookup table
in which it would look up the name "$x" and this would give it some
information about the current state of $x, with one of those pieces of
information being the current value of $x.  The idea here is that for
a Perl assignment statement, the interpreter could look up the record
containing $x and then reassign the value in that record to a new
value, which would involve changing the discriminant.  (Of course,
this is a huge oversimplification of the Perl language.  But it's the
sort of thing that could work in simpler interpreters---and, in fact,
I have used Ada for tools with command-line interfaces that would be
considered simple interpreters.  Also, of course, there are many other
possible uses for variant records that have nothing to do with
interpreters.)


> As there are Integer_Value, Float_Value, String_Value, I suppose each of  
> these three is associated to specific operations. So why not three types ?  
> Tagged types derived from a root abstract tagged type ?

Because the Ada record that contains information about $x cannot have
a component of type Root_Value_Type'Class.  The component would have
to be of an *access* type to Root_Value_Type'Class, and that's where
you start having to worry about allocation and memory leakage and the
like.  It's certainly one way to solve the problem, but it's not
without cost, and for a *simple* case (Perl would not be a simple
case, so it's a bad example), a variant record could be better.
Memory management is never as simple as it seems.

                                -- Adam



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 21:05       ` Maciej Sobczak
@ 2010-10-28  0:35         ` Robert A Duff
  2010-10-28  8:55           ` Maciej Sobczak
  0 siblings, 1 reply; 41+ messages in thread
From: Robert A Duff @ 2010-10-28  0:35 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

>> The latest GNAT says:
>>
>> � � �1. with Ada.Finalization; use Ada.Finalization;
>> � � �2. package Eg is
>> � � �3. � �type T (X: Boolean := False) is private;
>> � � �4. private
>> � � �5. � �type T (X: Boolean := False) is new Controlled with null
>> � � �record;
>> � � � � � � � � � � � � � � � � �|
>> � � � � >>> discriminants of tagged type cannot have defaults
>>
>> � � �6. end Eg;
>
> My compiler eats this stuff without even blinking. It complains only
> when I add the "tagged" keyword in line 3, between "is" and "private".

OK, well then it's a compiler bug that has since been fixed.
Now that I think about it, I think I remember a recent bug
in this area.

I'll bet if you tried hard enough, you'd find some cases
where the compiler generated code that did strange things
(before the bug was fixed, I mean).

> Protected objects, tasks and records already supported it.

Records never supported this notation for calls,
which I thought was what we're talking about.

I wasn't a big fan of it for tasks or protected objects, either.
But at least for these things, a "distinguished receiver" does
make sense, because there's only one object getting locked.
And because inside the operation, you can only see inside that
one object.  That is, in X.Y(Z), X is special in the
protected object case, but X and Z are just normal parameters
in the normal tagged case.

>... It is not a
> new idea, so it wasn't that big deal for compiler writers, I guess.

Well, it was.  Maybe it wouldn't have been if this new syntax
had been invented in the first place, but adding this sort
of thing into an existing compiler can be quite a pain.

> I treat it as a unification of syntax across these similar features -
> quite a valid goal in language design.
>
> This is especially reasonable if you take into account that in Ada
> 2005 protected types can derive from interfaces. It would be very
> inconsistent not to allow the same calling syntax across the whole
> hierarchy, including the class-wide type.

Good point.  But I'd prefer to unify the syntax in the
other direction.

- Bob



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 21:13       ` Maciej Sobczak
  2010-10-27 21:23         ` Ludovic Brenta
  2010-10-27 21:25         ` Vinzent Hoefler
@ 2010-10-28  7:53         ` Dmitry A. Kazakov
  2010-10-28  8:50           ` Maciej Sobczak
  2 siblings, 1 reply; 41+ messages in thread
From: Dmitry A. Kazakov @ 2010-10-28  7:53 UTC (permalink / raw)


On Wed, 27 Oct 2010 14:13:41 -0700 (PDT), Maciej Sobczak wrote:

> On 27 Païżœ, 18:02, Yannick Duchïżœne (Hibou57) <yannick_duch...@yahoo.fr>
> wrote:
> 
>>> as non-limited tagged types are nonsense anyway.
>>
>> Why ?
> 
> Because tagged types usually represent entities that are bound to some
> resources

This has nothing to do with copying. Consider a handle of a resource, e.g.
HWND as an example. It is bound to the resource, nevertheless it is
copyable.

> and copying them is somewhere between cumbersome and
> impossible. Communication channels, database connections, etc.

You conflate copying the resource and copying a proxy object.

> In Ada the only types I'm aware of which are tagged and which have
> justifiable copy semantics are containers - but you might as well
> argue that there is no reason whatsoever for them to be tagged, which
> only proves my point.

Rather the opposite, most of container types are not copyiable [*], most of
them are very useful to derive from [**].

----
* The picture with containers is quite distorted by language limitations.
The problem is that the properties of the container element types are not
inherited by the container type, but they necessarily constrain the latter.
The language does not provide any means to control this. So if the elements
are copyable that does not make the container copyable, though in some
cases it would make sense. The result is that the least requirement on the
elements (limited) translates into limited container types.

** You have to derive in many cases, because, again due to language
limitations, containers are generic, which makes their raw instances
sometimes unusable. Even if they are usable, quite often you would like to
hide or reshape something in the container interface and that requires
derivation.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-27 21:23         ` Ludovic Brenta
@ 2010-10-28  8:38           ` Maciej Sobczak
  0 siblings, 0 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-28  8:38 UTC (permalink / raw)


On 27 Paź, 23:23, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:

> Funny, I usually do the exact opposite.
>
> I usually represent these things with untagged limited types.  Why would
> these objects need to be tagged?

In my systems these are tagged to allow different implementations. A
database connection will be implemented differently for Oracle and for
PostgreSQL, although they may share a common interface.

Streams are good examples from the Ada standard library.

> Conversely, my tagged types do not
> necessarily (or usually, for that matter) represent resources; they
> represent data with behavior or GUI widgets.

GUI widgets are in the same category for me. They represent something
from outside of the program - copying windows objects is meaningless,
so it is safer to forbid copying whatsoever by making these types
limited.

I did not have to use types that are polymorphic and naturally
copyable.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-28  7:53         ` Dmitry A. Kazakov
@ 2010-10-28  8:50           ` Maciej Sobczak
  2010-10-28 10:28             ` Dmitry A. Kazakov
                               ` (2 more replies)
  0 siblings, 3 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-28  8:50 UTC (permalink / raw)


On 28 Paź, 09:53, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> > Because tagged types usually represent entities that are bound to some
> > resources
>
> This has nothing to do with copying. Consider a handle of a resource, e.g.
> HWND as an example. It is bound to the resource, nevertheless it is
> copyable.

Just like a file descriptor. Yet, there is no reason for these things
to be polymorphic.

Now consider a window or a file (as opposed to handle or descriptor).
They are different from handles and descriptors in that they represent
the target resources together with their lifetime management. That is,
I expect that finalizing the window object leads to the window being
closed or that finalizing the file object leads to the file being
flushed and closed, etc. Copy operations for such types are
meaningless.
What would it mean to copy a file object? Should the file on disk be
copied as well? Should the data that is still in the buffer be copied?
And so on. Instead of answering these questions in an unsatisfactory
way, it is better to outlaw the dubious operation up front.

> Rather the opposite, most of container types are not copyiable [*]

Is Vector limited?

> most of
> them are very useful to derive from [**].

I don't see any justification for this.

> ** You have to derive in many cases, because, again due to language
> limitations, containers are generic, which makes their raw instances
> sometimes unusable. Even if they are usable, quite often you would like to
> hide or reshape something in the container interface and that requires
> derivation.

I still don't see any justification, the above explanation is
circular.
Even if you can show an example where a language limitation prevents
you from doing something and thus justifies derivation, it is only a
proof that the language is broken, and not that the derivation
reflects any valid design objective.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-28  0:35         ` Robert A Duff
@ 2010-10-28  8:55           ` Maciej Sobczak
  0 siblings, 0 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-28  8:55 UTC (permalink / raw)


On 28 Paź, 02:35, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:

> > This is especially reasonable if you take into account that in Ada
> > 2005 protected types can derive from interfaces. It would be very
> > inconsistent not to allow the same calling syntax across the whole
> > hierarchy, including the class-wide type.
>
> Good point.  But I'd prefer to unify the syntax in the
> other direction.

And I would accept that other direction without any criticism, really.
The problem is that time has only one direction and now there is no
other option than to allow the dot syntax for everything.
In its current state, the language is inconsistent and only more
difficult to learn.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-28  8:50           ` Maciej Sobczak
@ 2010-10-28 10:28             ` Dmitry A. Kazakov
  2010-10-28 17:48             ` Yannick Duchêne (Hibou57)
  2010-10-29 18:59             ` Vinzent Hoefler
  2 siblings, 0 replies; 41+ messages in thread
From: Dmitry A. Kazakov @ 2010-10-28 10:28 UTC (permalink / raw)


On Thu, 28 Oct 2010 01:50:51 -0700 (PDT), Maciej Sobczak wrote:

> On 28 Paďż˝, 09:53, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
>>> Because tagged types usually represent entities that are bound to some
>>> resources
>>
>> This has nothing to do with copying. Consider a handle of a resource, e.g.
>> HWND as an example. It is bound to the resource, nevertheless it is
>> copyable.
> 
> Just like a file descriptor. Yet, there is no reason for these things
> to be polymorphic.

Nonsense. The handles must be typed. The relationships between their types
must reflect ones of the types of the target objects. Example, the handle
to an edit control must have a type derived from the type of a handle to a
window.

> Now consider a window or a file (as opposed to handle or descriptor).
> They are different from handles and descriptors in that they represent
> the target resources together with their lifetime management. That is,
> I expect that finalizing the window object leads to the window being
> closed or that finalizing the file object leads to the file being
> flushed and closed, etc. Copy operations for such types are
> meaningless.

That depends on the concrete case. There is much sense to be able to copy a
file or a graphical context.

> What would it mean to copy a file object? Should the file on disk be
> copied as well?

Yes, the file is on the disk, isn't it?

> Should the data that is still in the buffer be copied?

Yes. The data in the buffer is an implementation detail of which the file
user does not care. That is, the observable behavior shall not depend on
the implementation. If you copy a file it is copied independently on
whatever buffers be in whatever state.

> And so on. Instead of answering these questions in an unsatisfactory
> way, it is better to outlaw the dubious operation up front.

Programming is all about answering questions in unsatisfactory ways. The
goal is to minimize unsatisfaction. (:-))

>> Rather the opposite, most of container types are not copyiable [*]
> 
> Is Vector limited?

In which library? It could be or could be not. I designed unbounded arrays
not copyable.

>> most of them are very useful to derive from [**].
> 
> I don't see any justification for this.

Maybe you don't, but as a matter of fact, I derive from 3/4 of container
types I use. The container implementation provides an implementation to
adjust. It is a design tool, not an end product.

The way types (tools) are applied constitutes the types algebra. Derivation
is one of the most important operations of the algebra. That is why ideally
any type shall be inheritable.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-28  8:50           ` Maciej Sobczak
  2010-10-28 10:28             ` Dmitry A. Kazakov
@ 2010-10-28 17:48             ` Yannick Duchêne (Hibou57)
  2010-10-29 18:59             ` Vinzent Hoefler
  2 siblings, 0 replies; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-28 17:48 UTC (permalink / raw)


Le Thu, 28 Oct 2010 10:50:51 +0200, Maciej Sobczak  
<see.my.homepage@gmail.com> a écrit:
>> This has nothing to do with copying. Consider a handle of a resource,  
>> e.g.
>> HWND as an example. It is bound to the resource, nevertheless it is
>> copyable.
>
> [...]
> What would it mean to copy a file object? Should the file on disk be
> copied as well? Should the data that is still in the buffer be copied?
> And so on. Instead of answering these questions in an unsatisfactory
> way, it is better to outlaw the dubious operation up front.
Proxy objects needs not to be all the same. At least the Windows API do  
this (as others OS do) : you may open a file multiple times, get multiple  
handles to it, with for each, different access rights. The handle is not  
the file, this is a kind of proxy to a file's physical instance. The  
application on its own side, may do the same with handles, and hide file  
handles behind proxies (two levels). This is even a common construct, as  
in most designs you have references, smart references and proxies allover  
the place.

You obviously have the same with object whose intent is to draw on the  
screen.

May be this is too much wide to be uniquely identified and when the  
concept is referred to, it finally just tell few (and that's what may make  
its exact intent smoggy).

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-28  8:50           ` Maciej Sobczak
  2010-10-28 10:28             ` Dmitry A. Kazakov
  2010-10-28 17:48             ` Yannick Duchêne (Hibou57)
@ 2010-10-29 18:59             ` Vinzent Hoefler
  2010-10-30 21:05               ` Maciej Sobczak
  2 siblings, 1 reply; 41+ messages in thread
From: Vinzent Hoefler @ 2010-10-29 18:59 UTC (permalink / raw)


On Thu, 28 Oct 2010 10:50:51 +0200, Maciej Sobczak <see.my.homepage@gmail.com> wrote:

> On 28 Paź, 09:53, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>
>> > Because tagged types usually represent entities that are bound to some
>> > resources
>>
>> This has nothing to do with copying. Consider a handle of a resource, e.g.
>> HWND as an example. It is bound to the resource, nevertheless it is
>> copyable.
>
> Just like a file descriptor. Yet, there is no reason for these things
> to be polymorphic.

But they already are.

Sometimes they are files, sometimes devices, sometimes sockets, ...


Vinzent.

-- 
There is no signature.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-29 18:59             ` Vinzent Hoefler
@ 2010-10-30 21:05               ` Maciej Sobczak
  2010-10-30 21:21                 ` Vinzent Hoefler
  0 siblings, 1 reply; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-30 21:05 UTC (permalink / raw)


On 29 Paź, 20:59, "Vinzent Hoefler" <nntp-2010...@t-domaingrabbing.de>
wrote:

> > Just like a file descriptor. Yet, there is no reason for these things
> > to be polymorphic.
>
> But they already are.
>
> Sometimes they are files, sometimes devices, sometimes sockets, ...

No. File descriptors are just indices into some array of objects
managed by the operating system. Just plain integers, like here:

type Descriptor is Integer range 0 .. SOME_MAX;  -- this is what you
see

type Array_Of_Files_Managed_By_System_And_Hidden_From_You is
   array (Descriptor) of File'Class;

The actual objects are hidden from you and guess what? They have
polymorphic behaviour (sometimes they behave like files, sometimes
like devices and sometimes like sockets), but they are not themselves
copyable.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-30 21:05               ` Maciej Sobczak
@ 2010-10-30 21:21                 ` Vinzent Hoefler
  2010-10-30 22:01                   ` Yannick Duchêne (Hibou57)
  2010-10-31 16:20                   ` Maciej Sobczak
  0 siblings, 2 replies; 41+ messages in thread
From: Vinzent Hoefler @ 2010-10-30 21:21 UTC (permalink / raw)


On Sat, 30 Oct 2010 23:05:09 +0200, Maciej Sobczak <see.my.homepage@gmail.com> wrote:

> On 29 Paź, 20:59, "Vinzent Hoefler" <nntp-2010...@t-domaingrabbing.de>
> wrote:
>
>> > Just like a file descriptor. Yet, there is no reason for these things
>> > to be polymorphic.
>>
>> But they already are.
>>
>> Sometimes they are files, sometimes devices, sometimes sockets, ...
>
> No. File descriptors are just indices into some array of objects
> managed by the operating system.

Maybe they are, maybe they aren't. How are you supposed to know that?

> Just plain integers, like here:
>
> type Descriptor is Integer range 0 .. SOME_MAX;  -- this is what you
> see

No, what I see is:

|type Descriptor is private;

Making any assumptions about the layout of the type is just guesswork.

(Actually, in that particular implementation, I must admit, I made them
limited precisely to disallow copying, but the reasons for that have
nothing to do with polymorphism, but rather with access rights, meaning
I provide different types with different set of operations for clients
and servers. And I don't want a client to share it's access rights with
another one.)

> The actual objects are hidden from you and guess what? They have
> polymorphic behaviour (sometimes they behave like files, sometimes
> like devices and sometimes like sockets), but they are not themselves
> copyable.

Given an opaque type, how can you tell the difference? The set of
visible operations is the same.

Anything else is an implementation detail that does not concern the
user of the type. IMO polymorphism and copy semantics are distinct
concepts.


Vinzent.

-- 
There is no signature.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-30 21:21                 ` Vinzent Hoefler
@ 2010-10-30 22:01                   ` Yannick Duchêne (Hibou57)
  2010-10-31 16:20                   ` Maciej Sobczak
  1 sibling, 0 replies; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-30 22:01 UTC (permalink / raw)


Le Sat, 30 Oct 2010 23:21:39 +0200, Vinzent Hoefler  
<nntp-2010-10@t-domaingrabbing.de> a écrit:
> Given an opaque type, how can you tell the difference? The set of
> visible operations is the same.
>
> Anything else is an implementation detail that does not concern the
> user of the type. IMO polymorphism and copy semantics are distinct
> concepts.
And that's true from an Ada's point view indeed : you can have tagged  
types derived from the root Controlled type, and this can all be hidden  
 from the public view. So at least Ada allows tagged types to be either  
Reference Semantic or Value Semantic the same way, and this can be part of  
either the public contract or of the implementation only.

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-30 21:21                 ` Vinzent Hoefler
  2010-10-30 22:01                   ` Yannick Duchêne (Hibou57)
@ 2010-10-31 16:20                   ` Maciej Sobczak
  2010-10-31 17:04                     ` Yannick Duchêne (Hibou57)
  2010-10-31 18:36                     ` Shark8
  1 sibling, 2 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-31 16:20 UTC (permalink / raw)


On 30 Paź, 22:21, "Vinzent Hoefler" <nntp-2010...@t-domaingrabbing.de>
wrote:

> > No. File descriptors are just indices into some array of objects
> > managed by the operating system.
>
> Maybe they are, maybe they aren't. How are you supposed to know that?

I've read that on Wikipedia:

http://en.wikipedia.org/wiki/File_descriptor

;-)

File descriptor is called a file descriptor and not just a file,
because, well, it is a descriptor and not a file.

> Given an opaque type, how can you tell the difference? The set of
> visible operations is the same.

Almost. Descriptors become dangling when the actual objects cease to
exist - and this dangling state can be detected via their public
interface (perhaps only via errors). The actual objects never dangle,
only their descriptors (this concept includes pointers, names, etc.)
can do it.

> IMO polymorphism and copy semantics are distinct
> concepts.

As already said, I've yet to see a convincing example of a type that
is both justifiably polymorphic and copyable at the same time.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-31 16:20                   ` Maciej Sobczak
@ 2010-10-31 17:04                     ` Yannick Duchêne (Hibou57)
  2010-10-31 18:36                     ` Shark8
  1 sibling, 0 replies; 41+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-10-31 17:04 UTC (permalink / raw)


Le Sun, 31 Oct 2010 17:20:50 +0100, Maciej Sobczak  
<see.my.homepage@gmail.com> a écrit:
> As already said, I've yet to see a convincing example of a type that
> is both justifiably polymorphic and copyable at the same time.
A state (the one of a system of multiple and different objects), a  
continuation point (related to the latter, and subject to copy by  
definition), an application with some kind of internal backup system, an  
artificial-intelligence system, the text model in the black box in any  
kind of editor… and probably some other ideas could come later with a few  
more minutes or hours.

-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-31 16:20                   ` Maciej Sobczak
  2010-10-31 17:04                     ` Yannick Duchêne (Hibou57)
@ 2010-10-31 18:36                     ` Shark8
  2010-10-31 21:06                       ` Maciej Sobczak
  1 sibling, 1 reply; 41+ messages in thread
From: Shark8 @ 2010-10-31 18:36 UTC (permalink / raw)


On Oct 31, 10:20 am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> On 30 Paź, 22:21, "Vinzent Hoefler" <nntp-2010...@t-domaingrabbing.de>
> wrote:
>
> > IMO polymorphism and copy semantics are distinct
> > concepts.
>
> As already said, I've yet to see a convincing example of a type that
> is both justifiably polymorphic and copyable at the same time.
>
> --
> Maciej Sobczak *http://www.inspirel.com

I got one for you; I was using tagged types to implement the typing-
system for a PostScript interpreter. Virtually all PostScript objects
(that is, the things you push onto its stacks) are copyable... and all
the objects have attributes for being 'executable' (though the
execution thereof may be defined as [returning] the value thereof).



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-31 18:36                     ` Shark8
@ 2010-10-31 21:06                       ` Maciej Sobczak
  2010-11-01  0:44                         ` Shark8
  0 siblings, 1 reply; 41+ messages in thread
From: Maciej Sobczak @ 2010-10-31 21:06 UTC (permalink / raw)


On 31 Paź, 19:36, Shark8 <onewingedsh...@gmail.com> wrote:

> I got one for you; I was using tagged types to implement the typing-
> system for a PostScript interpreter.

Yes, this is a good example.
But then - do we consider assignment to be part of the "copyability"
property?
That is, it might be meaningful for your objects to be cloned
(duplicated), but is it also meaningful for them to be assigned to one
another?
Is the assignment meaningful only within the same type, or across the
hierarchy as well?

The reason for the above question is that even though at the language
level copy initialization and assignment are somewhat mixed together
by the type being either limited or not, they are in fact distinct
concepts and not that much similar.

In the tutorial analogy of famous shapes, it might be perfectly
reasonable to duplicate an arbitrary Shape'Class (whatever it is), but
it will be completely unreasonable to assign Square to some existing
Circle. This problem alone would be sufficient for me to make
everything limited.
Similarly with the interpreter objects, states in FSMs, and so on.

Thus, for the purpose of modeling clarity I prefer to distinguish
between:
- copyability, which means support for copy-initialization *and*
assignment
- cloneability, which is always deep

So - even though my tagged types are typically limited, in some
particular cases they can be also cloneable. It does not apply to
files, sockets, database connections and similar things that are
associated with some resources that exist outside of the physical
representation of the object, but it might apply to self-contained
data entities like interpreter instructions, document elements, states
in FSMs, etc.

I hope that the above clarification makes my rule of thumb more
understandable and not really conflicting with your examples.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-10-31 21:06                       ` Maciej Sobczak
@ 2010-11-01  0:44                         ` Shark8
  2010-11-01  9:41                           ` Maciej Sobczak
  0 siblings, 1 reply; 41+ messages in thread
From: Shark8 @ 2010-11-01  0:44 UTC (permalink / raw)


On Oct 31, 3:06 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> On 31 Paź, 19:36, Shark8 <onewingedsh...@gmail.com> wrote:
>
> > I got one for you; I was using tagged types to implement the typing-
> > system for a PostScript interpreter.
>
> Yes, this is a good example.
> But then - do we consider assignment to be part of the "copyability"
> property?
> That is, it might be meaningful for your objects to be cloned
> (duplicated), but is it also meaningful for them to be assigned to one
> another?

The assignability of PostScript objects is, IMO, a non-issue.
Most objects are created via PostScript commands, and those that
aren't are the ones which [arguably] are the PostScript interpreter
(the stacks and dictionaries of the interpreter).

While PostScript does have 'arrays' and procedures/functions (which
are merely executable arrays) they are produced by pushing a Mark
object and then zero-or-more PostScript objects, and a terminal-mark
object (which pops everything to-and including the mark off the stack,
packages them, and pushes the newly-created array-object onto the
stack); so it is somewhat similar to the Mark/Release dynamic memory
management paradigm.

You can put a name-object into one of the dictionary-objects and
associate it with some object from the stack; this is how procedures
are done. {Then when the interpreter encounters a name-object it looks
through the dictionaries to execute the associated object.}

So, in as far as the PostScript interpreter is concerned, I don't see
any particular reason assignments would be needed, excepting to class-
wide types.

> Is the assignment meaningful only within the same type, or across the
> hierarchy as well?
>
> The reason for the above question is that even though at the language
> level copy initialization and assignment are somewhat mixed together
> by the type being either limited or not, they are in fact distinct
> concepts and not that much similar.
>
> In the tutorial analogy of famous shapes, it might be perfectly
> reasonable to duplicate an arbitrary Shape'Class (whatever it is), but
> it will be completely unreasonable to assign Square to some existing
> Circle.

Interesting you mention that; I was working on a bit of a vector-
graphic program for a computer graphics class and I was kicking around
the idea of allowing such 'assignments' as being the equivalent of
"make a shape of this new type which has the same bounding rectangle."
I eventually decided against it because:
1 - The existence of an arbitrary and complex polygon would gum up the
works,
and
2) I'm lazy.

;)

> This problem alone would be sufficient for me to make
> everything limited.
> Similarly with the interpreter objects, states in FSMs, and so on.
>
> Thus, for the purpose of modeling clarity I prefer to distinguish
> between:
> - copyability, which means support for copy-initialization *and*
> assignment
> - cloneability, which is always deep

I can see how such is a useful distinction.

>
> So - even though my tagged types are typically limited, in some
> particular cases they can be also cloneable. It does not apply to
> files, sockets, database connections and similar things that are
> associated with some resources that exist outside of the physical
> representation of the object, but it might apply to self-contained
> data entities like interpreter instructions, document elements, states
> in FSMs, etc.
>
> I hope that the above clarification makes my rule of thumb more
> understandable and not really conflicting with your examples.

Hm, I see that it doesn't conflict... though one thing that was
bugging me was that Tasks cannot return values from their entries:
this means that I couldn't separate the parsing/object-generation from
the actual interpreter internals. {I was hoping to make it in such a
way that some server could run the parsing/object-creation possibly on
a different machine than the one the PostScript-objects would reside
on -- This would also allow for a single parser to serve multiple
PostScript interpreters on the same machine.}

And out parameters on a class-wide type wouldn't work because you need
to initialize a class-wide variable.
Today I found how to bypass the limitation by using a representation
clause.

[...]
  -- Inside the Parser-task, which may or may not be remote.
  -- Input is of In Out because a passed string may contain more than
one object,
  -- in that case the unconsumed portion of the string should be
returned to the client.
  Accept Parse( Output : Out PostScript_Object'Class; Input : In Out
String ) do
    Declare
      -- Because initialization of class-wide types are allowed,
      -- whereas assignments thereunto are not, unless the tags
      -- of both match. The class cannot be known until AFTER it is
parsed though.
      Temp : PostScript_Object'Class:= Parse_String( Input );
      For Temp'Address use Output'Address;
    Begin
        Null;
    End;
  end Parse;
[...]

So, I may be able to do it after all.
I'll just have to look at ensuring that the space used in the client-
side of portion is no less than the maximum size of a 'basic'
PostScript object.
>
> --
> Maciej Sobczak *http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Discriminants of tagged types
  2010-11-01  0:44                         ` Shark8
@ 2010-11-01  9:41                           ` Maciej Sobczak
  0 siblings, 0 replies; 41+ messages in thread
From: Maciej Sobczak @ 2010-11-01  9:41 UTC (permalink / raw)


On 1 Lis, 01:44, Shark8 <onewingedsh...@gmail.com> wrote:

> The assignability of PostScript objects is, IMO, a non-issue.
> Most objects are created via PostScript commands

Which makes them good candidates for being limited, as objects of
limited types can be initialized by functions.

On the other hand, limited types don't work with containers, so you
might want to consider that as a trade-off.

> > In the tutorial analogy of famous shapes, it might be perfectly
> > reasonable to duplicate an arbitrary Shape'Class (whatever it is), but
> > it will be completely unreasonable to assign Square to some existing
> > Circle.
>
> Interesting you mention that; I was working on a bit of a vector-
> graphic program for a computer graphics class and I was kicking around
> the idea of allowing such 'assignments' as being the equivalent of
> "make a shape of this new type which has the same bounding rectangle."
> I eventually decided against it because:
> 1 - The existence of an arbitrary and complex polygon would gum up the
> works,
> and
> 2) I'm lazy.

Laziness is a very good reason ;-), but in this case I think what is
more important is the fact that such assignment semantics would be
arbitrary (what about assigning colors?) and not self-explanatory at
the usage site.
Compare these two:

A := B;  -- what's going on here?

A.Resize_And_Move_For_New_Bounding_Rectangle (B);

I leave it up to you to invent a better operation name, but you get
the point.

I have never implemented any PostScript interpreter, but judging from
what you have described, I would make everything limited without much
regret.

--
Maciej Sobczak * http://www.inspirel.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2010-11-01  9:41 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-27 12:16 Discriminants of tagged types Maciej Sobczak
2010-10-27 12:34 ` Ludovic Brenta
2010-10-27 13:19   ` Dmitry A. Kazakov
2010-10-27 13:52     ` Robert A Duff
2010-10-27 14:12       ` Dmitry A. Kazakov
2010-10-27 13:44 ` Robert A Duff
2010-10-27 15:06   ` Adam Beneschan
2010-10-27 15:58     ` Yannick Duchêne (Hibou57)
2010-10-27 16:35       ` Vinzent Hoefler
2010-10-27 17:58       ` J-P. Rosen
2010-10-27 20:18         ` Yannick Duchêne (Hibou57)
2010-10-27 20:26       ` Adam Beneschan
2010-10-27 22:07         ` Yannick Duchêne (Hibou57)
2010-10-27 22:42           ` Adam Beneschan
2010-10-27 15:13   ` Maciej Sobczak
2010-10-27 16:02     ` Yannick Duchêne (Hibou57)
2010-10-27 21:13       ` Maciej Sobczak
2010-10-27 21:23         ` Ludovic Brenta
2010-10-28  8:38           ` Maciej Sobczak
2010-10-27 21:25         ` Vinzent Hoefler
2010-10-28  7:53         ` Dmitry A. Kazakov
2010-10-28  8:50           ` Maciej Sobczak
2010-10-28 10:28             ` Dmitry A. Kazakov
2010-10-28 17:48             ` Yannick Duchêne (Hibou57)
2010-10-29 18:59             ` Vinzent Hoefler
2010-10-30 21:05               ` Maciej Sobczak
2010-10-30 21:21                 ` Vinzent Hoefler
2010-10-30 22:01                   ` Yannick Duchêne (Hibou57)
2010-10-31 16:20                   ` Maciej Sobczak
2010-10-31 17:04                     ` Yannick Duchêne (Hibou57)
2010-10-31 18:36                     ` Shark8
2010-10-31 21:06                       ` Maciej Sobczak
2010-11-01  0:44                         ` Shark8
2010-11-01  9:41                           ` Maciej Sobczak
2010-10-27 16:06     ` Robert A Duff
2010-10-27 16:34       ` Yannick Duchêne (Hibou57)
2010-10-27 21:05       ` Maciej Sobczak
2010-10-28  0:35         ` Robert A Duff
2010-10-28  8:55           ` Maciej Sobczak
2010-10-27 21:28       ` Simon Wright
2010-10-27 13:54 ` J-P. Rosen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox