comp.lang.ada
 help / color / mirror / Atom feed
* Array slices and types
@ 2008-08-20 14:51 Maciej Sobczak
  2008-08-20 15:26 ` Niklas Holsti
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Maciej Sobczak @ 2008-08-20 14:51 UTC (permalink / raw)


Consider this:

   type Name is new String (1 .. 10);

   N : Name;

   Some_String : String := "abc";

How can I assign Some_String to the beginning slice (ie. to the first
three characters) of N?
Everything that I can think of (short of copying characters
individually) hits the type compatibility problem.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: Array slices and types
  2008-08-20 14:51 Array slices and types Maciej Sobczak
@ 2008-08-20 15:26 ` Niklas Holsti
  2008-08-20 15:46 ` Dmitry A. Kazakov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 15+ messages in thread
From: Niklas Holsti @ 2008-08-20 15:26 UTC (permalink / raw)


Maciej Sobczak wrote:
> Consider this:
> 
>    type Name is new String (1 .. 10);
> 
>    N : Name;
> 
>    Some_String : String := "abc";
> 
> How can I assign Some_String to the beginning slice (ie. to the first
> three characters) of N?
> Everything that I can think of (short of copying characters
> individually) hits the type compatibility problem.

One way is to assign all of N:

    N := Name (Some_String(1..3) & String (N(4..10)));

Another way is to use a helpful procedure:

    procedure Set (Target : out String; Source : in String)
    is
    begin
       Target := Source;
    end Set;

and use type "conversion" on the output parameter:

    Set (Target => String (N(1..3)), Source => Some_String(1..3));

That is equivalent to the (forbidden):

    String (N(1..3)) := Some_String(1..3);   -- Not Ada!


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Array slices and types
  2008-08-20 14:51 Array slices and types Maciej Sobczak
  2008-08-20 15:26 ` Niklas Holsti
@ 2008-08-20 15:46 ` Dmitry A. Kazakov
  2008-08-20 18:52   ` Niklas Holsti
  2008-08-20 17:47 ` stefan-lucks
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2008-08-20 15:46 UTC (permalink / raw)


On Wed, 20 Aug 2008 07:51:02 -0700 (PDT), Maciej Sobczak wrote:

> Consider this:
> 
>    type Name is new String (1 .. 10);
> 
>    N : Name;
> 
>    Some_String : String := "abc";
> 
> How can I assign Some_String to the beginning slice (ie. to the first
> three characters) of N?
> Everything that I can think of (short of copying characters
> individually) hits the type compatibility problem.

You need an unconstrained base type for this. In your case the base is
anonymous. So name it:

   type Name_Base is new String; -- The base type is now named
   subtype Name is Name_Base (1..10);
   N : Name;
   Some_String : String := "abc";
begin
   N (1..3) := Name_Base (Some_String);

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



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

* Re: Array slices and types
  2008-08-20 14:51 Array slices and types Maciej Sobczak
  2008-08-20 15:26 ` Niklas Holsti
  2008-08-20 15:46 ` Dmitry A. Kazakov
@ 2008-08-20 17:47 ` stefan-lucks
  2008-08-20 17:51   ` stefan-lucks
  2008-08-20 20:45 ` Adam Beneschan
  2008-08-23  2:50 ` Steve
  4 siblings, 1 reply; 15+ messages in thread
From: stefan-lucks @ 2008-08-20 17:47 UTC (permalink / raw)


On Wed, 20 Aug 2008, Maciej Sobczak wrote:

> Consider this:
> 
>    type Name is new String (1 .. 10);
> 
>    N : Name;
> 
>    Some_String : String := "abc";
> 
> How can I assign Some_String to the beginning slice (ie. to the first
> three characters) of N?

Some_String does always contain exactly ten characters, no more, no less.

But you can assign the first three characters of Some_String to name:

     N(1 .. 3) := Some_String;

> Everything that I can think of (short of copying characters
> individually) hits the type compatibility problem.

Here is a completely compilable example:

with Ada.Text_IO;

procedure Slice is
   S: String(1 .. 3);
   T: String(1 .. 5) := (others => '*');
   U: String(1 .. 9) := (others => '-');
begin
   S := T(1 .. 3);
   U(1 .. 5) := T;
   Ada.Text_IO.Put_Line(S & "|" & T & "|" & U);
end Slice;

As expected, the output is a line with the string "***|*****|*****----".



-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




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

* Re: Array slices and types
  2008-08-20 17:47 ` stefan-lucks
@ 2008-08-20 17:51   ` stefan-lucks
  0 siblings, 0 replies; 15+ messages in thread
From: stefan-lucks @ 2008-08-20 17:51 UTC (permalink / raw)


> >    type Name is new String (1 .. 10);
> > 
> >    N : Name;
> > 
> >    Some_String : String := "abc";
> > 
> > How can I assign Some_String to the beginning slice (ie. to the first
> > three characters) of N?
> 
> Some_String does always contain exactly ten characters, no more, no less.

Sorry, Some_String always contains exactly three characters, name contains 
ten. 


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




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

* Re: Array slices and types
  2008-08-20 15:46 ` Dmitry A. Kazakov
@ 2008-08-20 18:52   ` Niklas Holsti
  2008-08-20 20:01     ` Simon Wright
  0 siblings, 1 reply; 15+ messages in thread
From: Niklas Holsti @ 2008-08-20 18:52 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Wed, 20 Aug 2008 07:51:02 -0700 (PDT), Maciej Sobczak wrote:
> 
> 
>>Consider this:
>>
>>   type Name is new String (1 .. 10);
>>
>>   N : Name;
>>
>>   Some_String : String := "abc";
>>
>>How can I assign Some_String to the beginning slice (ie. to the first
>>three characters) of N?
>>Everything that I can think of (short of copying characters
>>individually) hits the type compatibility problem.
> 
> 
> You need an unconstrained base type for this. In your case the base is
> anonymous. So name it:
> 
>    type Name_Base is new String; -- The base type is now named
>    subtype Name is Name_Base (1..10);
>    N : Name;
>    Some_String : String := "abc";
> begin
>    N (1..3) := Name_Base (Some_String);

Or you can use the 'Base attribute:

    N(1..3) := Name'Base (Some_String(1..3));

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Array slices and types
  2008-08-20 18:52   ` Niklas Holsti
@ 2008-08-20 20:01     ` Simon Wright
  2008-08-21  5:26       ` Niklas Holsti
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Wright @ 2008-08-20 20:01 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> Or you can use the 'Base attribute:
>
>    N(1..3) := Name'Base (Some_String(1..3));

Only for scalar types, says GNAT.



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

* Re: Array slices and types
  2008-08-20 14:51 Array slices and types Maciej Sobczak
                   ` (2 preceding siblings ...)
  2008-08-20 17:47 ` stefan-lucks
@ 2008-08-20 20:45 ` Adam Beneschan
  2008-08-21 21:16   ` Maciej Sobczak
  2008-08-23  2:50 ` Steve
  4 siblings, 1 reply; 15+ messages in thread
From: Adam Beneschan @ 2008-08-20 20:45 UTC (permalink / raw)


On Aug 20, 7:51 am, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> Consider this:
>
>    type Name is new String (1 .. 10);
>
>    N : Name;
>
>    Some_String : String := "abc";
>
> How can I assign Some_String to the beginning slice (ie. to the first
> three characters) of N?
> Everything that I can think of (short of copying characters
> individually) hits the type compatibility problem.

Do you really need a new *type*, as opposed to:

   subtype Name is String (1 .. 10);

???

(The answer may be yes.  But I would not declare Name to be a new
*type*, rather than a subtype, unless there's a reason for this---such
as Name being declared earlier as a private type.  I just wanted to
make sure that you were aware that declaring a subtype is a
possibility.)

                                 -- Adam





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

* Re: Array slices and types
  2008-08-20 20:01     ` Simon Wright
@ 2008-08-21  5:26       ` Niklas Holsti
  2008-08-21  8:53         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 15+ messages in thread
From: Niklas Holsti @ 2008-08-21  5:26 UTC (permalink / raw)


Simon Wright wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> 
> 
>>Or you can use the 'Base attribute:
>>
>>   N(1..3) := Name'Base (Some_String(1..3));
> 
> 
> Only for scalar types, says GNAT.

Oops... GNAT 3.15p accepted 'Base for the array type. But the LRM 
indeed allows it only for scalar types, so this is a bug (or 
"extension" :-) in 3.15p. Sorry for my misinformation (and I know I 
should use a newer GNAT).

But doesn't this example show that it would be useful to have 'Base 
also for array types? Any strong reasons against it?

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Array slices and types
  2008-08-21  5:26       ` Niklas Holsti
@ 2008-08-21  8:53         ` Dmitry A. Kazakov
  2008-08-21 14:44           ` Adam Beneschan
  0 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2008-08-21  8:53 UTC (permalink / raw)


On Thu, 21 Aug 2008 08:26:26 +0300, Niklas Holsti wrote:

> But doesn't this example show that it would be useful to have 'Base 
> also for array types?

For any type, actually.

Consider this language design fault:

procedure Initialize (X : in out S) is
begin
   Initialize (T (X));
   ... -- My stuff
end Initialize;

A call to Initialize should be done automatically, but it is not. So the
parent of S must be explicitly specified and known to all descendant. This
is a really *bad* thing:

package Foo is
   type S is new T with private;
private
   type S is new Private_Decendant_Of_T with ...;
end Foo;

What would happen if Private_Decendant_Of_T overrode Initialize of T? The
result would be an inability to publicly derive from S any new types if
Initialize should be extended!

S'Base could mend it:

procedure Initialize (X : in out S) is
begin
   (S"Base (X)).Initialize; -- Call to parent whatever it be
   ... -- My stuff
end Initialize;

Presently the only way is to override Initialize, Finalize and Adjust
everywhere, even if you actually don't want to extend them:

package Foo is
   type S is new T with private;
   overriding procedure Initialize (X : in out S); -- Have to do this!
private
   type S is new Private_Decendant_Of_T with ...;
end Foo;

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



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

* Re: Array slices and types
  2008-08-21  8:53         ` Dmitry A. Kazakov
@ 2008-08-21 14:44           ` Adam Beneschan
  2008-08-21 15:46             ` Dmitry A. Kazakov
  2008-08-22  4:30             ` Randy Brukardt
  0 siblings, 2 replies; 15+ messages in thread
From: Adam Beneschan @ 2008-08-21 14:44 UTC (permalink / raw)


On Aug 21, 1:53 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 21 Aug 2008 08:26:26 +0300, Niklas Holsti wrote:
> > But doesn't this example show that it would be useful to have 'Base
> > also for array types?
>
> For any type, actually.
>
> Consider this language design fault:
>
> procedure Initialize (X : in out S) is
> begin
>    Initialize (T (X));
>    ... -- My stuff
> end Initialize;
>
> A call to Initialize should be done automatically, but it is not. So the
> parent of S must be explicitly specified and known to all descendant. This
> is a really *bad* thing:
>
> package Foo is
>    type S is new T with private;
> private
>    type S is new Private_Decendant_Of_T with ...;
> end Foo;
>
> What would happen if Private_Decendant_Of_T overrode Initialize of T? The
> result would be an inability to publicly derive from S any new types if
> Initialize should be extended!
>
> S'Base could mend it:
>
> procedure Initialize (X : in out S) is
> begin
>    (S"Base (X)).Initialize; -- Call to parent whatever it be
>    ... -- My stuff
> end Initialize;

Sorry, Dmitry, but if you'll pardon the expression, you're a little
off-base here.  S'Base and S are subtypes of the same *type*.  They
may be different subtypes (have different constraints), but they're
the same type.  You're asking for an attribute that would give you a
different type.  There may be merit in having such an attribute (I
haven't looked into it closely), but calling it 'Base would be a bad
idea.  S'Parent might be better.

Niklas is asking for S'Base to be the unconstrained array subtype of
the (possibly constrained) array subtype S.  It would still fit into
the definition of 'Base (3.5(15)).  I'm not sure why this wasn't
defined for array subtypes, or for any other type that could have
discriminants; offhand I don't see how this would cause any problems.

                                  -- Adam




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

* Re: Array slices and types
  2008-08-21 14:44           ` Adam Beneschan
@ 2008-08-21 15:46             ` Dmitry A. Kazakov
  2008-08-22  4:30             ` Randy Brukardt
  1 sibling, 0 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2008-08-21 15:46 UTC (permalink / raw)


On Thu, 21 Aug 2008 07:44:29 -0700 (PDT), Adam Beneschan wrote:

> Sorry, Dmitry, but if you'll pardon the expression, you're a little
> off-base here.  S'Base and S are subtypes of the same *type*.

No need to excuse, you are right, I don't see any semantic difference
between subtypes of "same" type and derived tagged types. Consequently, I
don't think it is worth to further maintain such difference in the
language.

> They
> may be different subtypes (have different constraints), but they're
> the same type.  You're asking for an attribute that would give you a
> different type.

Yep, for that matter, tag is merely a constraint put on T'Class. Ada 83
model is capable to incorporate OO! We always knew that! (:-))

> There may be merit in having such an attribute (I
> haven't looked into it closely), but calling it 'Base would be a bad
> idea.  S'Parent might be better.

Integer'Parent were Universal_Integer, I guess (:-))

> Niklas is asking for S'Base to be the unconstrained array subtype of
> the (possibly constrained) array subtype S.  It would still fit into
> the definition of 'Base (3.5(15)).  I'm not sure why this wasn't
> defined for array subtypes, or for any other type that could have
> discriminants; offhand I don't see how this would cause any problems.

I think that the reason was that S'Base was thought as a very low-level
thing, something like the least constrained type of the *same* internal
representation. For unconstrained arrays the representation is likely not
the same, they might have a dope. For other types nobody seemingly cared.
(:-))

IMO, if S'Base need to be extended, then that would require a bit firmer
foundation than the above.

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



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

* Re: Array slices and types
  2008-08-20 20:45 ` Adam Beneschan
@ 2008-08-21 21:16   ` Maciej Sobczak
  0 siblings, 0 replies; 15+ messages in thread
From: Maciej Sobczak @ 2008-08-21 21:16 UTC (permalink / raw)


On 20 Sie, 22:45, Adam Beneschan <a...@irvine.com> wrote:

> Do you really need a new *type*, as opposed to:
>
>    subtype Name is String (1 .. 10);
>
> ???

Good question. If I make it a subtype, then I have no protection
against mixing First_Name with Device_Name with File_Name with
Signal_Name with Any_Other_Name - and that would defeat the whole
purpose of defining them.

Consider:

declare

   subtype First_Name is String (1 .. 4);
   subtype Device_Name is String (1 .. 4);

   Someone : First_Name := "Adam";
   Something : Device_Name := "usb1";

begin
   Someone := Something;  -- oops
end;

That's why I was thinking about distinct types. I'm OK with type casts
when assigning them from regular String.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: Array slices and types
  2008-08-21 14:44           ` Adam Beneschan
  2008-08-21 15:46             ` Dmitry A. Kazakov
@ 2008-08-22  4:30             ` Randy Brukardt
  1 sibling, 0 replies; 15+ messages in thread
From: Randy Brukardt @ 2008-08-22  4:30 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:fc112b42-285c-4ed5-ae78-34be4e60f6df@i20g2000prf.googlegroups.com...
> On Aug 21, 1:53 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Thu, 21 Aug 2008 08:26:26 +0300, Niklas Holsti wrote:
>> > But doesn't this example show that it would be useful to have 'Base
>> > also for array types?
>>
>> For any type, actually.
>>
>> Consider this language design fault:
>>
>> procedure Initialize (X : in out S) is
>> begin
>>    Initialize (T (X));
>>    ... -- My stuff
>> end Initialize;
>>
>> A call to Initialize should be done automatically, but it is not. So the
>> parent of S must be explicitly specified and known to all descendant. 
>> This
>> is a really *bad* thing:
>>
>> package Foo is
>>    type S is new T with private;
>> private
>>    type S is new Private_Decendant_Of_T with ...;
>> end Foo;
>>
>> What would happen if Private_Decendant_Of_T overrode Initialize of T? The
>> result would be an inability to publicly derive from S any new types if
>> Initialize should be extended!
>>
>> S'Base could mend it:
>>
>> procedure Initialize (X : in out S) is
>> begin
>>    (S"Base (X)).Initialize; -- Call to parent whatever it be
>>    ... -- My stuff
>> end Initialize;
>
> Sorry, Dmitry, but if you'll pardon the expression, you're a little
> off-base here.  S'Base and S are subtypes of the same *type*.  They
> may be different subtypes (have different constraints), but they're
> the same type.  You're asking for an attribute that would give you a
> different type.  There may be merit in having such an attribute (I
> haven't looked into it closely), but calling it 'Base would be a bad
> idea.  S'Parent might be better.

I tried to propose such a thing for Ada 2005, but it didn't work out. There 
isn't necessarily a single type that is the parent, unless you break 
privacy. Specifically:

    package P is
          type New_Type is new Some_Base with private;
          procedure Some_Operation (Obj : in out New_Type; Parent : in 
New_Type'Parent);
    private
          type New_Type is new Some_Derived with record ...
    end P;

In this case, what does New_Type'Parent give you in the body? We'd want it 
to resolve to Some_Derived. But a client of P can't see the full declaration 
(and shouldn't be able to depend on it), and thus P.New_Type'Parent would 
have to resolve to Some_Base.

So far, we can live with this. But now consider the completion to 
Some_Operation: the body would use the same parameter types in order to 
conform, but the *meaning* of the second parameter would be different to 
clients and the body. Oops. One could ban using this attribute in such 
specs, but that looks like a nasty wart (as bad as the original one). Thus, 
we didn't get a 'Parent attribute.

> Niklas is asking for S'Base to be the unconstrained array subtype of
> the (possibly constrained) array subtype S.  It would still fit into
> the definition of 'Base (3.5(15)).  I'm not sure why this wasn't
> defined for array subtypes, or for any other type that could have
> discriminants; offhand I don't see how this would cause any problems.

It does cause problems, and they're pretty severe as I recall. After all, 
Ada 83 allowed 'Base on everything (but only as a prefix of another 
attribute). That was removed in Ada 95 because of problems. But I can't 
remember what they were precisely. Sorry about that.

                                    Randy.





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

* Re: Array slices and types
  2008-08-20 14:51 Array slices and types Maciej Sobczak
                   ` (3 preceding siblings ...)
  2008-08-20 20:45 ` Adam Beneschan
@ 2008-08-23  2:50 ` Steve
  4 siblings, 0 replies; 15+ messages in thread
From: Steve @ 2008-08-23  2:50 UTC (permalink / raw)


"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message 
news:5886ab95-8744-4b72-b911-e4cb8889c7e7@d1g2000hsg.googlegroups.com...
> Consider this:
>
>   type Name is new String (1 .. 10);
>
>   N : Name;
>
>   Some_String : String := "abc";
>
> How can I assign Some_String to the beginning slice (ie. to the first
> three characters) of N?
> Everything that I can think of (short of copying characters
> individually) hits the type compatibility problem.

If you can change the definition of Name to:

  subtype Name is String( 1 .. 10 );

Then of course you can use:

  N( 1 .. 3 ) := Some_String( 1 .. 3 );

But that doesn't sound like what you're looking for.

Regards,
  Steve

>
> --
> Maciej Sobczak * www.msobczak.com * www.inspirel.com
>
> Database Access Library for Ada: www.inspirel.com/soci-ada 





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

end of thread, other threads:[~2008-08-23  2:50 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-20 14:51 Array slices and types Maciej Sobczak
2008-08-20 15:26 ` Niklas Holsti
2008-08-20 15:46 ` Dmitry A. Kazakov
2008-08-20 18:52   ` Niklas Holsti
2008-08-20 20:01     ` Simon Wright
2008-08-21  5:26       ` Niklas Holsti
2008-08-21  8:53         ` Dmitry A. Kazakov
2008-08-21 14:44           ` Adam Beneschan
2008-08-21 15:46             ` Dmitry A. Kazakov
2008-08-22  4:30             ` Randy Brukardt
2008-08-20 17:47 ` stefan-lucks
2008-08-20 17:51   ` stefan-lucks
2008-08-20 20:45 ` Adam Beneschan
2008-08-21 21:16   ` Maciej Sobczak
2008-08-23  2:50 ` Steve

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