February 23, 2002
"Barry Pederson" <barryp@yahoo.com> wrote in message news:3C77CFDD.2050404@yahoo.com...
> I've been following this debate about slices and cases with some interest.
As
> a Python programmer, I'm rooting for end-exclusiveness in slices - it's
the
> way Python handles slices, and seems to work very well in practice.  If D sticks with that, then I think there'll be a lot of Python programmers who will be able to make use of it very comfortably.
>
> Another Python-ish thing that might be worth considering would be support
for
> negative array indexes.  For example:
>
>     foo[-1]  is the last element of array foo
>     foo[-2]  is the second-to-last element of array foo
>
> then with slices
>
>     foo[-2..] would be the last two elements of foo
>     foo[1..-1] would be a copy of foo, except for the first and last
elements
>
> implementation should be pretty simple, for any index < 0, such as:
foo[-n],
> the compiler would just treat it like: foo[foo.length - n]

While this is a great idea, it suffers from a serious problem - the compiler will have to insert a runtime check for negative indices whenever the index expression is not a constant. This will be too much overhead.


> CASES
> ----------
>
> When it comes to case-ranges though, I agree that end-exclusiveness would
be a
> weird PITA.  Perhaps the thing to do is decide that case-ranges and array-slices will be different things, and go ahead and use different
syntaxes.
>
> To steal from Python again, perhaps use a colon for array slicing
(foo[1:-1])
> and keep '..' for case-ranges (which seems pretty natural).
>
> This would also kind of make sense if you also supported Python-style
negative
> array indexes, since negative numbers in case-ranges would presumably have
a
> completely different meaning.

Yes, using a different syntax may be the best solution.


February 26, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a56tc4$1534$2@digitaldaemon.com...
>
> "Pavel Minayev" <evilone@omen.ru> wrote in message news:a562qa$5lv$1@digitaldaemon.com...
> > This is a far better idea. What I like in Pascal is the ability to
> > use 0-based, 1-based or whatever else based arrays depending on
> > your task and your personal taste. Those who care of speed (me) would
> > probably use 0-based (and I believe it should be the default, to
> > work the same way as in C/C++). Otherwise, you can specify it yourself:
> >
> >     int[5]    foo;     // consists of foo[0] to foo[4]
> >     int[1..5] bar;     // consists of bar[1] to bar[5]
>
> Having lower bounds specifiable will work with D (and even with C), but in
> my decades (!) of programming I've never found a use for it. I came to C
> from Basic, FORTRAN, and Pascal.

Instead I have some Pascal sources that will keep as they are. When I do
programming I want to use all features the language provides. And my old
Pascal sources are full of sets, subrange variables, nested procedures,
arbitrary
indexed arrays, and so on.
Automatic code translators simply produce unmaintainable code, once I
started
to translate one of them in C++, but I stopped when I realized I'd have to
work hard
to produce a huge set of classes only to support base Pascal capabilities,
with a
big loss in readability.

> I had some initial trouble getting used to
> 0 based rather than 1 based, but never looked back. 0 based looked more
> 'right' to me.

Don't confuse normal initial trouble with language expressiveness lack.
I know that, at the end, an array index must be translated to a 0-based
integer.
But simply doing the translation myself doesn't seem to me the right
solution in
most cases.

So I agree with Pavel: array should be 0-based by default, letting the
possibility
to choose a different start index if needed, stating clearly that n-based
indexes are
less performant.

Ciao


February 27, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a562qa$5lv$1@digitaldaemon.com...
> "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a55s13$1c8a$1@digitaldaemon.com...
>
<SNIP>
> This is a far better idea. What I like in Pascal is the ability to
> use 0-based, 1-based or whatever else based arrays depending on
> your task and your personal taste. Those who care of speed (me) would
> probably use 0-based (and I believe it should be the default, to
> work the same way as in C/C++). Otherwise, you can specify it yourself:
>
>     int[5]    foo;     // consists of foo[0] to foo[4]
>     int[1..5] bar;     // consists of bar[1] to bar[5]
>


Seconded!


--
Stijn
OddesE_XYZ@hotmail.com
http://OddesE.cjb.net
__________________________________________
Remove _XYZ from my address when replying by mail




February 27, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a562qa$5lv$1@digitaldaemon.com...
> "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a55s13$1c8a$1@digitaldaemon.com...
<SNIP>
> This is a far better idea. What I like in Pascal is the ability to
> use 0-based, 1-based or whatever else based arrays depending on
> your task and your personal taste. Those who care of speed (me) would
> probably use 0-based (and I believe it should be the default, to
> work the same way as in C/C++). Otherwise, you can specify it yourself:
>
>     int[5]    foo;     // consists of foo[0] to foo[4]
>     int[1..5] bar;     // consists of bar[1] to bar[5]
>


And maybe make a property, array.StartIndex so
you could always dynamically find out what the
start index of the array is!


--
Stijn
OddesE_XYZ@hotmail.com
http://OddesE.cjb.net
__________________________________________
Remove _XYZ from my address when replying by mail



February 27, 2002
"OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:a5jajn$168e$1@digitaldaemon.com...

> And maybe make a property, array.StartIndex so
> you could always dynamically find out what the
> start index of the array is!

Then maybe:

    array.start    // first index
    array.end      // last index
    array.length   // length (end - start + 1)

And define this for all arrays, including 0-based.


February 27, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a56tc4$1534$2@digitaldaemon.com...

> Having lower bounds specifiable will work with D (and even with C), but in my decades (!) of programming I've never found a use for it. I came to C from Basic, FORTRAN, and Pascal. I had some initial trouble getting used
to
> 0 based rather than 1 based, but never looked back. 0 based looked more 'right' to me.

Well, there are actually cases where you'd prefer some base other than 0.
As you've seen, many people here consider 1 to be more suitable, and
I understand them... also there are some other cases, for example, suppose
you have an array of year income for 1990-2000, in Pascal you'd probably
declare it as "array[1990 .. 2000] of integer", and then index it like
income[1995], letting the compiler do his job and insert all the necessary
decrements; the result is clean code, easy to read and maintain. In C,
you have to do it all yourself, and probably define some const base = 1990,
and clutter all your code with things like income[1995 - base].

After all, it's as simple as subtracting the base from the index, a single SUB... ain't it worth the thing?


February 28, 2002
On a related note, Pascal had succ and pred for enums, but from what I remember didn't have first and last?

All four would be quite handy to have for enums... unfortunately if you can define your own values for an enumerant, succ and pred become (at runtime) a function containing a switch statement or table lookup.

Personally I think enums *should* be sequential, and a separate flags type could deal with bitflags.  typedef'd ints can handle any other case.

Sean

"Pavel Minayev" <evilone@omen.ru> wrote in message news:a5jb30$16ij$1@digitaldaemon.com...
> "OddesE" <OddesE_XYZ@hotmail.com> wrote in message news:a5jajn$168e$1@digitaldaemon.com...
>
> > And maybe make a property, array.StartIndex so
> > you could always dynamically find out what the
> > start index of the array is!
>
> Then maybe:
>
>     array.start    // first index
>     array.end      // last index
>     array.length   // length (end - start + 1)
>
> And define this for all arrays, including 0-based.



February 28, 2002
"Sean L. Palmer" <spalmer@iname.com> wrote in message news:a5l3t1$1ua6$1@digitaldaemon.com...

> On a related note, Pascal had succ and pred for enums, but from what I remember didn't have first and last?

Yes, right. Succ and Pred, however, were defined for all ordinal types, not just enums.

> All four would be quite handy to have for enums... unfortunately if you
can
> define your own values for an enumerant, succ and pred become (at runtime)
a
> function containing a switch statement or table lookup.

There's the same problem in Pascal (it supports custom values for enum members since Delphi 6, AFAIK), and it's handled in a somewhat strange manner: Succ always means +1, and Pred is -1, regardless of what declaration says. So:

    type TEnum = (foo = 1000, bar = 2000, baz = 3000);

The thing is, Pascal defines enum as "a subrange whose lowest and highest values correspond to the lowest and highest ordinalities of the constants in the declaration". So variable of type TEnum can take any value in range 1000 .. 3000, and thus, Succ and Pred just inrements/decrements by one...

> Personally I think enums *should* be sequential, and a separate flags type could deal with bitflags.  typedef'd ints can handle any other case.

It is sometimes very convenient to define an enum with members equal to those of API:

    enum Key
    {
        LButton = 1,
        RButton = 2,
        Cancel = 3,
        MButton = 4,
        Back = 8, BackSpace = Back,
        Tab = 9,
        Clear = 12,
        Return = 13, Enter = Return,
        Shift = 16,
        Control = 17,
        ...
    }

Now every Key, being casted to int, equals the appropriate VK_* constant - no need for switch() or alike.



March 01, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a5labi$214t$1@digitaldaemon.com...
> "Sean L. Palmer" <spalmer@iname.com> wrote in message news:a5l3t1$1ua6$1@digitaldaemon.com...
>
> > On a related note, Pascal had succ and pred for enums, but from what I remember didn't have first and last?
>
> Yes, right. Succ and Pred, however, were defined for all ordinal types, not just enums.

Right.  Used it in place of ++ and -- alot.

> > All four would be quite handy to have for enums... unfortunately if you
> can
> > define your own values for an enumerant, succ and pred become (at
runtime)
> a
> > function containing a switch statement or table lookup.
>
> There's the same problem in Pascal (it supports custom values for enum members since Delphi 6, AFAIK), and it's handled in a somewhat strange manner: Succ always means +1, and Pred is -1, regardless of what declaration says. So:
>
>     type TEnum = (foo = 1000, bar = 2000, baz = 3000);
>
> The thing is, Pascal defines enum as "a subrange whose lowest and highest values correspond to the lowest and highest ordinalities of the constants in the declaration". So variable of type TEnum can take any value in range 1000 .. 3000, and thus, Succ and Pred just inrements/decrements by one...

That's why I think enums should be limited to sequential values.

> > Personally I think enums *should* be sequential, and a separate flags
type
> > could deal with bitflags.  typedef'd ints can handle any other case.
>
> It is sometimes very convenient to define an enum with members equal to those of API:
>
>     enum Key
>     {
>         LButton = 1,
>         RButton = 2,
>         Cancel = 3,
>         MButton = 4,
>         Back = 8, BackSpace = Back,
>         Tab = 9,
>         Clear = 12,
>         Return = 13, Enter = Return,
>         Shift = 16,
>         Control = 17,
>         ...
>     }
>
> Now every Key, being casted to int, equals the appropriate VK_* constant - no need for switch() or alike.

So what's so inconvenient about this?

typedef int VKCode;   // in D I believe this makes a distinct type which
behaves identically to int except for type conversion can't
                                   // be implicitly done from int to VKCode
(though I think the opposite still happens implicitly)
static const VKCode
        LButton = 1,
        RButton = 2,
        Cancel = 3,
        MButton = 4,
        Back = 8, BackSpace = Back,
        Tab = 9,
        Clear = 12,
        Return = 13, Enter = Return,
        Shift = 16,
        Control = 17;  // this is assuming that implicit conversion from int
to VKCode can still be done in the initializer.
                               // if you think about it, that's really an
explicit conversion anyway, don't you think?

That's how I'd like it to be handled, anyway.

Sean


March 01, 2002
"Sean L. Palmer" <spalmer@iname.com> wrote in message news:a5nm1p$r0$1@digitaldaemon.com...

> So what's so inconvenient about this?
>
> typedef int VKCode;   // in D I believe this makes a distinct type which
> behaves identically to int except for type conversion can't
>                                    // be implicitly done from int to
VKCode
> (though I think the opposite still happens implicitly)
> static const VKCode
>         LButton = 1,
>         RButton = 2,
>         Cancel = 3,
>         MButton = 4,
>         Back = 8, BackSpace = Back,
>         Tab = 9,
>         Clear = 12,
>         Return = 13, Enter = Return,
>         Shift = 16,
>         Control = 17;  // this is assuming that implicit conversion from
int
> to VKCode can still be done in the initializer.
>                                // if you think about it, that's really an
> explicit conversion anyway, don't you think?

The difference is that enum defines its own namespace.
So it'd be Key.Enter, Key.Tab, Key.A etc... I don't see
any other way to do it apart from declaring a separate class
specially for that - probably not the best idea...