www.digitalmars.com         C & C++   DMDScript  

D - Feature suggestions

reply "Ben Cohen" <bc skygate.co.uk> writes:
Hi,

D seems to be a really nice idea -- I've been looking for a language which
has these features.  I have some suggestions for the few places where (I
think) I have different ideas or preferences:


Multiple Inheritance: 
   There are some advantages to multiple inheritance.  Note that the problems
   normally occur when you try to inherit a class in more than one way,
   so that you have inherited twice from an ancestor; we could call this
   "incest" and disallow it but allow other multiple inheritance.  This
   also makes the language syntax a bit simpler (since you don't need
   "interface").


Potentially dangerous C features:
   Since the language is not directly C-compatible, it would be nice to
   remove some common problems with C:
      - Accidental fallthoughs in switches:   these could be prevented using
        a goto (like C#) or a compulsory continue or fallthrough statement.
      - Forgetting { } around a code block:   braces could be made
        compulsory, or a style more like Ada's blocking could be used.
      - Side-effects:  using side-effects is regarded as confusing and could be
        disallowed.


Possible new features:
   Similarly, it might be worth adding some features from other languages
   such as Python:
      - Tuples are quite nice, for example to return more than one value from 
        a function.  It would be OK to say that the type has to be 
        determinable at runtime.
      - Lists would be useful for operations such as appending and slicing.
        It would be OK for the type to be the same, like an array.  (Perhaps
        the dynamic array type could have these properties?)
      - Ranges are an idea I have which I haven't seen implemented but which
        might prevent off-by-one errors.  It would be a type derived from a
        base type (int, float, char,...) which has a start, an end and a
        length; its value depends on any two of these since the third is then
        fixed.  Then any of the three could be used (e.g., x = range.length). 
      - It would be nice to be able to say "foreach i in set" where set is
        a range, list or array.


Does the order of declarations in a file matter?  In C it does, but in Java 
it doesn't; I think it would be nicer if D didn't.  For example, in C if 
you define a function foo() which calls function bar(), but bar() is 
defined later in the same file, then you have to give a prototype.


Can variables in D be declared in the middle of code blocks (like Java) or
only at the start (like C)?  I am not sure which is preferable.


Being able to use C libraries is great -- one of the fundamental things I 
wanted in the language.  However, how do you plan to deal with importing
the C include files?  Is there any easy way to handle this?


If the name is a problem, other corny variants on C are possible such as
Object-Improved C, or Seymour;)  (Sequel is also OK but is taken, sort of.)


Ben.
Aug 16 2001
parent reply "Walter" <walter digitalmars.com> writes:
"Ben Cohen" <bc skygate.co.uk> wrote in message
news:9lgtfa$2g90$1 digitaldaemon.com...
 Hi,
 D seems to be a really nice idea -- I've been looking for a language which
 has these features.  I have some suggestions for the few places where (I
 think) I have different ideas or preferences:

Fire away.
 Multiple Inheritance:
    There are some advantages to multiple inheritance.  Note that the

    normally occur when you try to inherit a class in more than one way,
    so that you have inherited twice from an ancestor; we could call this
    "incest" and disallow it but allow other multiple inheritance.  This
    also makes the language syntax a bit simpler (since you don't need
    "interface").

Experience suggests that single inheritance with interfaces will cover nearly all the bases. I know some people really do want MI, but my eyes always glaze over trying to understand it, and I think I'll just stay away!
 Potentially dangerous C features:
    Since the language is not directly C-compatible, it would be nice to
    remove some common problems with C:
       - Accidental fallthoughs in switches:   these could be prevented

         a goto (like C#) or a compulsory continue or fallthrough

This keeps coming up. I happen to use the fallthrough thing a lot, and just don't want to give it up! I also suspect that removing it may make for a difficult transition from C to D, since one can get soooo used to the fallthrough.
       - Forgetting { } around a code block:   braces could be made
         compulsory, or a style more like Ada's blocking could be used.

This is already true in some cases, you can't do: while (...) ; since that is likely a typo. Instead, use: while (...) { } for an empty loop.
       - Side-effects:  using side-effects is regarded as confusing and

         disallowed.

This is a good idea, and it can be approached with the compiler, but not absolutely solved.
 Possible new features:
    Similarly, it might be worth adding some features from other languages
    such as Python:
       - Tuples are quite nice, for example to return more than one value

         a function.  It would be OK to say that the type has to be
         determinable at runtime.

Tuples are a great idea, but the D way is to use out parameters.
       - Lists would be useful for operations such as appending and

         It would be OK for the type to be the same, like an array.

         the dynamic array type could have these properties?)

I think the dynamic array will cover these uses.
       - Ranges are an idea I have which I haven't seen implemented but

         might prevent off-by-one errors.  It would be a type derived from

         base type (int, float, char,...) which has a start, an end and a
         length; its value depends on any two of these since the third is

         fixed.  Then any of the three could be used (e.g., x =

That looks like it might be a reasonable extension to enums.
       - It would be nice to be able to say "foreach i in set" where set is
         a range, list or array.

 Does the order of declarations in a file matter?  In C it does, but in

 it doesn't; I think it would be nicer if D didn't.  For example, in C if
 you define a function foo() which calls function bar(), but bar() is
 defined later in the same file, then you have to give a prototype.

The order does not matter. It is surprising how liberating that is.
 Can variables in D be declared in the middle of code blocks (like Java) or
 only at the start (like C)?  I am not sure which is preferable.

In the middle. I think it makes for more readable code as you can locate the declaration next to where it is used.
 Being able to use C libraries is great -- one of the fundamental things I
 wanted in the language.  However, how do you plan to deal with importing
 the C include files?  Is there any easy way to handle this?

I've been thinking of writing a tool to convert a .h file into an import file. Having a C compiler, this would not be too difficult. The trouble comes from attempting to convert macro constants into enums. It's unlikely the tool would do a perfect job, it'd require some hand editting of the result.
 If the name is a problem, other corny variants on C are possible such as
 Object-Improved C, or Seymour;)  (Sequel is also OK but is taken, sort

The name "D" started out as a joke from my friends, but it just kinda stuck. Finally, I just gave in and search & replaced the name to "D" in the documentation. Funny how things work out <g>.
Aug 16 2001
next sibling parent reply "Ben Cohen" <bc skygate.co.uk> writes:
In article <9lh4a4$2ok1$1 digitaldaemon.com>, "Walter"
<walter digitalmars.com> wrote:

 Potentially dangerous C features:
    Since the language is not directly C-compatible, it would be nice to
    remove some common problems with C:
       - Accidental fallthoughs in switches:   these could be prevented

         a goto (like C#) or a compulsory continue or fallthrough

This keeps coming up. I happen to use the fallthrough thing a lot, and just don't want to give it up! I also suspect that removing it may make for a difficult transition from C to D, since one can get soooo used to the fallthrough.
       - Forgetting { } around a code block:   braces could be made
         compulsory, or a style more like Ada's blocking could be used.

This is already true in some cases, you can't do: while (...) ; since that is likely a typo. Instead, use: while (...) { } for an empty loop.

I also think that changes from C to D should be minimised, and should be limited to useful extensions, simplifying the language, and making the language safer. So, for example, your alteration to struct's namespace is great (I would have done that) since it simplifies the language; while In, Out, InOut make the language safer and even simplify it a bit (since you don't then need pointers so much). You want D to be for people who "routinely use lint..." and "compile with maximum warning levels...", so I would think that one of the language's aims would be to be as safe as possible to program in. I think the two problems above are two of the most common C pitfalls which you haven't already addressed. I like the suggestion for treatment of switches by Mark Shackelford ("Suggestions: switch, case, also, elsif syntax"). Incidentally, can you do a ``break label'' out of a switch? I agree that enforcing {} rather than just ; for an empty while is good. Enforcing {} for a single statement looks messy and would be irritating at first because C programmers aren't used to it, but it might be worth it. The alternative would be having something like Ada: if ... statements statements endif This has the disadvantage that it no longer looks like C (and is slower to type). I am not sure which I prefer here.
 Possible new features:
    Similarly, it might be worth adding some features from other
    languages such as Python:
       - Tuples are quite nice, for example to return more than one
       value

         a function.  It would be OK to say that the type has to be
         determinable at runtime.

Tuples are a great idea, but the D way is to use out parameters.

Or structs/objects (if you want to plug several return values from one function into another)... OK.
       - Lists would be useful for operations such as appending and

         It would be OK for the type to be the same, like an array.

         the dynamic array type could have these properties?)

I think the dynamic array will cover these uses.

That's what I was hoping -- so the dynamic array can change its length even when it is instantiated and has values.
       - Ranges are an idea I have which I haven't seen implemented but

         might prevent off-by-one errors.  It would be a type derived
         from

         base type (int, float, char,...) which has a start, an end and
         a length; its value depends on any two of these since the third
         is

         fixed.  Then any of the three could be used (e.g., x =

That looks like it might be a reasonable extension to enums.

That looks like a sensible way to do it.
       - It would be nice to be able to say "foreach i in set" where set
       is
         a range, list or array.


Is there a way to do this?
 Does the order of declarations in a file matter?  In C it does, but in

 it doesn't; I think it would be nicer if D didn't.  For example, in C
 if you define a function foo() which calls function bar(), but bar() is
 defined later in the same file, then you have to give a prototype.

The order does not matter. It is surprising how liberating that is.

That's really good.
 If the name is a problem, other corny variants on C are possible such
 as Object-Improved C, or Seymour;)  (Sequel is also OK but is taken,
 sort

The name "D" started out as a joke from my friends, but it just kinda stuck. Finally, I just gave in and search & replaced the name to "D" in the documentation. Funny how things work out <g>.

Yes, D (or P;) is a much more `traditional' sequel to C! What would you have called it?
Aug 17 2001
next sibling parent reply Christophe de Dinechin <descubes earthlink.net> writes:
 This keeps coming up. I happen to use the fallthrough thing a lot, and
 just don't want to give it up! I also suspect that removing it may make
 for a difficult transition from C to D, since one can get soooo used to
 the fallthrough.

       - Forgetting { } around a code block:   braces could be made
         compulsory, or a style more like Ada's blocking could be used.

This is already true in some cases, you can't do: while (...) ; since that is likely a typo. Instead, use: while (...) { } for an empty loop.


I see a problem with the reasoning here: "I make that mistake, so I remove it from the language (while {}), but I use the other feature, so I keep it even if it's a common mistake for others." I personally tend to use the semi-colon 'for' and 'while' forms regularly. Typically: for (list = first; list && !condition(list); list = list->next); On the other hand, I tend to "document" that, as well as fall throughs: for (list = first; list && !condition(list); list = list->next) /* nop */; if (list) switch (list->data) { case BIG: list->bigflag = true; /* fallthrough */ case SMALL: ... }
 I agree that enforcing {} rather than just ; for an empty while is good.
 Enforcing {} for a single statement looks messy and would be irritating at
 first because C programmers aren't used to it, but it might be worth it.
 The alternative would be having something like Ada:

 if ...
     statements
     statements
 endif

 This has the disadvantage that it no longer looks like C (and is slower to
 type).  I am not sure which I prefer here.

Or you can use intend-based syntax, as in LX or Python. It's remarkable how much "clutter" it removes from code: if condition then statements; statements if condition then statement statement statement // not in the if
 Possible new features:
    Similarly, it might be worth adding some features from other
    languages such as Python:
       - Tuples are quite nice, for example to return more than one
       value

         a function.  It would be OK to say that the type has to be
         determinable at runtime.

Tuples are a great idea, but the D way is to use out parameters.

Or structs/objects (if you want to plug several return values from one function into another)... OK.

Tuples actually are not the same thing as structs, and they are often more readable than out parameters (but not always, so having both is good.) (A, B, C) = foo(1, 2, 3) foo(1, 2, 3, A, B, C) foo(1, 2, 3, out A, out B, out C) LX doesn't support tuples as a language feature, but only because you can implement them in the library.
       - Lists would be useful for operations such as appending and

         It would be OK for the type to be the same, like an array.

         the dynamic array type could have these properties?)

I think the dynamic array will cover these uses.

That's what I was hoping -- so the dynamic array can change its length even when it is instantiated and has values.

Dynamic arrays and lists have very different performance characteristics. That's why the STL has both. As I said in other threads, BUILT-IN TYPES ARE EVIL.
       - Ranges are an idea I have which I haven't seen implemented but

         might prevent off-by-one errors.  It would be a type derived
         from

         base type (int, float, char,...) which has a start, an end and
         a length; its value depends on any two of these since the third
         is

         fixed.  Then any of the three could be used (e.g., x =

That looks like it might be a reasonable extension to enums.

That looks like a sensible way to do it.

Same thing: your language ought to be able to DEFINE range objects, rather than have to build them in.
Aug 17 2001
next sibling parent "Ben Cohen" <bc skygate.co.uk> writes:
In article <3B7D2DDC.C631FFE1 earthlink.net>, "Christophe de Dinechin"
<descubes earthlink.net> wrote:

 I see a problem with the reasoning here: "I make that mistake, so I
 remove it from the language (while {}), but I use the other feature, so
 I keep it even if it's a common mistake for others."
 
 I personally tend to use the semi-colon 'for' and 'while' forms
 regularly. Typically:
 
     for (list = first; list && !condition(list); list = list->next);
 
 On the other hand, I tend to "document" that, as well as fall throughs:
 
     for (list = first; list && !condition(list); list = list->next) /*
     nop
  */;

Python uses the "pass" statement which is explicit like this, but {} might be good enough.
     if (list)
         switch (list->data)
         {
         case BIG:
             list->bigflag = true;
             /* fallthrough */
         case SMALL:
             ...
         }

Yes, I'm basically asking that the language requires this comment, but makes it a keyword rather than a comment :)
 might be worth it. The alternative would be having something like Ada:

 if ...
     statements
     statements
 endif

 This has the disadvantage that it no longer looks like C (and is slower
 to type).  I am not sure which I prefer here.

Or you can use intend-based syntax, as in LX or Python. It's remarkable how much "clutter" it removes from code: if condition then statements; statements if condition then statement statement statement // not in the if

This is less cluttered but how often do lines accidentally not get indented enough? The Ada form is a bit more secure here since you can't get the indent wrong by mistake and you can't miss the endif out by mistake as it's required.
 Possible new features:
    Similarly, it might be worth adding some features from other
    languages such as Python:
       - Tuples are quite nice, for example to return more than one
       value

         a function.  It would be OK to say that the type has to be
         determinable at runtime.

Tuples are a great idea, but the D way is to use out parameters.

Or structs/objects (if you want to plug several return values from one function into another)... OK.

Tuples actually are not the same thing as structs, and they are often more readable than out parameters (but not always, so having both is good.)

Yes, I meant that if you needed to get some values from one function to place into another, assuming you'd designed them yourself, it could be more appropriate to define a struct instead. I'd envisaged tuples as a grouping notation, rather than as an actual language type; it would be determined at compile time (oops, I meant that, not runtime) as if you had defined a struct, but you don't have to as a convenience.
Aug 17 2001
prev sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
 I see a problem with the reasoning here: "I make that mistake, so I remove

 from the language (while {}), but I use the other feature, so I keep it

 if it's a common mistake for others."

 I personally tend to use the semi-colon 'for' and 'while' forms regularly.
 Typically:

     for (list = first; list && !condition(list); list = list->next);

I forgot about "for". ;)
 On the other hand, I tend to "document" that, as well as fall throughs:

     for (list = first; list && !condition(list); list = list->next) /* nop
 */;
     if (list)
         switch (list->data)
         {
         case BIG:
             list->bigflag = true;
             /* fallthrough */
         case SMALL:
             ...
         }

I also have to document my fallthroughs. This just illustrates why it'd be safer to have to specify you *want* to fall through, instead of having to specify that you don't. I'd much rather see the language modified like so: switch (list->data) { case BIG: list->bigflag = true; continue; // fall through to the next case case SMALL: init(); } I suppose an analysis on how frequently people break out of the switch at the end of the case vs how often they fall through. Aside from Duff's device, I'd wager that breaking out is much more frequent in typical C/C++ code. There way be some way to have either. Sean
Oct 23 2001
parent reply "Ben Cohen" <bc skygate.co.uk> writes:
In article <9r3di1$9oh$1 digitaldaemon.com>, "Sean L. Palmer"
<spalmer iname.com> wrote:


 On the other hand, I tend to "document" that, as well as fall throughs:

     for (list = first; list && !condition(list); list = list->next) /*
     nop
 */;
     if (list)
         switch (list->data)
         {
         case BIG:
             list->bigflag = true;
             /* fallthrough */
         case SMALL:
             ...
         }

I also have to document my fallthroughs. This just illustrates why it'd be safer to have to specify you *want* to fall through, instead of having to specify that you don't. I'd much rather see the language modified like so: switch (list->data) { case BIG: list->bigflag = true; continue; // fall through to the next case case SMALL: init(); }

I think you would have to keep the break, to help port existing code and to make the code clearer. (It could be confusing otherwise.) The other thing is that using the keyword "continue" could be a problem, since is can be used in C for a different purpose (i.e., jumping out of a containing loop), which would trip you up when porting from C to D. (In fact the use of break but not continue in C switches is a bit asymmetric.)
 I suppose an analysis on how frequently people break out of the switch
 at the end of the case vs how often they fall through.  Aside from
 Duff's device, I'd wager that breaking out is much more frequent in
 typical C/C++ code.

I would agree that breaking is probably more frequent. However, that was the reasoning by which K&R decided to use = for assignment and == for comparison (which is a frequent cause of errors) . The way C does it makes more intuitive sense to me -- you keep going until you are told to stop. I think it would be clearer if you have to use a keyword in both cases, so you can't accidentally omit it.
Oct 23 2001
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
In an earlier discussion, we got rid of the break/non-break problem (sort of)
by introducing a new syntax.  IMHO, the new syntax is more "C-like":

switch(list->data)
{
    case(BIG)
    {
        list->bigflag = true;
        continue case(SMALL);
           // continues into whichever case handles SMALL...even though it
turns out
           // that that case also handles MEDIUM
    };
    case(SMALL,MEDIUM)
    {
        init();
    };
    default
    {
        throw exception;
     };
};

Walter hasn't signed off on using this syntax, but I think that it really
looks good...

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Oct 23 2001
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
It's definitely not C-like, totally unlike C's switch.  But I like it.
Ditch the }; though.

Only problem is if the language ever allowed one to not put in a trailing
semi after a statement, and didn't require a block for each case, the syntax
for continue case(SMALL); might be confused with continue; case (SMALL) {}

Personally I don't like trailing semis for statement separation, but without
them it's hard to tell the difference between a valid

do
{
}
while (x)

{
}

and an invalid

do
{
}

while (x)
{
}

The language itself is still well-specified, but it makes it easier for
programmers to make mistakes.  However with semicolons the most common case
is to forget a semicolon, so I'm kinda willing to make that trade-off.  In
my script languages, I make semicolons optional.  If you want to protect
yourself, use them; if you're lazy, don't.  Same thing with parenthesis
around expressions in if/while statements... optional.  These are annoying
because everybody on my team at work types them out different than I do.

I type like this:

while (x > 5)
{}

they type like this:

while( x > 5 )
{}

which would of course not be a problem if you could just do this:

while x > 5
{}

I can see one issue with this:

if x
  *x = 7

Does that say:  if (x) *x = 7;  or does it say:  if (x*x = 7); which is an
error?  Programmer can always put in parenthesis to clarify... no, actually
in this case they can't, because if (x) *x = 7;  could be interpreted as
this longer expression:  if ((x)*x = 7)

Problem would be solved by two things:  Disallowing assignment in if/while
boolean expressions, and disallowing statements consisting of just an
expression that has no side-effects.  For instance  (a>b); wouldn't be a
legal statement, but assignments or function calls would be.

But oh yeah, we're talking about D here...

Sean

"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3BD585B8.46597003 deming-os.org...
 In an earlier discussion, we got rid of the break/non-break problem (sort

 by introducing a new syntax.  IMHO, the new syntax is more "C-like":

 switch(list->data)
 {
     case(BIG)
     {
         list->bigflag = true;
         continue case(SMALL);
            // continues into whichever case handles SMALL...even though it

            // that that case also handles MEDIUM
     };
     case(SMALL,MEDIUM)
     {
         init();
     };
     default
     {
         throw exception;
      };
 };

 Walter hasn't signed off on using this syntax, but I think that it really
 looks good...

Oct 25 2001
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
"Sean L. Palmer" wrote:

 It's definitely not C-like, totally unlike C's switch.  But I like it.

IMHO, C's switch is very "un-C-like." It's the only language construct that has conceptual "blocks of code" but ditches the {}. I would opine that this new syntax is MORE C-like than C. :)
 Ditch the }; though.

Old habit. Don't remember why I started doing it. :/ -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Oct 25 2001
parent reply "EvilOne" <evilone omen.ru> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3BD8AEA0.318DCD6E deming-os.org...

 IMHO, C's switch is very "un-C-like."  It's the only language construct that
has
 conceptual "blocks of code" but ditches the {}.  I would opine that this new
 syntax is MORE C-like than C.    :)

Totally agreed. I always hated that switch syntax in C. Just one thing. If we are concerned about compatibility (with C), then maybe an alternative syntax - on(...) instead of case(...) and "else" instead of "default": switch (list->data) { on (BIG) { list->bigflag = true; continue case(SMALL); // continues into whichever case handles SMALL... // even though it turns out // that that case also handles MEDIUM } on (SMALL, MEDIUM) { init(); } else { throw exception; } } This way, on() block should be equal to usual C case block enclosed in brackets and with break; at the end. Not only this allows to port existing code easily, but also to mix both versions: switch (list->data) { case BIG: list->bigflag = true; // no break so go further on (SMALL, MEDIUM) { init(); // now break } else // could be default: as well { throw exception; } }
Oct 29 2001
parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
EvilOne wrote:

 Just one thing. If we are concerned about compatibility (with C),
 then maybe an alternative syntax - on(...) instead of case(...)
 and "else" instead of "default":

That might make sense. I'm not 100% sold on it, but it's not bad...
 This way, on() block should be equal to usual C case block enclosed in
 brackets and with break; at the end. Not only this allows to port
 existing code easily, but also to mix both versions:

In theory, I agree. However, it is laden with problems. For example, in the example code you give, why does the BIG case fall through? It doesn't seem evident from the structure. If we are going to allow both types, then I think that we should either disallow mixing in a given switch() block, or create a new keyword that indicates that we are using the new syntax.
     switch (list->data)
     {
         case BIG:
             list->bigflag = true;
             // no break so go further

         on (SMALL, MEDIUM)
         {
             init();
             // now break
         }

         else    // could be default: as well
         {
             throw exception;
         }
     }

-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Oct 29 2001
parent "EvilOne" <evilone omen.ru> writes:
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message
news:3BDD698E.EDA2E4F deming-os.org...

 This way, on() block should be equal to usual C case block enclosed in
 brackets and with break; at the end. Not only this allows to port
 existing code easily, but also to mix both versions:

In theory, I agree. However, it is laden with problems. For example, in the example code you give, why does the BIG case fall through? It doesn't seem evident from the structure. If we are going to allow both types, then I think that we should either disallow mixing in a given switch() block, or create a new keyword that indicates that we are using the new syntax.

I wouldn't say that C switch makes it evident that cases fall through as well. =) In fact, I believe that "case" should be left mostly for compatibility reasons, especially since most people here agreed that it's actually rather "anti-C'ish" syntactically. If you want strict, ensured behaviour, you can always use whatever new form will be there, no?
Oct 29 2001
prev sibling next sibling parent "Walter" <walter digitalmars.com> writes:
Ben Cohen wrote in message <9limv6$14q5$1 digitaldaemon.com>...
I also think that changes from C to D should be minimised, and should be
limited to useful extensions, simplifying the language, and making the
language safer.

Yes, absolutely. I want it to feel like C and be comfortable for C programmers to use.
So, for example, your alteration to struct's namespace is
great (I would have done that) since it simplifies the language;

I proposed that to the C++ people way back in 88. I still think not fixing that was a massive mistake for C++.
I like the suggestion for treatment of switches by Mark Shackelford
("Suggestions: switch, case, also, elsif syntax").  Incidentally, can you
do a ``break label'' out of a switch?

Yes.
Yes, D (or P;) is a much more `traditional' sequel to C!  What would you
have called it?

The original name was the "Mars" language. Note the company name <g>.
Aug 18 2001
prev sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
I'd like it for if() to be subject to the same treatment as while()

i.e. make the following illegal:

if (expr)
  ;
else
  ;

the valid way would be like so:

if (expr)
{}
else
{}

The language may as well be self-consistent.

Sean

 This is already true in some cases, you can't do:

     while (...) ;

 since that is likely a typo. Instead, use:

     while (...) { }

 for an empty loop.


Oct 23 2001
parent reply "Walter" <walter digitalmars.com> writes:
Yes, you're right. -Walter

Sean L. Palmer wrote in message <9r3d54$9nc$1 digitaldaemon.com>...
I'd like it for if() to be subject to the same treatment as while()

i.e. make the following illegal:

if (expr)
  ;
else
  ;

the valid way would be like so:

if (expr)
{}
else
{}

The language may as well be self-consistent.

Sean

 This is already true in some cases, you can't do:

     while (...) ;

 since that is likely a typo. Instead, use:

     while (...) { }

 for an empty loop.



Oct 25 2001
parent reply a <a b.c> writes:
In that case, would it be OK to have a perl style 

	stmt if(exp);

syntax?  It's nice to not have to bog down code with structure were it's
not needed.  Kind of like runtime debug output (not to be confused with
compiler time debug code).

	printf("Don't make me do it! I'm warning you!\n") if(!quiet);
	do_it();
	printf("I told you I'd do it, but you didn't believe me!\n") if(debug);

To be honest, I like the perl syntax for this better anyway since it the
print that is the most important part.  In these cases that fact that
the output doesn't happen every time is kind of secondary.  The same
rarely holds for block statements. 
	Anyhow, it's just a wish if you are going to take away the simple form
of if.  I'd hate to see people abuse the short circuit behavior of ||
and && to get the same brevity of expression.

Dan

Walter wrote:
 
 Yes, you're right. -Walter
 
 Sean L. Palmer wrote in message <9r3d54$9nc$1 digitaldaemon.com>...
I'd like it for if() to be subject to the same treatment as while()

i.e. make the following illegal:

if (expr)
  ;
else
  ;

the valid way would be like so:

if (expr)
{}
else
{}

The language may as well be self-consistent.

Sean

 This is already true in some cases, you can't do:

     while (...) ;

 since that is likely a typo. Instead, use:

     while (...) { }

 for an empty loop.




Oct 25 2001
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
I wasn't suggesting disallowing the use of a statement instead of a block.
This would still be valid in D:

if (a>b)
  CallFunction();
else
  Dont();

But this wouldn't be valid if Walter accepts my suggestion:

if (a>b)
  ;
else
  CallSomething();

But this would:

if (a>b)
{}
else
  CallSomething();

Essentially my suggestion is that the null statement should not be useable
in the controlled clauses of if, while, or for statements.

I don't think I'd like perl's if syntax.  Stuff off to the right of a line
of code tends to go off the side of the window, you'd have to scroll over to
see it.  And this indentation wouldn't make much sense in a C-style world:

printf("Don't make me do it! I'm warning you!\n")
  if(!quiet);
do_it();
printf("I told you I'd do it, but you didn't believe me!\n")
  if(debug);

Sean

"a" <a b.c> wrote in message news:3BD8C0C1.A2A1BC8B b.c...
 In that case, would it be OK to have a perl style

 stmt if(exp);

 syntax?  It's nice to not have to bog down code with structure were it's
 not needed.  Kind of like runtime debug output (not to be confused with
 compiler time debug code).

 printf("Don't make me do it! I'm warning you!\n") if(!quiet);
 do_it();
 printf("I told you I'd do it, but you didn't believe me!\n") if(debug);

 To be honest, I like the perl syntax for this better anyway since it the
 print that is the most important part.  In these cases that fact that
 the output doesn't happen every time is kind of secondary.  The same
 rarely holds for block statements.
 Anyhow, it's just a wish if you are going to take away the simple form
 of if.  I'd hate to see people abuse the short circuit behavior of ||
 and && to get the same brevity of expression.

 Dan

 Walter wrote:
 Yes, you're right. -Walter

 Sean L. Palmer wrote in message <9r3d54$9nc$1 digitaldaemon.com>...
I'd like it for if() to be subject to the same treatment as while()

i.e. make the following illegal:

if (expr)
  ;
else
  ;

the valid way would be like so:

if (expr)
{}
else
{}

The language may as well be self-consistent.

Sean

 This is already true in some cases, you can't do:

     while (...) ;

 since that is likely a typo. Instead, use:

     while (...) { }

 for an empty loop.





Oct 26 2001
parent a <a b.c> writes:
"Sean L. Palmer" wrote:
 
 I wasn't suggesting disallowing the use of a statement instead of a block.
 This would still be valid in D:

 Essentially my suggestion is that the null statement should not be useable
 in the controlled clauses of if, while, or for statements.

My bad. I mis-read.
 I don't think I'd like perl's if syntax.  Stuff off to the right of a line
 of code tends to go off the side of the window, you'd have to scroll over to
 see it.  And this indentation wouldn't make much sense in a C-style world:
 
 printf("Don't make me do it! I'm warning you!\n")
   if(!quiet);
 do_it();
 printf("I told you I'd do it, but you didn't believe me!\n")
   if(debug);

Well, I'll agree that it's a departure for C folk. I think the above is clear though. I write code like that (in perl) all the time. Using if and unless this way make code fairly readable. This of course assumes you use it right. Like any construct, it can be used to obfuscate too. In any case, as long as we have the non block version of if then my case isn't worth pursuing. Dan
Oct 26 2001
prev sibling next sibling parent reply John Fletcher <J.P.Fletcher aston.ac.uk> writes:
 A couple of comments.

Walter wrote:

 "Ben Cohen" <bc skygate.co.uk> wrote in message
 news:9lgtfa$2g90$1 digitaldaemon.com...

       - Tuples are quite nice, for example to return more than one value

         a function.  It would be OK to say that the type has to be
         determinable at runtime.

Tuples are a great idea, but the D way is to use out parameters.

Tuples are available in C++ via the Lambda Library. (See http://lambda.cs.utu.fi/ but it won't run with DM unfortunately.) There is also a version from the same stable in the Boost collection. I don't see how out parameters can be made to nest in the same way as a return value.
 I've been thinking of writing a tool to convert a .h file into an import
 file. Having a C compiler, this would not be too difficult. The trouble
 comes from attempting to convert macro constants into enums. It's unlikely
 the tool would do a perfect job, it'd require some hand editting of the
 result.

Havve you looked at the work of SWIG (http://www.swig.org/) which while designed to generate an interface to C or C++ from another language, certainly can parse a reduced form of a header file. It is extensible via language modules (I haven't looked into this) so might be a way to interface code to D. John Fletcher
Aug 17 2001
parent "Walter" <walter digitalmars.com> writes:
John Fletcher wrote in message <3B7D0E76.D3EED485 aston.ac.uk>...
 I've been thinking of writing a tool to convert a .h file into an import
 file. Having a C compiler, this would not be too difficult. The trouble
 comes from attempting to convert macro constants into enums. It's


 the tool would do a perfect job, it'd require some hand editting of the
 result.


to generate an interface to C or C++ from another language, certainly can

a reduced form of a header file. It is extensible via language modules (I
haven't looked into this) so might be a way to interface code to D.

The big thing to convert is windows.h. It takes a lot of development work to successfully parse it. Since I've got that already, I just have to build something to walk the symbol table and output a D import.
Aug 18 2001
prev sibling parent reply "John Carney" <john.carney pacific.net.au> writes:
"Walter" <walter digitalmars.com> wrote in message
news:9lh4a4$2ok1$1 digitaldaemon.com...
 "Ben Cohen" <bc skygate.co.uk> wrote in message
 news:9lgtfa$2g90$1 digitaldaemon.com...

<snip>
 Experience suggests that single inheritance with interfaces will cover
 nearly all the bases. I know some people really do want MI, but my eyes
 always glaze over trying to understand it, and I think I'll just stay

A few years ago I did about 12 months worth of Java development. I didn't come across a single problem that couldn't be solved by interfaces. It's my opinion that most times when people want to use multiple inheritance, they're just plain wrong (eg., mistaking has-a relationships for is-a relationships) and the rest of the time what they *really* need is Java-style interfaces rather than MI. Regards, John Carney.
Aug 17 2001
parent Charles Hixson <charleshixsn earthlink.net> writes:
John Carney wrote:
 ...
 A few years ago I did about 12 months worth of Java development. I didn't
 come across a single problem that couldn't be solved by interfaces. It's my
 opinion that most times when people want to use multiple inheritance,
 they're just plain wrong (eg., mistaking has-a relationships for is-a
 relationships) and the rest of the time what they *really* need is
 Java-style interfaces rather than MI.
 
 Regards,
 John Carney.
 

(precompiled & I don't have source code) class supports my brand new interface. Particularlly if you could also indicate: But what it calls rutabagas() are elsewhere called turnips(), and that's how I'm referring to them. The feature that "Jamie" (a Java preprocessor) called delegation would also be useful. I would agree that these two features in combination would essentially eliminate the need for multiple inheritance. But without them simple things sometimes take an alarming amount of code, as you write by hand a large number of methods of, e.g., the form: int A(p : Parameter) { return p.A(); }
Aug 20 2001