comp.lang.ada
 help / color / mirror / Atom feed
* basic basic ada question
@ 2006-10-19 14:30 markww
  2006-10-19 14:47 ` Georg Bauhaus
                   ` (2 more replies)
  0 siblings, 3 replies; 45+ messages in thread
From: markww @ 2006-10-19 14:30 UTC (permalink / raw)


Hi,

Can someone give me an example of a command line app where I can read
in command line arguments?

In C++ we have:

int main(int argc, char **argv)
{
    printf("There are [%i] arguments.\n", argc);
    return 0;
}

all I have so far in ada is:


    with Ada.Text_IO; use Ada.Text_IO;
    procedure DynamicArray is
    begin

        -- Tell the user what we're doing.
        Put_Line ("This application will allocate a dynamic array.");

        -- Now allocate a dynamic array.
        Name : array (0 .. 20) of INTEGER

        -- That's it.

    end DynamicArray;

eventually I'd like to allocate that array based on the number of
elements passed as an argument by the user.

Thanks,
Mark




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

* Re: basic basic ada question
  2006-10-19 14:30 basic basic ada question markww
@ 2006-10-19 14:47 ` Georg Bauhaus
  2006-10-19 15:10   ` markww
  2006-10-19 15:11 ` Dmitry A. Kazakov
  2006-10-19 21:30 ` James Alan Farrell
  2 siblings, 1 reply; 45+ messages in thread
From: Georg Bauhaus @ 2006-10-19 14:47 UTC (permalink / raw)


On Thu, 2006-10-19 at 07:30 -0700, markww wrote:
> Hi,
> 
> Can someone give me an example of a command line app where I can read
> in command line arguments?
> 
> In C++ we have:
> 
> int main(int argc, char **argv)
> {
>     printf("There are [%i] arguments.\n", argc);
>     return 0;
> }

This is from Ada's standard library:

 package Ada.Command_Line is

4       function Argument_Count return Natural;

5       function Argument (Number : in Positive) return String;


Once you have read the number of desired array components
from the command line into, say, the constant Num_Components,
declare a corresponding array type,

    ...
    type Your_Name_Here is array (? .. Num_Components) of ...;
    ...







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

* Re: basic basic ada question
  2006-10-19 14:47 ` Georg Bauhaus
@ 2006-10-19 15:10   ` markww
  2006-10-21 10:29     ` Stephen Leake
  0 siblings, 1 reply; 45+ messages in thread
From: markww @ 2006-10-19 15:10 UTC (permalink / raw)


Hi Georg,

Thanks for your response. I just don't understand how to implement it.
In ada we have a function definition like:

procedure DynamicArray is
begin

    -- Function body stuff here...
    -- Where does Argument_Count come from?
    -- Where does Argument (0...numArgs) come from?

end DynamicArray;


Thanks,
Mark



On Oct 19, 10:47 am, Georg Bauhaus <bauh...@futureapps.de> wrote:
> On Thu, 2006-10-19 at 07:30 -0700, markww wrote:
> > Hi,
>
> > Can someone give me an example of a command line app where I can read
> > in command line arguments?
>
> > In C++ we have:
>
> > int main(int argc, char **argv)
> > {
> >     printf("There are [%i] arguments.\n", argc);
> >     return 0;
> > }This is from Ada's standard library:
>
>  package Ada.Command_Line is
>
> 4       function Argument_Count return Natural;
>
> 5       function Argument (Number : in Positive) return String;
>
> Once you have read the number of desired array components
> from the command line into, say, the constant Num_Components,
> declare a corresponding array type,
>
>     ...
>     type Your_Name_Here is array (? .. Num_Components) of ...;
>     ...




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

* Re: basic basic ada question
  2006-10-19 14:30 basic basic ada question markww
  2006-10-19 14:47 ` Georg Bauhaus
@ 2006-10-19 15:11 ` Dmitry A. Kazakov
  2006-10-19 15:45   ` markww
  2006-10-19 21:30 ` James Alan Farrell
  2 siblings, 1 reply; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-19 15:11 UTC (permalink / raw)


On 19 Oct 2006 07:30:31 -0700, markww wrote:

> Can someone give me an example of a command line app where I can read
> in command line arguments?

See the package Ada.Command_Line.

> In C++ we have:
> 
> int main(int argc, char **argv)
> {
>     printf("There are [%i] arguments.\n", argc);
>     return 0;
> }
> 
> all I have so far in ada is:
> 
> 
>     with Ada.Text_IO; use Ada.Text_IO;
>     procedure DynamicArray is

   type Array_Of_Integers is array (Integer range <>) of Integer;
      -- Not necessary, but a good style. You might need a subprogram
      -- dealing with your arrays later.
   Number_Of_Elements : Natural;

>     begin
> 
>         -- Tell the user what we're doing.
>         Put_Line ("This application will allocate a dynamic array.");

   Number_Of_Elements := ...; -- use Ada.Command_Line
 
>         -- Now allocate a dynamic array.
>         Name : array (0 .. 20) of INTEGER

   declare
      My_Array : Array_Of_Integers (1..Number_Of_Elements);
   begin
      -- Do with My_Array what you have to
   end;
>         -- That's it.
> 
>     end DynamicArray;
> 
> eventually I'd like to allocate that array based on the number of
> elements passed as an argument by the user.

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



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

* Re: basic basic ada question
  2006-10-19 15:11 ` Dmitry A. Kazakov
@ 2006-10-19 15:45   ` markww
  2006-10-19 16:29     ` Gautier
                       ` (2 more replies)
  0 siblings, 3 replies; 45+ messages in thread
From: markww @ 2006-10-19 15:45 UTC (permalink / raw)


Ok, am I understanding this correctly - if I just '#include" the
command line package:

    with Ada.Command_Line; use Ada.Command_Line;

then the package defines the functions:

    function Argument_Count return Natural;
    function Argument (Number : in Positive) return String;

for me which I can use from then on?

So in my little app I can just use them like:

    Number_Of_Elements := Argument(0);

(assuming the 0th argument is the # of elements to allocate...)

Thanks;



On Oct 19, 11:11 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On 19 Oct 2006 07:30:31 -0700, markww wrote:
>
> > Can someone give me an example of a command line app where I can read
> > in command line arguments?See the package Ada.Command_Line.
>
> > In C++ we have:
>
> > int main(int argc, char **argv)
> > {
> >     printf("There are [%i] arguments.\n", argc);
> >     return 0;
> > }
>
> > all I have so far in ada is:
>
> >     with Ada.Text_IO; use Ada.Text_IO;
> >     procedure DynamicArray is   type Array_Of_Integers is array (Integer range <>) of Integer;
>       -- Not necessary, but a good style. You might need a subprogram
>       -- dealing with your arrays later.
>    Number_Of_Elements : Natural;
>
> >     begin
>
> >         -- Tell the user what we're doing.
> >         Put_Line ("This application will allocate a dynamic array.");   Number_Of_Elements := ...; -- use Ada.Command_Line
>
> >         -- Now allocate a dynamic array.
> >         Name : array (0 .. 20) of INTEGER   declare
>       My_Array : Array_Of_Integers (1..Number_Of_Elements);
>    begin
>       -- Do with My_Array what you have to
>    end;
>
> >         -- That's it.
>
> >     end DynamicArray;
>
> > eventually I'd like to allocate that array based on the number of
> > elements passed as an argument by the user.--
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de




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

* Re: basic basic ada question
  2006-10-19 15:45   ` markww
@ 2006-10-19 16:29     ` Gautier
  2006-10-19 17:16     ` Dmitry A. Kazakov
  2006-10-19 20:07     ` Jeffrey R. Carter
  2 siblings, 0 replies; 45+ messages in thread
From: Gautier @ 2006-10-19 16:29 UTC (permalink / raw)


markww:

> Ok, am I understanding this correctly - if I just '#include" the
> command line package:
> 
>     with Ada.Command_Line; use Ada.Command_Line;
> 
> then the package defines the functions:
> 
>     function Argument_Count return Natural;
>     function Argument (Number : in Positive) return String;
> 
> for me which I can use from then on?

The effect will be that.
Just, the "with" has a lot more stronger sense than inserting lines with #include.

> So in my little app I can just use them like:
> 
>     Number_Of_Elements := Argument(0);
> 
> (assuming the 0th argument is the # of elements to allocate...)
> 
> Thanks;

It is Argument(1) indeed - the argument number one. As a hint, the function 
Argument takes a positive value.
HTH, Gautier
______________________________________________________________
Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!



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

* Re: basic basic ada question
  2006-10-19 15:45   ` markww
  2006-10-19 16:29     ` Gautier
@ 2006-10-19 17:16     ` Dmitry A. Kazakov
  2006-10-19 20:07     ` Jeffrey R. Carter
  2 siblings, 0 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-19 17:16 UTC (permalink / raw)


On 19 Oct 2006 08:45:20 -0700, markww wrote:

> So in my little app I can just use them like:
> 
>     Number_Of_Elements := Argument(0);
> 
> (assuming the 0th argument is the # of elements to allocate...)

You should convert it from String to Integer. For example, like this:

    Number_Of_Elements := Integer'Value (Argument (1));
 
[I presume you meant 1st argument.]

See S'Value attribute for details.

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



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

* Re: basic basic ada question
  2006-10-19 15:45   ` markww
  2006-10-19 16:29     ` Gautier
  2006-10-19 17:16     ` Dmitry A. Kazakov
@ 2006-10-19 20:07     ` Jeffrey R. Carter
  2006-10-19 22:20       ` Robert A Duff
  2006-10-20  7:25       ` Maciej Sobczak
  2 siblings, 2 replies; 45+ messages in thread
From: Jeffrey R. Carter @ 2006-10-19 20:07 UTC (permalink / raw)


markww wrote:
> Ok, am I understanding this correctly - if I just '#include" the
> command line package:

"with" is significantly different from simple text inclusion. Most of 
what you know from C/++ is wrong for Ada. The sooner you can stop 
thinking in C/++ and start thinking in Ada, the easier you will find it.

>     with Ada.Command_Line; use Ada.Command_Line;

As a beginner, I would strongly recommend that you avoid "use", at least 
until you understand Ada's visibility rules better.

> then the package defines the functions:
> 
>     function Argument_Count return Natural;
>     function Argument (Number : in Positive) return String;
> 
> for me which I can use from then on?
> 
> So in my little app I can just use them like:
> 
>     Number_Of_Elements := Argument(0);
> 
> (assuming the 0th argument is the # of elements to allocate...)

As you quoted, Argument's parameter Number has subtype Positive. Zero is 
not a value of Positive. So such a call will raise Constraint_Error. In 
Ada, as in life, we usually count or number things starting from 1. 
Getting away from the low-level, offset-oriented C mindset is part of 
learning to think in Ada.

ARM A.15 says, "If the external execution environment supports passing 
arguments to a program, then Argument returns an implementation-defined 
value corresponding to the argument at relative position Number. If 
Number is outside the range 1..Argument_Count, then Constraint_Error is 
propagated."

So, if you have a single argument, it will be number 1. If you have 2, 
they will be 1 and 2. And so on.

It's a good idea to get familiar with Annex A.

Second, Argument's return type is String. Assuming Number_Of_Elements is 
the same type as the value being assigned to it (String), assigning 
complete Strings is usually not a good idea, since source and target 
must be the same length.

Finally, assuming that Number_Of_Elements is, as its name suggests, an 
object of a numeric type, source and target have different types, and 
the statement will result in a compilation error.

-- 
Jeff Carter
"I fart in your general direction."
Monty Python & the Holy Grail
05



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

* Re: basic basic ada question
  2006-10-19 14:30 basic basic ada question markww
  2006-10-19 14:47 ` Georg Bauhaus
  2006-10-19 15:11 ` Dmitry A. Kazakov
@ 2006-10-19 21:30 ` James Alan Farrell
  2006-10-19 23:03   ` Robert A Duff
                     ` (2 more replies)
  2 siblings, 3 replies; 45+ messages in thread
From: James Alan Farrell @ 2006-10-19 21:30 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2641 bytes --]

markww wrote:
> Hi,
> 
> Can someone give me an example of a command line app where I can read
> in command line arguments?
> 
> In C++ we have:
> 
> int main(int argc, char **argv)
> {
>     printf("There are [%i] arguments.\n", argc);
>     return 0;
> }
> 
> all I have so far in ada is:
> 
> 
>     with Ada.Text_IO; use Ada.Text_IO;
>     procedure DynamicArray is
>     begin
> 
>         -- Tell the user what we're doing.
>         Put_Line ("This application will allocate a dynamic array.");
> 
>         -- Now allocate a dynamic array.
>         Name : array (0 .. 20) of INTEGER
> 
>         -- That's it.
> 
>     end DynamicArray;
> 
> eventually I'd like to allocate that array based on the number of
> elements passed as an argument by the user.
> 
> Thanks,
> Mark
> 

-- start code

with Ada.Text_IO;
with Ada.Command_Line;
procedure Main is
    Parm_Max : constant := 1024;
    subtype Arg_String_Chars is String(1 .. Parm_Max);

    type Arg_String is record
       Len   : Integer;
       Chars : Arg_String_Chars;
    end record;

    Argc : Integer := Ada.Command_Line.Argument_Count;
    Argv : array(1 .. Argc) of Arg_String;
begin
    for I in 1 .. Argc loop
       Argv(I).Len := Ada.Command_Line.Argument(I)'Length;
       Argv(I).chars(1..Argv(I).Len) := Ada.Command_Line.Argument(I);
    end loop;

    for I in 1 .. Argc loop
       Ada.Text_IO.Put_Line(Argv(I).chars(1 .. Argv(I).Len));
    end loop;
end Main;

-- end code

Some comments:
1. I created an array to hold the command string so I could include the 
length.  The 'length attribute gives the length of the array with no 
consideration of the contents of the array.  So without some external 
reference to the length you will print out 1024 characters for each 
parameter, no matter how long the parameter really is.

2. There does not seem to be an argument(0).  It appears to be the case 
you cannot reference the name used to call the program.

3. The array is not actually dynamically allocated, but it is sized to 
the number of parameters.

4. All parameters are stored in arrays of 1024 characters, which is 
innefficient.  It would be possible to declare a string access type and 
allocate a string on the heap for each parameter.  (Mostly I've used Ada 
in safety critical environments where that is considered bad form.)  But 
if you do this the need for the record goes away because you can then 
use the 'length attribute to write out the argument.

I don't think it is possible to have different length strings holding 
the arrays without using accesses and dynamic allocations (someone 
correct me if I'm wrong).

James Alan Farrell

[-- Attachment #2: jfarrell.vcf --]
[-- Type: text/x-vcard, Size: 88 bytes --]

begin:vcard
fn:James Alan Farrell
n:Farrell;James
org:GrammaTech
version:2.1
end:vcard


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

* Re: basic basic ada question
  2006-10-19 20:07     ` Jeffrey R. Carter
@ 2006-10-19 22:20       ` Robert A Duff
  2006-10-20  5:10         ` Jeffrey R. Carter
  2006-10-20  7:25       ` Maciej Sobczak
  1 sibling, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-19 22:20 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.not.jrcarter@acm.not.spam.org> writes:

> markww wrote:
>> Ok, am I understanding this correctly - if I just '#include" the
>> command line package:
>
> "with" is significantly different from simple text inclusion.

True, but they serve roughly the same purpose, in practise.  For someone
coming from the C world, it's not so bad to think that a package spec is
a cleaner way to do .h files, and "with" is a cleaner way to do
#include.

>...Most of
> what you know from C/++ is wrong for Ada. The sooner you can stop
> thinking in C/++ and start thinking in Ada, the easier you will find it.

Why should one think in C or Ada?  There are lots of concepts that
transcend the languages.  After all, both languages have subroutines,
parameter passing, stack/heap allocation, etc, etc.

>>     with Ada.Command_Line; use Ada.Command_Line;
>
> As a beginner, I would strongly recommend that you avoid "use", at least
> until you understand Ada's visibility rules better.

Probably a good idea.

>> then the package defines the functions:
>>     function Argument_Count return Natural;
>>     function Argument (Number : in Positive) return String;
>> for me which I can use from then on?
>> So in my little app I can just use them like:
>>     Number_Of_Elements := Argument(0);
>> (assuming the 0th argument is the # of elements to allocate...)
>
> As you quoted, Argument's parameter Number has subtype Positive. Zero is
> not a value of Positive. So such a call will raise Constraint_Error. In
> Ada, as in life, we usually count or number things starting from
> 1. Getting away from the low-level, offset-oriented C mindset is part of
> learning to think in Ada.

Well, actually, the first argument is numbered 1 in C, too.  ;-)
argv[0] is what Ada calls Command_Name -- not one of the arguments.

Dijkstra wrote an interesting paper called "Why numbering should start
at zero", which you can find via google.  I don't buy it -- I like to
number most things starting at 1, despite his fairly reasonable
arguments to the contrary.

It's interesting that for enumeration types, T'Pos starts numbering
at 0.

- Bob



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

* Re: basic basic ada question
  2006-10-19 21:30 ` James Alan Farrell
@ 2006-10-19 23:03   ` Robert A Duff
  2006-10-20  4:54   ` Jeffrey R. Carter
  2006-10-20  7:53   ` Dmitry A. Kazakov
  2 siblings, 0 replies; 45+ messages in thread
From: Robert A Duff @ 2006-10-19 23:03 UTC (permalink / raw)


James Alan Farrell <jfarrell@nospam.com> writes:

> 2. There does not seem to be an argument(0).  It appears to be the case
> you cannot reference the name used to call the program.

No, you can.  Take a look at the Command_Line package in the RM.

> 4. All parameters are stored in arrays of 1024 characters, which is
> innefficient.

And it's an annoying arbitrary limitation.

>...  It would be possible to declare a string access type and
> allocate a string on the heap for each parameter.  (Mostly I've used Ada
> in safety critical environments where that is considered bad form.)  But
> if you do this the need for the record goes away because you can then
> use the 'length attribute to write out the argument.
>
> I don't think it is possible to have different length strings holding
> the arrays without using accesses and dynamic allocations (someone
> correct me if I'm wrong).

That's correct, but the Unbounded_Strings package can be used to hide
the dynamic allocation.  Probably not appropriate for your safety
critical environments, but sensible in other environments.

- Bob



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

* Re: basic basic ada question
  2006-10-19 21:30 ` James Alan Farrell
  2006-10-19 23:03   ` Robert A Duff
@ 2006-10-20  4:54   ` Jeffrey R. Carter
  2006-10-20  7:53   ` Dmitry A. Kazakov
  2 siblings, 0 replies; 45+ messages in thread
From: Jeffrey R. Carter @ 2006-10-20  4:54 UTC (permalink / raw)


James Alan Farrell wrote:
> 
> 2. There does not seem to be an argument(0).  It appears to be the case 
> you cannot reference the name used to call the program.

Ada.Command_Line.Command_Name serves this purpose.

> 4. All parameters are stored in arrays of 1024 characters, which is 
> innefficient.  It would be possible to declare a string access type and 
> allocate a string on the heap for each parameter.  (Mostly I've used Ada 
> in safety critical environments where that is considered bad form.)  But 
> if you do this the need for the record goes away because you can then 
> use the 'length attribute to write out the argument.
> 
> I don't think it is possible to have different length strings holding 
> the arrays without using accesses and dynamic allocations (someone 
> correct me if I'm wrong).

Use of Ada.Strings.[Un]Bounded would be preferable to reinventing this 
wheel.

-- 
Jeff Carter
"I fart in your general direction."
Monty Python & the Holy Grail
05



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

* Re: basic basic ada question
  2006-10-19 22:20       ` Robert A Duff
@ 2006-10-20  5:10         ` Jeffrey R. Carter
  2006-10-20  7:13           ` Maciej Sobczak
  0 siblings, 1 reply; 45+ messages in thread
From: Jeffrey R. Carter @ 2006-10-20  5:10 UTC (permalink / raw)


Robert A Duff wrote:
> 
> Why should one think in C or Ada?  There are lots of concepts that
> transcend the languages.  After all, both languages have subroutines,
> parameter passing, stack/heap allocation, etc, etc.

The Ada mindset is essentially the same as the SW engineering mindset.

> Well, actually, the first argument is numbered 1 in C, too.  ;-)
> argv[0] is what Ada calls Command_Name -- not one of the arguments.

To C, it's one of the arguments (the 1st, so naturally it's numbered 0). 
Ada realizes that it's not. It's the command that the arguments are 
arguments to.

> Dijkstra wrote an interesting paper called "Why numbering should start
> at zero", which you can find via google.  I don't buy it -- I like to
> number most things starting at 1, despite his fairly reasonable
> arguments to the contrary.

I've seen it, and I don't buy it, either. My experience is that fewer 
mistakes are made when the numbering from the domain is used. Some of 
his arguments, such as ease of calculating the length of a sequence, are 
things that the language should do for you. There should be 'Length for 
discrete subtypes; it returns the number of values in the subtype.

> It's interesting that for enumeration types, T'Pos starts numbering
> at 0.

Yes. They're not Pos-itions, they're offsets. Positions should start at 
1. If they did, then T'Base'First could be 0. That might be useful in 
some cases.

-- 
Jeff Carter
"I fart in your general direction."
Monty Python & the Holy Grail
05



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

* Re: basic basic ada question
  2006-10-20  5:10         ` Jeffrey R. Carter
@ 2006-10-20  7:13           ` Maciej Sobczak
  2006-10-20 20:39             ` Jeffrey R. Carter
  0 siblings, 1 reply; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-20  7:13 UTC (permalink / raw)


Jeffrey R. Carter wrote:

>> Why should one think in C or Ada?  There are lots of concepts that
>> transcend the languages.  After all, both languages have subroutines,
>> parameter passing, stack/heap allocation, etc, etc.
> 
> The Ada mindset is essentially the same as the SW engineering mindset.

Cool sentence, but I know another: "Computers think in C".

Both are good (and actually used) in flamewars.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-19 20:07     ` Jeffrey R. Carter
  2006-10-19 22:20       ` Robert A Duff
@ 2006-10-20  7:25       ` Maciej Sobczak
  2006-10-20 20:54         ` Jeffrey R. Carter
  1 sibling, 1 reply; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-20  7:25 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> Most of 
> what you know from C/++ is wrong for Ada.

It's a bit of overstatement and I, personally, don't find it to be the 
case. I would rather claim that if someone brings some bad habits from C 
or C++ to Ada, they were already bad habits in C and C++ anyway.

> The sooner you can stop 
> thinking in C/++ and start thinking in Ada, the easier you will find it.

Thinking in Ada is probably the same bad idea as thinking in C or C++ - 
at least if the final goal is not to have fun with the language (that's 
also a valid reason to write programs, really), but rather to build good 
final software. In this latter case thinking in terms of good 
engineering principles is the keyword - and then either any given 
language makes the implementation of these principles possible or not. 
This means that "thinking" in any particular language is already a bad 
idea and *using* the language to implement the chosen engineering 
principles is much more correct.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-19 21:30 ` James Alan Farrell
  2006-10-19 23:03   ` Robert A Duff
  2006-10-20  4:54   ` Jeffrey R. Carter
@ 2006-10-20  7:53   ` Dmitry A. Kazakov
  2006-10-20  8:17     ` Maciej Sobczak
  2006-10-20 21:00     ` Jeffrey R. Carter
  2 siblings, 2 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-20  7:53 UTC (permalink / raw)


On Thu, 19 Oct 2006 17:30:59 -0400, James Alan Farrell wrote:

> I don't think it is possible to have different length strings holding 
> the arrays without using accesses and dynamic allocations (someone 
> correct me if I'm wrong).

It is unclear why somebody would need an array of arguments, because
Ada.Command_Line.Argument already is an "array." There is no syntax
difference between arrays and functions of single argument. Looking at
Argument (I) you cannot tell if Argument is an array or not.

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



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

* Re: basic basic ada question
  2006-10-20  7:53   ` Dmitry A. Kazakov
@ 2006-10-20  8:17     ` Maciej Sobczak
  2006-10-20  9:08       ` Dmitry A. Kazakov
  2006-10-20 21:00     ` Jeffrey R. Carter
  1 sibling, 1 reply; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-20  8:17 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> There is no syntax
> difference between arrays and functions of single argument. Looking at
> Argument (I) you cannot tell if Argument is an array or not.

Nor you can tell if it's a type conversion.

Ada consistently promotes explicit syntax for readability reasons, you 
know. ;-)

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-20  8:17     ` Maciej Sobczak
@ 2006-10-20  9:08       ` Dmitry A. Kazakov
  2006-10-20 11:15         ` Maciej Sobczak
  2006-10-20 15:27         ` Robert A Duff
  0 siblings, 2 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-20  9:08 UTC (permalink / raw)


On Fri, 20 Oct 2006 10:17:16 +0200, Maciej Sobczak wrote:

> Dmitry A. Kazakov wrote:
> 
>> There is no syntax
>> difference between arrays and functions of single argument. Looking at
>> Argument (I) you cannot tell if Argument is an array or not.
> 
> Nor you can tell if it's a type conversion.

> Ada consistently promotes explicit syntax for readability reasons, you 
> know. ;-)

Exactly! Because wether Argument (I) is a function call, array indexing,
conversion, that is an implementation detail for the reader.

Note that, probably unlike others, I wouldn't object to add [x], {x}, <x>,
|x|, (*x*), <+x+> and so on, brackets to Ada. But I do object to binding
language semantics to the tuple brackets. Any semantic difference between
A[x,y] and A(x,y) should come solely from the application domain. That is
not language business. Also, let's allow [], but then they should be
allowed to subprograms, as well as type conversions, entry points etc.

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



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

* Re: basic basic ada question
  2006-10-20  9:08       ` Dmitry A. Kazakov
@ 2006-10-20 11:15         ` Maciej Sobczak
  2006-10-20 12:19           ` Dmitry A. Kazakov
  2006-10-20 19:04           ` Simon Wright
  2006-10-20 15:27         ` Robert A Duff
  1 sibling, 2 replies; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-20 11:15 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

>>> There is no syntax
>>> difference between arrays and functions of single argument. Looking at
>>> Argument (I) you cannot tell if Argument is an array or not.
>> Nor you can tell if it's a type conversion.
> 
>> Ada consistently promotes explicit syntax for readability reasons, you 
>> know. ;-)
> 
> Exactly! Because wether Argument (I) is a function call, array indexing,
> conversion, that is an implementation detail for the reader.

Interesting, but I prefer to see it completely the other way round.
The function call, array indexing and conversion are concepts that 
convey some meaning to the reader (for example, with array indexing one 
can assume the lookup semantics, whereas for function call it's value 
computation) and thus should look different. On the implementation 
detail level, however, whether it's direct indexing or maybe overloaded 
function is not important. Thus (C++):

a = b(c); // value computation
a = b[c]; // lookup
a = static_cast<b>(c); // translation to domain b

I don't care how they are implemented, but I care about their meaning.

I agree that this is very subjective.

> Note that, probably unlike others, I wouldn't object to add [x], {x}, <x>,
> |x|, (*x*), <+x+> and so on, brackets to Ada. But I do object to binding
> language semantics to the tuple brackets. Any semantic difference between
> A[x,y] and A(x,y) should come solely from the application domain.

Yes. So we agree. :-)

> That is
> not language business.

Well, language has to allow you to implement these operations.

 > Also, let's allow [], but then they should be
> allowed to subprograms, as well as type conversions, entry points etc.

It can be whatever - but the presence of square brackets in the source 
code means for me "lookup". Like phonebook lookup.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-20 11:15         ` Maciej Sobczak
@ 2006-10-20 12:19           ` Dmitry A. Kazakov
  2006-10-20 12:38             ` Maciej Sobczak
  2006-10-20 15:29             ` Robert A Duff
  2006-10-20 19:04           ` Simon Wright
  1 sibling, 2 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-20 12:19 UTC (permalink / raw)


On Fri, 20 Oct 2006 13:15:23 +0200, Maciej Sobczak wrote:

> Dmitry A. Kazakov wrote:
> 
>>>> There is no syntax
>>>> difference between arrays and functions of single argument. Looking at
>>>> Argument (I) you cannot tell if Argument is an array or not.
>>> Nor you can tell if it's a type conversion.
>> 
>>> Ada consistently promotes explicit syntax for readability reasons, you 
>>> know. ;-)
>> 
>> Exactly! Because wether Argument (I) is a function call, array indexing,
>> conversion, that is an implementation detail for the reader.
> 
> Interesting, but I prefer to see it completely the other way round.
> The function call, array indexing and conversion are concepts that 
> convey some meaning to the reader (for example, with array indexing one 
> can assume the lookup semantics, whereas for function call it's value 
> computation) and thus should look different. On the implementation 
> detail level, however, whether it's direct indexing or maybe overloaded 
> function is not important. Thus (C++):
> 
> a = b(c); // value computation
> a = b[c]; // lookup
> a = static_cast<b>(c); // translation to domain b
> 
> I don't care how they are implemented, but I care about their meaning.
> 
> I agree that this is very subjective.

See, because you could not formalize either "lookup" or "computation"
semantics. [Well, "translation" is nothing but just an explicit
sub/supertype constructor.]

There is nothing but behavior and the behavior is determined by the
subprogram named "()" or "[]" and the types of the parameters: a,b,c (the
result and the dedicated argument included).

[ Assignment should be a primitive operation, of course ]

>> That is
>> not language business.
> 
> Well, language has to allow you to implement these operations.

Sure. Indexing operation (BTW, aggregates, ".", X'Attribute, "in", ".all"
too) should be primitive. The problem is that one cannot to it right
without 1) MD, 2) a proper construction model, 3) a more elaborated
subroutine extension mechanics than just inherit vs. replace.

It is a great chunk, and I saw no language where 1-3 were reasonably
solved.

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



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

* Re: basic basic ada question
  2006-10-20 12:19           ` Dmitry A. Kazakov
@ 2006-10-20 12:38             ` Maciej Sobczak
  2006-10-20 13:26               ` Dmitry A. Kazakov
  2006-10-20 15:29             ` Robert A Duff
  1 sibling, 1 reply; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-20 12:38 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

>> a = b(c); // value computation
>> a = b[c]; // lookup
>> a = static_cast<b>(c); // translation to domain b
>>
>> I don't care how they are implemented, but I care about their meaning.
>>
>> I agree that this is very subjective.
> 
> See, because you could not formalize either "lookup" or "computation"
> semantics.

Of course - just as I cannot formalize the rule that variable names 
should be meaningful. Still, some informal wisdom allows me to pick 
names (and/or operators) that have this property. :-)

> [Well, "translation" is nothing but just an explicit
> sub/supertype constructor.]

In a sense, yes. The cast operator just sticks out more visibly.

> Indexing operation (BTW, aggregates, ".", X'Attribute, "in", ".all"
> too) should be primitive. The problem is that one cannot to it right
> without 1) MD, 2) a proper construction model, 3) a more elaborated
> subroutine extension mechanics than just inherit vs. replace.

What's MD and what is really needed for 3)?


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-20 12:38             ` Maciej Sobczak
@ 2006-10-20 13:26               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-20 13:26 UTC (permalink / raw)


On Fri, 20 Oct 2006 14:38:21 +0200, Maciej Sobczak wrote:

> Dmitry A. Kazakov wrote:
> 
>> Indexing operation (BTW, aggregates, ".", X'Attribute, "in", ".all"
>> too) should be primitive. The problem is that one cannot to it right
>> without 1) MD, 2) a proper construction model, 3) a more elaborated
>> subroutine extension mechanics than just inherit vs. replace.
> 
> What's MD and what is really needed for 3)?

MD = multiple dispatch. I assumed the obvious: all types have to have
classes and almost all public operations should be either primitive or
class-wide.

For 3 there should be some sane way to bring together class-wide and
primitive (dispatching) operations. The most notorious case is represented
by constructors and destructors (and aggregates too). Clearly, if there
existed a solution for constructors, then exactly the same technique could
be exposed to all other subprograms. Dispatch upon construction is
seemingly necessary and re-dispatch obviously contradicts to the
requirement "classes for all." This IMO means that there should be a
mixture of class-wide and primitive parts of the body of some
"hyper-primitive" (:-)) subprogram defined on the class. Basically you have
three "quarks":

Q1. The things you wish to enforce on the base type (defined on Base_Type)
Q2. The things specific to the base type (defined on Base_Type)
Q3. The things you wish to enforce on all derived types (defined on
Base_Type'Class)

Q1 is a classic extension as found in C++ constructors; Q2 can be
overridden/inherited; Q3 is some class-wide part from which one can
dispatch on already constructed object. More precisely Q3 acts on the
polymorphic object which invariant is true. Q1 and Q2 maintain the
invariants of specific types.

For destructors the order is reverse Q3-Q2-Q1.

For other operations it might be Q1-Q2-Q3-Q2'-Q1'.

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



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

* Re: basic basic ada question
  2006-10-20  9:08       ` Dmitry A. Kazakov
  2006-10-20 11:15         ` Maciej Sobczak
@ 2006-10-20 15:27         ` Robert A Duff
  2006-10-20 17:37           ` Dmitry A. Kazakov
  1 sibling, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-20 15:27 UTC (permalink / raw)


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

> Exactly! Because wether Argument (I) is a function call, array indexing,
> conversion, that is an implementation detail for the reader.

That argument would be more convincing if arrays and functions had the
same semantics.  E.g., "X := F(Y);" can have side effects if F is a
function, but not if F is an array.  And "F(Z) := ..." might or might
not make sense.

- Bob



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

* Re: basic basic ada question
  2006-10-20 12:19           ` Dmitry A. Kazakov
  2006-10-20 12:38             ` Maciej Sobczak
@ 2006-10-20 15:29             ` Robert A Duff
  2006-10-20 17:37               ` Dmitry A. Kazakov
  1 sibling, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-20 15:29 UTC (permalink / raw)


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

>...2) a proper construction model, ...

What do you see as the problems with Ada's construction model?
I think "a function that returns T is a constructor for T"
is a pretty good idea.  I don't like the "all constructors
are implicit/anonymous" idea from C++ and others.

- Bob



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

* Re: basic basic ada question
  2006-10-20 15:29             ` Robert A Duff
@ 2006-10-20 17:37               ` Dmitry A. Kazakov
  2006-10-20 20:59                 ` Robert A Duff
  0 siblings, 1 reply; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-20 17:37 UTC (permalink / raw)


On Fri, 20 Oct 2006 11:29:35 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>>...2) a proper construction model, ...
> 
> What do you see as the problems with Ada's construction model?

1. All kinds of types without exceptions should support user-defined
constructors.

2. The semantics of construction / destruction of the bases should be
enforceable. (Presently only components enforce their construction
semantics). This requirement is applied to abstract bases, interfaces and
interfaces inherited from concrete types (presently not allowed)

3. Same for copy constructors. Assignment should be defined in terms of
copy constructors.

4. Dispatch. There should be a safe way to dispatch upon construction /
destruction. As I see it, this is related / equivalent to providing
class-wide constructors.

5. Determining constraints (and so the object size) from the constructor
parameters.

6. All types should support construction per user-defined aggregates.

> I think "a function that returns T is a constructor for T"
> is a pretty good idea.

A constructor (+ allocator) is a factory, but not every factory is a
constructor. A constructor produces a valid object from raw memory. Any
constructing function should in the end  directly or not call to a proper
constructor, which still exist, though maybe is language defined. So to
pretend that there is no one does not help the language. Clearly, when a
task is created there is a lot of things to happen before it becomes valid.
Even for simple types I prefer to think that the constructor is null,
rather than there is no one.

> I don't like the "all constructors
> are implicit/anonymous" idea from C++ and others.

But Ada allows declare X : T; thus it has default constructors. Why then
the user should not be able to override some parts of the constructor?

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



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

* Re: basic basic ada question
  2006-10-20 15:27         ` Robert A Duff
@ 2006-10-20 17:37           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-20 17:37 UTC (permalink / raw)


On Fri, 20 Oct 2006 11:27:18 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> Exactly! Because wether Argument (I) is a function call, array indexing,
>> conversion, that is an implementation detail for the reader.
> 
> That argument would be more convincing if arrays and functions had the
> same semantics.  E.g., "X := F(Y);" can have side effects if F is a
> function, but not if F is an array.  And "F(Z) := ..." might or might
> not make sense.

Yes, but if Ada provided abstract array interfaces then arrays and
functions would be fully symmetric.

I find it pitiful that Ada has no guts  to support

   Container (Key) := Element;

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



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

* Re: basic basic ada question
  2006-10-20 11:15         ` Maciej Sobczak
  2006-10-20 12:19           ` Dmitry A. Kazakov
@ 2006-10-20 19:04           ` Simon Wright
  1 sibling, 0 replies; 45+ messages in thread
From: Simon Wright @ 2006-10-20 19:04 UTC (permalink / raw)


Maciej Sobczak <no.spam@no.spam.com> writes:

> a = b[c]; // lookup

Am I imagining operator[] ? there may be some semantic implication of
the [] notation but the implementation is up to the implementer -- as
it should be, of course.



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

* Re: basic basic ada question
  2006-10-20  7:13           ` Maciej Sobczak
@ 2006-10-20 20:39             ` Jeffrey R. Carter
  0 siblings, 0 replies; 45+ messages in thread
From: Jeffrey R. Carter @ 2006-10-20 20:39 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> Cool sentence, but I know another: "Computers think in C".

Computers don't think, but they follow instructions in object code. 
"Real men write object code."

It indicates a good point: SW engineers deal with abstraction and try to 
ignore or hide implementation details as much as possible. Coders like 
to try to do everything at a low level.

-- 
Jeff Carter
"I was hobbling along, minding my own business, all of a
sudden, up he comes, cures me! One minute I'm a leper with
a trade, next minute my livelihood's gone! Not so much as a
'by your leave!' You're cured, mate. Bloody do-gooder!"
Monty Python's Life of Brian
76



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

* Re: basic basic ada question
  2006-10-20  7:25       ` Maciej Sobczak
@ 2006-10-20 20:54         ` Jeffrey R. Carter
  0 siblings, 0 replies; 45+ messages in thread
From: Jeffrey R. Carter @ 2006-10-20 20:54 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> It's a bit of overstatement and I, personally, don't find it to be the 
> case. I would rather claim that if someone brings some bad habits from C 
> or C++ to Ada, they were already bad habits in C and C++ anyway.

Well, yes. Overstatement tends to attract the attention, and thus get 
the reader to think about it. Saying "Ada is different from C" is 
obvious, and will be ignored. You'll still get Ada-C, with pointers 
everywhere. Saying "Everything you know from C is wrong" might get him 
looking for ways to do things differently.

> Thinking in Ada is probably the same bad idea as thinking in C or C++ - 
> at least if the final goal is not to have fun with the language (that's 
> also a valid reason to write programs, really), but rather to build good 
> final software. In this latter case thinking in terms of good 
> engineering principles is the keyword - and then either any given 
> language makes the implementation of these principles possible or not. 
> This means that "thinking" in any particular language is already a bad 
> idea and *using* the language to implement the chosen engineering 
> principles is much more correct.

I should have said "the Ada mindset", which is also known as "the SW 
engineering mindset", but when you're knocking out these posts you often 
don't have time to perfect your wording. But ...

Thinking in terms of the language is not as good as thinking in SW 
engineering concepts, but when a person is thinking in C/++, thinking in 
Ada is much closer to those concepts than the way the person is 
thinking. Getting a coder to consider thinking in such concepts is 
harder than getting him to consider thinking in another language. Once 
he starts thinking in Ada, the final step is much easier.

-- 
Jeff Carter
"I was hobbling along, minding my own business, all of a
sudden, up he comes, cures me! One minute I'm a leper with
a trade, next minute my livelihood's gone! Not so much as a
'by your leave!' You're cured, mate. Bloody do-gooder!"
Monty Python's Life of Brian
76



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

* Re: basic basic ada question
  2006-10-20 17:37               ` Dmitry A. Kazakov
@ 2006-10-20 20:59                 ` Robert A Duff
  2006-10-21 13:39                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-20 20:59 UTC (permalink / raw)


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

> On Fri, 20 Oct 2006 11:29:35 -0400, Robert A Duff wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>>...2) a proper construction model, ...
>> 
>> What do you see as the problems with Ada's construction model?
>
> 1. All kinds of types without exceptions should support user-defined
> constructors.

I agree.  Of course this is already true for constructor functions.
If you're talking about default values, then yes, I agree that it's
a kludge that records can have defaults (via component defaults)
but other types cannot.

But now that Ada 2005 allows limited constructor functions,
I wouldn't mind eliminating per-type default values altogether.
(I mean from a pure language-design point of view -- of course
nobody is going to make such an incompatible change to Ada.)

I prefer to say:

    X: Integer_Sequence := Empty;

rather than having Integer_Sequence default to an empty sequence.

Return-by-reference was a bad mistake in Ada 95.  It's very cool that in
Ada 2005 you can say:

    function F(...) return T;

where T is limited, contains tasks, etc, and F creates a new object of
type T.

> 2. The semantics of construction / destruction of the bases should be
> enforceable. (Presently only components enforce their construction
> semantics). This requirement is applied to abstract bases, interfaces and
> interfaces inherited from concrete types (presently not allowed)

I don't understand what you mean by the above.

It would be nice to have a feature to prevent uninitialized variables.

It would be nice to have invariants that constructor functions must
obey (similar to Eiffel).

But I'm not sure those are what you meant...

> 3. Same for copy constructors. Assignment should be defined in terms of
> copy constructors.

Yes.  We tried to do it that way in Ada 95, and failed, because we
didn't know how to make it work for types with defaulted discriminants.
There's some discussion of this in the AARM.

> 4. Dispatch. There should be a safe way to dispatch upon construction /
> destruction. As I see it, this is related / equivalent to providing
> class-wide constructors.

Again, not sure what you mean.  We do have class-wide functions.
How can dispatching work, when you are creating an object -- dispatching
requires a Tag, and that's part of what you're creating.

> 5. Determining constraints (and so the object size) from the constructor
> parameters.

Works fine for constructors-as-functions.  You can also use
discriminants as "parameters".

> 6. All types should support construction per user-defined aggregates.

Yes.  I strongly agree.  Also user-defined literals.

>> I think "a function that returns T is a constructor for T"
>> is a pretty good idea.

I should have said "returns a new object of type T" instead of just
"returns T".

> A constructor (+ allocator) is a factory, but not every factory is a
> constructor. A constructor produces a valid object from raw memory. Any
> constructing function should in the end  directly or not call to a proper
> constructor, which still exist, though maybe is language defined. So to
> pretend that there is no one does not help the language. Clearly, when a
> task is created there is a lot of things to happen before it becomes valid.
> Even for simple types I prefer to think that the constructor is null,
> rather than there is no one.

I think the above makes sense, although I'm not sure exactly what you
mean by "factory" -- to me, a factory is a module that constructs
objects, usually based on some parameters passed to it.

>> I don't like the "all constructors
>> are implicit/anonymous" idea from C++ and others.
>
> But Ada allows declare X : T; thus it has default constructors. Why then
> the user should not be able to override some parts of the constructor?

I'm not sure default constructors are really a good idea.  When you say
"X: T", you don't know (without looking at the private part where T is
declared) whether X is a valid object of type T, or just uninitialized
junk.  If default values are allowed, it seems to me that this
distinction should be part of the contract.

- Bob



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

* Re: basic basic ada question
  2006-10-20  7:53   ` Dmitry A. Kazakov
  2006-10-20  8:17     ` Maciej Sobczak
@ 2006-10-20 21:00     ` Jeffrey R. Carter
  2006-10-21  8:19       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 45+ messages in thread
From: Jeffrey R. Carter @ 2006-10-20 21:00 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> 
> It is unclear why somebody would need an array of arguments, because
> Ada.Command_Line.Argument already is an "array." There is no syntax
> difference between arrays and functions of single argument. Looking at
> Argument (I) you cannot tell if Argument is an array or not.

I presumed the array was simply for demonstrating the way to access 
various arguments. I can't recall any application that needed a copy of 
all the arguments.

But I've seen plenty of applications that need to process an argument or 
two, modifying it before being able to decide what to do with/because of 
it. In such cases it may be reasonable to copy the argument.

In many cases in C, this is done using strcpy into a fixed buffer, 
creating a buffer-overflow error. At least this Ada example raises an 
exception if the argument won't fit in the buffer.

-- 
Jeff Carter
"I was hobbling along, minding my own business, all of a
sudden, up he comes, cures me! One minute I'm a leper with
a trade, next minute my livelihood's gone! Not so much as a
'by your leave!' You're cured, mate. Bloody do-gooder!"
Monty Python's Life of Brian
76



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

* Re: basic basic ada question
  2006-10-20 21:00     ` Jeffrey R. Carter
@ 2006-10-21  8:19       ` Dmitry A. Kazakov
  2006-10-21 17:32         ` Robert A Duff
  0 siblings, 1 reply; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-21  8:19 UTC (permalink / raw)


On Fri, 20 Oct 2006 21:00:33 GMT, Jeffrey R. Carter wrote:

> But I've seen plenty of applications that need to process an argument or 
> two, modifying it before being able to decide what to do with/because of 
> it. In such cases it may be reasonable to copy the argument.
> 
> In many cases in C, this is done using strcpy into a fixed buffer, 
> creating a buffer-overflow error. At least this Ada example raises an 
> exception if the argument won't fit in the buffer.

Well, this is a more general issue than just command line arguments. As for
me I consider the very idea of tokenizing as harmful. It is unfortunate
that both C and Ada follow a wrong concept in the command line interface.
Tokenizing is just wasting resources. It is also useless when you have
delimiters other than spaces, keyed arguments, or some nested structure. I
prefer always to parse the original source: the command line as a whole. I
never copy anything.

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



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

* Re: basic basic ada question
  2006-10-19 15:10   ` markww
@ 2006-10-21 10:29     ` Stephen Leake
  0 siblings, 0 replies; 45+ messages in thread
From: Stephen Leake @ 2006-10-21 10:29 UTC (permalink / raw)


"markww" <markww@gmail.com> writes:

> Thanks for your response. I just don't understand how to implement it.
> In ada we have a function definition like:
>
> procedure DynamicArray is
> begin
>
>     -- Function body stuff here...
>     -- Where does Argument_Count come from?

The same place argc does in C.

>     
>     -- Where does Argument (0...numArgs) come from?

The same place argv does in C. Except Argument is a function, not an array.

> end DynamicArray;

I think you are missing how packages work in Ada; you need to go back
to your textbook.

Here's a working example:


with Ada.Command_Line;
with Ada.Text_IO;
procedure Demo is
begin
   Ada.Text_IO.Put_Line 
    ("Command line args: " & Integer'Image (Ada.Command_Line.Argument_Count));
   Ada.Text_IO.Put_Line 
    ("First        arg : '" & Ada.Command_Line.Argument (1) & "'");
end;

./demo.exe foo bar
Command line args:  2
First        arg : 'foo'

-- 
-- Stephe



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

* Re: basic basic ada question
  2006-10-20 20:59                 ` Robert A Duff
@ 2006-10-21 13:39                   ` Dmitry A. Kazakov
  2006-10-21 17:53                     ` Robert A Duff
  2006-10-23  7:45                     ` Maciej Sobczak
  0 siblings, 2 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-21 13:39 UTC (permalink / raw)


On Fri, 20 Oct 2006 16:59:49 -0400, Robert A Duff wrote:

> But now that Ada 2005 allows limited constructor functions,
> I wouldn't mind eliminating per-type default values altogether.
> (I mean from a pure language-design point of view -- of course
> nobody is going to make such an incompatible change to Ada.)
>
> I prefer to say:
> 
>     X: Integer_Sequence := Empty;
> 
> rather than having Integer_Sequence default to an empty sequence.

Of course. We could have the above retaining backward compatibility. Make
the default constructor of Integer_Sequence private and X :
Integer_Sequence; becomes illegal. Standard.Integer can still have its
default constructor visible and empty. For types like Integer_Sequence, for
which the compiler could invent a reasonable default constructor, we could
provide S'Empty attribute. So it would be:

   X: Integer_Sequence; -- Error
   X: Integer_Sequence := Integer_Sequence'Empty;
          -- OK, you know what you're doing

> Return-by-reference was a bad mistake in Ada 95.  It's very cool that in
> Ada 2005 you can say:
> 
>     function F(...) return T;
> 
> where T is limited, contains tasks, etc, and F creates a new object of
> type T.

Though it does not work with assignments.

>> 2. The semantics of construction / destruction of the bases should be
>> enforceable. (Presently only components enforce their construction
>> semantics). This requirement is applied to abstract bases, interfaces and
>> interfaces inherited from concrete types (presently not allowed)
> 
> I don't understand what you mean by the above.
> 
> It would be nice to have a feature to prevent uninitialized variables.

Invisible constructors are IMO ideal for this. As well as for expressing
"limitness" (= no copy constructor). An additional advantage is in that you
can name a constructor as a normal subroutine. So you can use standard
language tools to express classes and sets of types, rather than inventing
awkward reserved words like limited, private and their combinations.

> It would be nice to have invariants that constructor functions must
> obey (similar to Eiffel).
> 
> But I'm not sure those are what you meant...

I meant things like Initialize and Finalize. Presently, a derived type is
free to skip them. There obviously should be parts of user-defined
constructors which cannot be circumvented [otherwise than by
Unchecked_Conversion or Program_Error propagation].

>> 3. Same for copy constructors. Assignment should be defined in terms of
>> copy constructors.
> 
> Yes.  We tried to do it that way in Ada 95, and failed, because we
> didn't know how to make it work for types with defaulted discriminants.
> There's some discussion of this in the AARM.

That's because a constructor should not be considered as single subprogram
like factory. When instead of that you let the compiler generate a
constructor out of several distinct subprograms, you could solve the
problem by determining the discriminants (and other constraints) outside
the factory and also before memory allocation. Their values can be then
passed to the factory or checked before entering it.

>> 4. Dispatch. There should be a safe way to dispatch upon construction /
>> destruction. As I see it, this is related / equivalent to providing
>> class-wide constructors.
> 
> Again, not sure what you mean.  We do have class-wide functions.
> How can dispatching work, when you are creating an object -- dispatching
> requires a Tag, and that's part of what you're creating.

That's why it should be a class-wide constructor. You construct first a
specific object, then its class it constructed. At this point you can
dispatch, because the specific object is already sane. This applies only to
the tagged types which have class views and class-wide objects. So when you
construct either, first T is constructed and after that T'Class. If S were
derived from T, then construction of S could look like:

1. T's components
2. S's components
3. T (Initialize)
4. S (Initialize)
5. T'Class
    -- here a class-wide constructor defined for T can safely dispatch to a
    -- some primitive operation overridden by S
6. S'Class

[I am not sure about ordering 5 and 6]

>> 5. Determining constraints (and so the object size) from the constructor
>> parameters.
> 
> Works fine for constructors-as-functions.  You can also use
> discriminants as "parameters".

Not so fine. When an array is returned there is a good chance that it will
be copied.

>>> I think "a function that returns T is a constructor for T"
>>> is a pretty good idea.
> 
> I should have said "returns a new object of type T" instead of just
> "returns T".
>
>> A constructor (+ allocator) is a factory, but not every factory is a
>> constructor. A constructor produces a valid object from raw memory. Any
>> constructing function should in the end  directly or not call to a proper
>> constructor, which still exist, though maybe is language defined. So to
>> pretend that there is no one does not help the language. Clearly, when a
>> task is created there is a lot of things to happen before it becomes valid.
>> Even for simple types I prefer to think that the constructor is null,
>> rather than there is no one.
> 
> I think the above makes sense, although I'm not sure exactly what you
> mean by "factory" -- to me, a factory is a module that constructs
> objects, usually based on some parameters passed to it.

Yes, this is why I used "factory" instead of "constructing function."
Constructor is less than a factory. This is why it cannot be expressed as a
subprogram without strange looking tricks, like Ada 2005 return statement.

>>> I don't like the "all constructors
>>> are implicit/anonymous" idea from C++ and others.
>>
>> But Ada allows declare X : T; thus it has default constructors. Why then
>> the user should not be able to override some parts of the constructor?
> 
> I'm not sure default constructors are really a good idea.  When you say
> "X: T", you don't know (without looking at the private part where T is
> declared) whether X is a valid object of type T, or just uninitialized
> junk.  If default values are allowed, it seems to me that this
> distinction should be part of the contract.

Absolutely. The contract should say - there is a default constructor, so
one can write X : T. Of course I agree that an implied contract should
exclude the default constructor, as well as copy constructor (so
assignment), [in]equality, values like null etc.

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



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

* Re: basic basic ada question
  2006-10-21  8:19       ` Dmitry A. Kazakov
@ 2006-10-21 17:32         ` Robert A Duff
  2006-10-22  8:45           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-21 17:32 UTC (permalink / raw)


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

> Well, this is a more general issue than just command line arguments. As for
> me I consider the very idea of tokenizing as harmful. It is unfortunate
> that both C and Ada follow a wrong concept in the command line interface.
> Tokenizing is just wasting resources. It is also useless when you have
> delimiters other than spaces, keyed arguments, or some nested structure. I
> prefer always to parse the original source: the command line as a whole. I
> never copy anything.

How?  On many operating systems, the "shell" or whatever will do all
kinds of command-line parsing before you can get your hands on it.  On
Unix, it even expands wildcards (a rather bad design, IMHO).

- Bob



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

* Re: basic basic ada question
  2006-10-21 13:39                   ` Dmitry A. Kazakov
@ 2006-10-21 17:53                     ` Robert A Duff
  2006-10-22  8:45                       ` Dmitry A. Kazakov
  2006-10-23  7:45                     ` Maciej Sobczak
  1 sibling, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-21 17:53 UTC (permalink / raw)


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

[lots of good stuff snipped]
> On Fri, 20 Oct 2006 16:59:49 -0400, Robert A Duff wrote:
>> Return-by-reference was a bad mistake in Ada 95.  It's very cool that in
>> Ada 2005 you can say:
>> 
>>     function F(...) return T;
>> 
>> where T is limited, contains tasks, etc, and F creates a new object of
>> type T.
>
> Though it does not work with assignments.

Assignment statements, you mean.  (The RM uses the term "assignment" for
both assignment_statements and initializations.)  Of course not!  If
assignment statements were allows for limited types, they wouldn't be
limited anymore.  The whole point of "limited" is to prevent copying (of
already-existing objects).

The mistake in Ada 83 and Ada 95 was in confusing initialization with
assignment_statement.  They are rather different things --
initialization starts out with an empty bucket of meaningless bits.

> I meant things like Initialize and Finalize. Presently, a derived type is
> free to skip them. There obviously should be parts of user-defined
> constructors which cannot be circumvented [otherwise than by
> Unchecked_Conversion or Program_Error propagation].

Lisp has methods that are called in addition to the parent's method,
as well as the more usual methods that replace the parent's method.

There was some discussion in the ARG about a feature that would allow
you to declare that all overridings must call the parent operation.
Probably checked at compile time.  I don't think it went anywhere.

Initialize and Finalize are not the only operations that have this problem

> Not so fine. When an array is returned there is a good chance that it will
> be copied.

Arrays are no different than records in this regard.
Limited arrays are never copied on function return.
Nonlimited arrays need not be copied if the function
creates a new object to return, and the function is called
in an initialization context (as opposed to an assignment statement,
which must copy if the function itself can get its hands on the
left-hand side).

- Bob



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

* Re: basic basic ada question
  2006-10-21 17:53                     ` Robert A Duff
@ 2006-10-22  8:45                       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-22  8:45 UTC (permalink / raw)


On Sat, 21 Oct 2006 13:53:30 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
> [lots of good stuff snipped]
>> On Fri, 20 Oct 2006 16:59:49 -0400, Robert A Duff wrote:
>>> Return-by-reference was a bad mistake in Ada 95.  It's very cool that in
>>> Ada 2005 you can say:
>>> 
>>>     function F(...) return T;
>>> 
>>> where T is limited, contains tasks, etc, and F creates a new object of
>>> type T.
>>
>> Though it does not work with assignments.
> 
> Assignment statements, you mean.  (The RM uses the term "assignment" for
> both assignment_statements and initializations.)  Of course not!  If
> assignment statements were allows for limited types, they wouldn't be
> limited anymore.  The whole point of "limited" is to prevent copying (of
> already-existing objects).

How could this be  prevented? We have to distinguish semantic copying and
copying the compiler uses for its purposes. You cannot forbid the first,
the programmer can always write something which would produce an object
equivalent the original in the sense known only to the programmer. It is
outside the language scope. "Limited" means the second. It don't see why
the name Copy in

   type T is limited ...;
   procedure Copy (X : in out T; Y : T);

is any better or worse than the name ":=". A mistake of Ada was to treat
":=" as a statement. Clearly, the statement is procedure call. ":=" is just
a name of the primitive operation. 

> The mistake in Ada 83 and Ada 95 was in confusing initialization with
> assignment_statement.  They are rather different things --
> initialization starts out with an empty bucket of meaningless bits.

Right. Because initialization = pure constructor. Assignment = destructor +
constructor or alternatively object state changer. One cannot bring all
these under the roof of a factory function. It cannot work this way,
without a perversion of very meaning of "function".

>> I meant things like Initialize and Finalize. Presently, a derived type is
>> free to skip them. There obviously should be parts of user-defined
>> constructors which cannot be circumvented [otherwise than by
>> Unchecked_Conversion or Program_Error propagation].
> 
> Lisp has methods that are called in addition to the parent's method,
> as well as the more usual methods that replace the parent's method.
> 
> There was some discussion in the ARG about a feature that would allow
> you to declare that all overridings must call the parent operation.
> Probably checked at compile time.  I don't think it went anywhere.

That would be awful. Surely the calls must be inserted by the compiler.
Just like in C++.

> Initialize and Finalize are not the only operations that have this problem

Yes. This mechanics should be available for all primitive operations.

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



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

* Re: basic basic ada question
  2006-10-21 17:32         ` Robert A Duff
@ 2006-10-22  8:45           ` Dmitry A. Kazakov
  2006-10-30 11:46             ` Martin Krischik
  0 siblings, 1 reply; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-22  8:45 UTC (permalink / raw)


On Sat, 21 Oct 2006 13:32:45 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> Well, this is a more general issue than just command line arguments. As for
>> me I consider the very idea of tokenizing as harmful. It is unfortunate
>> that both C and Ada follow a wrong concept in the command line interface.
>> Tokenizing is just wasting resources. It is also useless when you have
>> delimiters other than spaces, keyed arguments, or some nested structure. I
>> prefer always to parse the original source: the command line as a whole. I
>> never copy anything.
> 
> How?  On many operating systems, the "shell" or whatever will do all
> kinds of command-line parsing before you can get your hands on it.  On
> Unix, it even expands wildcards (a rather bad design, IMHO).

Surely depends on OS. In Windows there is GetCommandLine.

I didn't criticise design of Ada.Command_Line, rather I did the idea of
tokenizing, when the programmer acts like a hamster storing things here and
there. Most of them he will never find again. I don't know whether
"hamster" programming stems from UNIX or just influenced it. (:-))

As for Ada.Command_Line, it could provide function Command return String;
with a remark that depending on the OS its result might be not very
authentic. [Neither Argument's result is.]

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



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

* Re: basic basic ada question
  2006-10-21 13:39                   ` Dmitry A. Kazakov
  2006-10-21 17:53                     ` Robert A Duff
@ 2006-10-23  7:45                     ` Maciej Sobczak
  2006-10-23  9:21                       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-23  7:45 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> That's why it should be a class-wide constructor. You construct first a
> specific object, then its class it constructed. At this point you can
> dispatch, because the specific object is already sane. This applies only to
> the tagged types which have class views and class-wide objects. So when you
> construct either, first T is constructed and after that T'Class. If S were
> derived from T, then construction of S could look like:
> 
> 1. T's components
> 2. S's components
> 3. T (Initialize)
> 4. S (Initialize)
> 5. T'Class
>     -- here a class-wide constructor defined for T can safely dispatch to a
>     -- some primitive operation overridden by S
> 6. S'Class
> 
> [I am not sure about ordering 5 and 6]

And I am not sure why do you need 5 and 6 at all - you've already done 
the whole job in 3 and 4.
Note also that having all these points (3-6) opens wide opportunities 
for duplicated actions and other maintenance nightmares. For me 4 should 
be the last step and 5,6 should not exist at all.

And you could safely change the order for 2 and 3.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-23  7:45                     ` Maciej Sobczak
@ 2006-10-23  9:21                       ` Dmitry A. Kazakov
  2006-10-23 14:30                         ` Maciej Sobczak
  0 siblings, 1 reply; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-23  9:21 UTC (permalink / raw)


On Mon, 23 Oct 2006 09:45:31 +0200, Maciej Sobczak wrote:

> Dmitry A. Kazakov wrote:
> 
>> That's why it should be a class-wide constructor. You construct first a
>> specific object, then its class it constructed. At this point you can
>> dispatch, because the specific object is already sane. This applies only to
>> the tagged types which have class views and class-wide objects. So when you
>> construct either, first T is constructed and after that T'Class. If S were
>> derived from T, then construction of S could look like:
>> 
>> 1. T's components
>> 2. S's components
>> 3. T (Initialize)
>> 4. S (Initialize)
>> 5. T'Class
>>     -- here a class-wide constructor defined for T can safely dispatch to a
>>     -- some primitive operation overridden by S
>> 6. S'Class
>> 
>> [I am not sure about ordering 5 and 6]
> 
> And I am not sure why do you need 5 and 6 at all - you've already done 
> the whole job in 3 and 4.

You cannot dispatch to the procedures of S from Initialize of T, i.e. from
3 before 4 is done. S might be unusable. The step 5 is for this purpose.

> Note also that having all these points (3-6) opens wide opportunities 
> for duplicated actions and other maintenance nightmares.

It is difficult to say. In Ada there is a clean distinction between T and
T'Class. So many things will be difficult to duplicate without an explicit
type conversion. Normally, actions called from 5 would be abstract
primitive operations. You'll get a compile error calling them from 3. Same
with class-wide operations.

> For me 4 should 
> be the last step and 5,6 should not exist at all.

Which is indeed a maintenance disaster. Consider GUI interfaces built in
C++. Note that practically all of them have procedures like OnInit, because
it is eventually impossible to construct widgets fully functional. Ada
suffers this as well. For example, it is impossible to embed task
components. You need special Start/Stop entries in the tasks.

I see this as a consequence of incomplete construction model which does not
allow to define actions on the class. [ OnInit is that sort of action.
Presently, you have to be call it manually, and you have a composition
problem of many OnInit's along the inheritance chain.]

> And you could safely change the order for 2 and 3.

I think so.

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



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

* Re: basic basic ada question
  2006-10-23  9:21                       ` Dmitry A. Kazakov
@ 2006-10-23 14:30                         ` Maciej Sobczak
  2006-10-23 15:08                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 45+ messages in thread
From: Maciej Sobczak @ 2006-10-23 14:30 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

>>> 1. T's components
>>> 2. S's components
>>> 3. T (Initialize)
>>> 4. S (Initialize)
>>> 5. T'Class
>>>     -- here a class-wide constructor defined for T can safely dispatch to a
>>>     -- some primitive operation overridden by S
>>> 6. S'Class
>>>
>>> [I am not sure about ordering 5 and 6]
>> And I am not sure why do you need 5 and 6 at all - you've already done 
>> the whole job in 3 and 4.
> 
> You cannot dispatch to the procedures of S from Initialize of T, i.e. from
> 3 before 4 is done. S might be unusable. The step 5 is for this purpose.

But why would you need to dispatch to S after step 4?

>> For me 4 should 
>> be the last step and 5,6 should not exist at all.
> 
> Which is indeed a maintenance disaster. Consider GUI interfaces built in
> C++. Note that practically all of them have procedures like OnInit, because
> it is eventually impossible to construct widgets fully functional. Ada
> suffers this as well. For example, it is impossible to embed task
> components. You need special Start/Stop entries in the tasks.

But then, the construction process will involve the interaction with 
other objects and that's why automating all 6 steps above for a single 
object will not necessarily solve the problem. In the case of GUI, you 
might want to construct widgets somewhere between 4 and 5. The 
OnInit-like procedures provide explicit hooks for this.
I any case, if there is a way to get rid of OnInit, I think it should be 
possible without 5 and 6 anyway - possibly with additional objects 
involved instead, but I'd prefer more elaborate collaboration pattern 
(which is explicit in the design) in place of more elaborate 
construction mechanism (which is implicit).


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



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

* Re: basic basic ada question
  2006-10-23 14:30                         ` Maciej Sobczak
@ 2006-10-23 15:08                           ` Dmitry A. Kazakov
  2006-10-23 15:49                             ` Robert A Duff
  0 siblings, 1 reply; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-23 15:08 UTC (permalink / raw)


On Mon, 23 Oct 2006 16:30:23 +0200, Maciej Sobczak wrote:

> Dmitry A. Kazakov wrote:
> 
>>>> 1. T's components
>>>> 2. S's components
>>>> 3. T (Initialize)
>>>> 4. S (Initialize)
>>>> 5. T'Class
>>>>     -- here a class-wide constructor defined for T can safely dispatch to a
>>>>     -- some primitive operation overridden by S
>>>> 6. S'Class
>>>>
>>>> [I am not sure about ordering 5 and 6]
>>> And I am not sure why do you need 5 and 6 at all - you've already done 
>>> the whole job in 3 and 4.
>> 
>> You cannot dispatch to the procedures of S from Initialize of T, i.e. from
>> 3 before 4 is done. S might be unusable. The step 5 is for this purpose.
> 
> But why would you need to dispatch to S after step 4?

type T is abstract ...;
function Greeting_Message return String is abstract;
procedure Initialize (X : in out T) is
begin
   Put_Line ("Hi," & Greeting_Message (T'Class (X))); -- Illegal!
end Initialize;

type S is new T with ...;
function Greeting_Message return String is
begin
   return "I am T!";
end Greeting_Message;

>>> For me 4 should 
>>> be the last step and 5,6 should not exist at all.
>> 
>> Which is indeed a maintenance disaster. Consider GUI interfaces built in
>> C++. Note that practically all of them have procedures like OnInit, because
>> it is eventually impossible to construct widgets fully functional. Ada
>> suffers this as well. For example, it is impossible to embed task
>> components. You need special Start/Stop entries in the tasks.
> 
> But then, the construction process will involve the interaction with 
> other objects and that's why automating all 6 steps above for a single 
> object will not necessarily solve the problem. In the case of GUI, you 
> might want to construct widgets somewhere between 4 and 5. The 
> OnInit-like procedures provide explicit hooks for this.
> I any case, if there is a way to get rid of OnInit, I think it should be 
> possible without 5 and 6 anyway - possibly with additional objects 
> involved instead, but I'd prefer more elaborate collaboration pattern 
> (which is explicit in the design) in place of more elaborate 
> construction mechanism (which is implicit).

OO spaghetti, in short...

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



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

* Re: basic basic ada question
  2006-10-23 15:08                           ` Dmitry A. Kazakov
@ 2006-10-23 15:49                             ` Robert A Duff
  2006-10-24  7:34                               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 45+ messages in thread
From: Robert A Duff @ 2006-10-23 15:49 UTC (permalink / raw)


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

> type T is abstract ...;
> function Greeting_Message return String is abstract;

I presume the above is supposed to say (X : T), right?
If so, I don't see anything illegal here.

> procedure Initialize (X : in out T) is
> begin
>    Put_Line ("Hi," & Greeting_Message (T'Class (X))); -- Illegal!
> end Initialize;
>
> type S is new T with ...;
> function Greeting_Message return String is
> begin
>    return "I am T!";
> end Greeting_Message;

- Bob



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

* Re: basic basic ada question
  2006-10-23 15:49                             ` Robert A Duff
@ 2006-10-24  7:34                               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 45+ messages in thread
From: Dmitry A. Kazakov @ 2006-10-24  7:34 UTC (permalink / raw)


On Mon, 23 Oct 2006 11:49:17 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> type T is abstract ...;
>> function Greeting_Message return String is abstract;
> 
> I presume the above is supposed to say (X : T), right?

Yes, my fault.

> If so, I don't see anything illegal here.

OK, I didn't specifically mean Ada.

As for Ada if Initialize were a declared part of the default constructor,
then view conversions to the class could be statically detected and made
illegal. Though, I would consider to disallow them for the types to replace
present tagged types. I mean the types with the type tag stored in the
objects. For the tag-less types it not a problem, because T'Class would
create a new object constructed through a copy constructor.

>> procedure Initialize (X : in out T) is
>> begin
>>    Put_Line ("Hi," & Greeting_Message (T'Class (X))); -- Illegal!
>> end Initialize;
>>
>> type S is new T with ...;
>> function Greeting_Message return String is
>> begin
>>    return "I am T!";
>> end Greeting_Message;

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



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

* Re: basic basic ada question
  2006-10-22  8:45           ` Dmitry A. Kazakov
@ 2006-10-30 11:46             ` Martin Krischik
  0 siblings, 0 replies; 45+ messages in thread
From: Martin Krischik @ 2006-10-30 11:46 UTC (permalink / raw)


Dmitry A. Kazakov schrieb:
> On Sat, 21 Oct 2006 13:32:45 -0400, Robert A Duff wrote:
> 
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>
>>> Well, this is a more general issue than just command line arguments. As for
>>> me I consider the very idea of tokenizing as harmful. It is unfortunate
>>> that both C and Ada follow a wrong concept in the command line interface.
>>> Tokenizing is just wasting resources. It is also useless when you have
>>> delimiters other than spaces, keyed arguments, or some nested structure. I
>>> prefer always to parse the original source: the command line as a whole. I
>>> never copy anything.
>> How?  On many operating systems, the "shell" or whatever will do all
>> kinds of command-line parsing before you can get your hands on it.  On
>> Unix, it even expands wildcards (a rather bad design, IMHO).
> 
> Surely depends on OS. In Windows there is GetCommandLine.
> 
> I didn't criticise design of Ada.Command_Line, rather I did the idea of
> tokenizing, when the programmer acts like a hamster storing things here and
> there. Most of them he will never find again. I don't know whether
> "hamster" programming stems from UNIX or just influenced it. (:-))
> 
> As for Ada.Command_Line, it could provide function Command return String;
> with a remark that depending on the OS its result might be not very
> authentic. [Neither Argument's result is.]

function Command return Wide_String;
function Command return Wide_Wide_String;

Martin



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

end of thread, other threads:[~2006-10-30 11:46 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-19 14:30 basic basic ada question markww
2006-10-19 14:47 ` Georg Bauhaus
2006-10-19 15:10   ` markww
2006-10-21 10:29     ` Stephen Leake
2006-10-19 15:11 ` Dmitry A. Kazakov
2006-10-19 15:45   ` markww
2006-10-19 16:29     ` Gautier
2006-10-19 17:16     ` Dmitry A. Kazakov
2006-10-19 20:07     ` Jeffrey R. Carter
2006-10-19 22:20       ` Robert A Duff
2006-10-20  5:10         ` Jeffrey R. Carter
2006-10-20  7:13           ` Maciej Sobczak
2006-10-20 20:39             ` Jeffrey R. Carter
2006-10-20  7:25       ` Maciej Sobczak
2006-10-20 20:54         ` Jeffrey R. Carter
2006-10-19 21:30 ` James Alan Farrell
2006-10-19 23:03   ` Robert A Duff
2006-10-20  4:54   ` Jeffrey R. Carter
2006-10-20  7:53   ` Dmitry A. Kazakov
2006-10-20  8:17     ` Maciej Sobczak
2006-10-20  9:08       ` Dmitry A. Kazakov
2006-10-20 11:15         ` Maciej Sobczak
2006-10-20 12:19           ` Dmitry A. Kazakov
2006-10-20 12:38             ` Maciej Sobczak
2006-10-20 13:26               ` Dmitry A. Kazakov
2006-10-20 15:29             ` Robert A Duff
2006-10-20 17:37               ` Dmitry A. Kazakov
2006-10-20 20:59                 ` Robert A Duff
2006-10-21 13:39                   ` Dmitry A. Kazakov
2006-10-21 17:53                     ` Robert A Duff
2006-10-22  8:45                       ` Dmitry A. Kazakov
2006-10-23  7:45                     ` Maciej Sobczak
2006-10-23  9:21                       ` Dmitry A. Kazakov
2006-10-23 14:30                         ` Maciej Sobczak
2006-10-23 15:08                           ` Dmitry A. Kazakov
2006-10-23 15:49                             ` Robert A Duff
2006-10-24  7:34                               ` Dmitry A. Kazakov
2006-10-20 19:04           ` Simon Wright
2006-10-20 15:27         ` Robert A Duff
2006-10-20 17:37           ` Dmitry A. Kazakov
2006-10-20 21:00     ` Jeffrey R. Carter
2006-10-21  8:19       ` Dmitry A. Kazakov
2006-10-21 17:32         ` Robert A Duff
2006-10-22  8:45           ` Dmitry A. Kazakov
2006-10-30 11:46             ` Martin Krischik

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