www.digitalmars.com Home | Search | C & C++ | D | DMDScript | News Groups | index | prev | next
Archives

D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.ide
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript
electronics



digitalmars.D - why ; ?

↑ ↓ ← Tomasz Sowinski <tomeksowi gmail.com> writes:
Just another feature thought. Never gonna happen, but still...

What's the reason of having lines end with a semicolon? Anything else than a
legacy issue with C/C++?

The only thing I can think of is having multiple statements in one line, but
that only makes code unreadable. Wouldn't getting rid of ; improve readability?


Tomek
May 05 2008
Robert Fraser <fraserofthenight gmail.com> writes:
Tomasz Sowinski wrote:
 Just another feature thought. Never gonna happen, but still...
 
 What's the reason of having lines end with a semicolon? Anything else than a
legacy issue with C/C++?
 
 The only thing I can think of is having multiple statements in one line, but
that only makes code unreadable. Wouldn't getting rid of ; improve readability?
 
 
 Tomek

So the end of a statement would be marked by a newline character a la Python? I usually like to keep my lines under 80 characters long for readability, and occasionally have long statements (especially if there's a ternary operator in there somewhere), so my vote is "nay". There are various other arguments against it, too (especially in that it makes parsing easier).
May 05 2008
Tomasz Sowinski <tomeksowi gmail.com> writes:
Robert Fraser Wrote:

 So the end of a statement would be marked by a newline character a la 
 Python?

yes
 I usually like to keep my lines under 80 characters long for 
 readability, and occasionally have long statements (especially if 
 there's a ternary operator in there somewhere), so my vote is "nay".

Maybe a breakline symbol like in Ruby or VB for long statements?
 There are various other arguments against it, too (especially in that it 
 makes parsing easier).

There is a meaningful newline character anyway to know where the // comment ends, so would removing ; make a big difference in parsing? I'm not arguing. As I said, I know it's never going to happen, I was just curious about those "other various arguments".
May 05 2008
→ BCS <BCS pathlink.com> writes:
Tomasz Sowinski wrote:

 
 There is a meaningful newline character anyway to know where the // comment
ends

as a side issue, that is a lexical effect. The newline is part of the comment token so it likely never even shows up in the parser.
May 05 2008
Tom <tom nospam.com> writes:
Tomasz Sowinski escribió:
 Robert Fraser Wrote:
 
 So the end of a statement would be marked by a newline character a la 
 Python?

yes
 I usually like to keep my lines under 80 characters long for 
 readability, and occasionally have long statements (especially if 
 there's a ternary operator in there somewhere), so my vote is "nay".

Maybe a breakline symbol like in Ruby or VB for long statements?

Please no! Tom;
May 05 2008
Michael Neumann <mneumann ntecs.de> writes:
Tom wrote:
 Tomasz Sowinski escribió:
 Robert Fraser Wrote:

 So the end of a statement would be marked by a newline character a la
 Python?

yes
 I usually like to keep my lines under 80 characters long for
 readability, and occasionally have long statements (especially if
 there's a ternary operator in there somewhere), so my vote is "nay".

Maybe a breakline symbol like in Ruby or VB for long statements?

Please no!

It is very successful in Ruby! But Ruby is a very different language. Ruby allows you to separate statements with ";" in one line. And it recognises statements that cross a line boundary like shown below: a + b ==> a + b a + b ==> a; +b (probably not what you want!) One problem is clearly (as Walter said) that reporting syntax errors can become hard, or very unprecise. The latter is the case in Ruby. Regards, Michael
May 06 2008
↑ ↓ Daniel Giddings <daniel.giddings gmail.com> writes:
; also works in Python as a line separator:

print "a" ; print "b"

and it gives quite good syntax error messages

Personally I'm more in favor of the Python style code as opposed to C 
style code, because while you might need a \ line break char for some 
code, it is very much the exception to the rule - saving quite an amount 
of hassle.

:-) Dan

Michael Neumann wrote:
 Tom wrote:
  > Tomasz Sowinski escribió:
  >> Robert Fraser Wrote:
  >>
  >>> So the end of a statement would be marked by a newline character a la
  >>> Python?
  >>
  >> yes
  >>
  >>> I usually like to keep my lines under 80 characters long for
  >>> readability, and occasionally have long statements (especially if
  >>> there's a ternary operator in there somewhere), so my vote is "nay".
  >>
  >> Maybe a breakline symbol like in Ruby or VB for long statements?
  >>
  >
  > Please no!
 
 It is very successful in Ruby! But Ruby is a very different language.
 Ruby allows you to separate statements with ";" in one line. And it
 recognises statements that cross a line boundary like shown below:
 
   a +
   b
   ==> a + b
 
   a
   + b
   ==> a; +b (probably not what you want!)
 
 One problem is clearly (as Walter said) that reporting syntax errors can
 become hard, or very unprecise. The latter is the case in Ruby.
 
 Regards,
 
   Michael

May 06 2008
→ bearophile <bearophileHUGS lycos.com> writes:
Leandro Lucarella Wrote [...]

I also suggest to take a look at the well designed Scala language, I think it
has optional ; 

Bye,
bearophile
May 07 2008
→ bearophile <bearophileHUGS lycos.com> writes:
Leandro Lucarella:

An example of Scala code:

http://shootout.alioth.debian.org/gp4/benchmark.php?test=meteor&lang=scala&id=4

More examples can be found near that one...

Bye,
bearophile
May 07 2008
Gilles G. <schaouette free.fr> writes:
 Yeah, we're going round and round. If I break a line because it's too
 long, I absolutely do not want the compiler assuming that means "end
 of statement". As numerous examples have shown, it is perfectly
 possible for the compiler to misinterpret the programmers intent, and
 produce code that does completely the wrong thing.
 
 There are only two ways to avoid this problem:
 (1) require semicolons at end of statement
 (2) require line breaks which are not end-of-statement to be escaped
 
 Since I don't like (2), I must support (1).

Using Python aVeryLongFunctionName( argument1, argument2,
May 08 2008
↑ ↓ → "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Thu, 08 May 2008 13:00:22 +0100, Janice Caron <caron800 googlemail.com>  
wrote:

 Z008/5/8 Gilles G. <schaouette free.fr>:
  > As numerous examples have shown, it is perfectly
  > possible for the compiler to misinterpret the programmers intent, and
  > produce code that does completely the wrong thing.
  >
  In Python, nearly every time you need a long line, there are already  
 parentheses in the expression, so you don't need to escape the new line.

So if I mistype, and accidently fail to match parenthesis, the compiler can't detect it, and instead goes ploughing on, tying to compile through the next few statements. When it finally reaches a point where it can't parse any more, it will have no idea exactly where it got lost in the first place.

I got the T-shirt for that one when learning Python.
May 09 2008
→ "Janice Caron" <caron800 googlemail.com> writes:
Z008/5/8 Gilles G. <schaouette free.fr>:
  > As numerous examples have shown, it is perfectly
  > possible for the compiler to misinterpret the programmers intent, and
  > produce code that does completely the wrong thing.
  >
  In Python, nearly every time you need a long line, there are already
parentheses in the expression, so you don't need to escape the new line.

So if I mistype, and accidently fail to match parenthesis, the compiler can't detect it, and instead goes ploughing on, tying to compile through the next few statements. When it finally reaches a point where it can't parse any more, it will have no idea exactly where it got lost in the first place.
May 08 2008
Leandro Lucarella <llucax gmail.com> writes:
Janice Caron, el  8 de mayo a las 05:23 me escribiste:
 On 08/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
 No you don't, \n is your redundancy. So you still get meaningful messages.

That would be true IF AND ONLY IF we were forced to escape newlines that didn't mean end-of-statement. e.g. auto a = b \ (c) I wasn't aware that requiring me to escaping newlines was part of the suggestion. If it was, then I'm even more against it.

Yes, in my suggestion you need to escape false-newline-end-of-statement in some few cases, like in Python. What you written (which doesn't make any sense, I don't know what's the point of putting shitty and unreal examples to prove a point) need a escape at the end of the line, but this (more realistic) version doesn't: auto a = b( c) Because when you don't expect a statement to finish until the closing ) is found (which is *exactly* the same behavior you get now, so please don't bring the "meaningful errors" argument again =). I have a Python project with 6482 LOC and I have just 39 lines with line continuation. I think adding an extra character (\) to 0.6% of the lines is pretty acceptable if you get rid of the extra character (;) at the end of the line in the other 99.4% =) Really. You are telling me that is ugly to have a '\' in 0.6% lines of code but is pretty to have ';' in 100% of them??? It doesn't makes any sense to me...
 Besides which, how would that work with statements like
 
     if (a == b) { ++i; ++j } else { --i; --j }
 
 If newlines were to take over the role of semicolons, then that would turn into
 
     if (a == b) { ++i
     ++j } else { --i
     --j }
 
 Yuk.

Is *that* hard to read the entire message? I said ';' is OPTIONAL (and that's the key for backward compatibility). So you can perfectly write: if (a == b) { ++i; ++j } else { --i; --j } "Yuk." -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Dentro de 30 años Argentina va a ser un gran supermercado con 15 changuitos, porque esa va a ser la cantidad de gente que va a poder comprar algo. -- Sidharta Wiki
May 08 2008
→ "Nick Sabalausky" <a a.a> writes:
 Really. You are telling me that is ugly to have a '\' in 0.6% lines of 
 code
 but is pretty to have ';' in 100% of them??? It doesn't makes any sense to
 me...

I think we're starting to get more into an issue of preferences here, but: Aside from the fact that ";" is only used on statements that don't end in a "{}" code block, I would have to say: yes, definitely. Personally, I find the rule "A statement is ended by either a semicolon or a curly-brace code block (where applicable)" to be cleaner and more consistent than "Statements end with a newline unless a "\" is used or the compiler is able to infer the statement shouldn't end", plus it allows me to rearrange portions of a long statement for readability without messing with adding/removing/moving "\" operators. Of course, in some cases, I can omit the "\", but that means I have to worry about "Do I need it here, or not?". Which first of all violates "don't make me think", and secondly leads to: FormatString("This ({}) is a number, and this is a very," \ "very, very long string. Yes it is, yes it is.", thisIsA + (rather() * longComputation) + orAtLeast \ IAmTrying(toMakeItSo) - (yesIam * 2)) The use of multiple lines in that is very ugly. Of course, this can be solved by either trying to arrange parentheses in a way that side-steps the need for "\" (ie, very kludgey), or by saying "screw it, I'm using '\' on all the lines" (ie, effectively eliminating the "don't need it on parameter lists" feature), or by doing "FormatString(preComputedStr, preComputedValue)" (but why should I have to?) Also, I've seen a lot of ECMAScript code that has semicolons on some lines and lacks it on others, just on the whim of the coder - that strikes me as very messy. Consistency is pretty. Regarding remembering the semicolon, I haven't found that to be a problem. I find I do it naturally without even thinking about it, at least whenever I haven't been spending a lot of time in a language like VB which outright forbids semicolons. But even then, the compiler will tell me exactly where I went wrong until I can get the VB out of my head, so no big deal.
May 08 2008
Leandro Lucarella <llucax gmail.com> writes:
Janice Caron, el  8 de mayo a las 15:51 me escribiste:
 2008/5/8 Leandro Lucarella <llucax gmail.com>:
 I don't know what's the
  point of putting shitty and unreal examples to prove a point

You won't win any arguments by calling examples "shitty". All that will achieve is that people who don't want to be insulted will stop debating with you, and D won't change.

Great excuse to not answer a mail with a lot of good points... Very convenient. Ok, you are right about "shitty", my apologies for using an unappropriate word. Please remove " shitty and" in my previous mail and tell me what flaws you find in my proposal? Thank you. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- EL PRIMER MONITO DEL MILENIO... -- Crónica TV
May 08 2008
↑ ↓ → Leandro Lucarella <llucax gmail.com> writes:
Janice Caron, el  9 de mayo a las 05:42 me escribiste:
 I'm not sure there's anything further to say, however. The reason is,
 when you said "Yes, in my suggestion you need to escape
 false-newline-end-of-statement", you effectively closed all
 ambiguities. My arguments were predicated on the assumption that there
 would be no newline-escaping. That means, your plan /is/ workable -
 but the price (having to escape newlines) is higher than I want to
 pay. It becomes a matter of taste. I prefer C-style; you prefer
 Python-style. Maybe you (or someone else who wants this) can write
 that conversion tool I mentioned somewhere.

I don't think it's entirely a matter of taste. It saves typing and thus makes the code more readable and easier to maintain. Is like saying "auto" it's just a matter of taste, and you say "auto" is bad because we should always have the redundancy of the type declaration.
 But even with the "you need to escape escape
 false-newline-end-of-statement" rule, there is still room for silent
 bugs to creep in. For example:
 
     foo(int x)  // Danger!
     {
         /* stuff */
     }

Is this valid D?
 Under your scheme that would have to be rewritten as either
 
     foo(int x)  {
         /* stuff */
     }
 
 or
 
     foo(int x)  \
     {
         /* stuff */
     }
 
 or else run the risk of being misparsed as
 
     foo(int x);
     {
         /* stuff */
     }
 
 which often times will be valid D. (Not always, but sometimes - e.g.
 as an inner function). So unless you go "all the way" and aim for full
 Python style, you run the risk of introducing some very hard to find
 bugs.

I don't think that's valid D anyway, but I'll assume you meant: void foo(int x) { /* stuff */ } If this is the case, the parser should expect a function definition after a function declaration (since function declaration are not *that* usual in D, I think is the better way to go). So, for a function declaration and a new block of code you write: void foo(int x); // ; is mandatory for function declaration { // new block } For function definition, you just type: void foo(int x) { /* stuff */ } BTW, I know this will never make it into D, I just don't think you have the right reasons. I think the only valid reason to not do it (and a very big one) is that D wants to be in the C-like syntax family, so it *wants* to look like C. The ambiguities, redundancy and supposed hidden bugs are all very weak reasons IMHO... -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- EL PRIMER MONITO DEL MILENIO... -- Crónica TV
May 12 2008
Michael Neumann <mneumann ntecs.de> writes:
Janice Caron wrote:
 2008/5/8 Nick Sabalausky <a a.a>:
  Not that I'm advocating any "non-compulsory semicolon" syntax, but 


  the first one work fine by saying "Newline and semicolon are BOTH
  interpreted as end-of-statement"? (aside from the issue of "with or 


  a continue-on-next-line symbol"). Or am I just taking the discusion 


  circle?

Yeah, we're going round and round. If I break a line because it's too long, I absolutely do not want the compiler assuming that means "end of statement". As numerous examples have shown, it is perfectly possible for the compiler to misinterpret the programmers intent, and produce code that does completely the wrong thing. There are only two ways to avoid this problem: (1) require semicolons at end of statement (2) require line breaks which are not end-of-statement to be escaped

(3) "Intelligent Parser" a + b Here the parser knows that something has to follow. f(1, 2, 3, 4, 5, 6) Here again the parser knows that something has to follow. Etc. It works perfectly well in Ruby, and I've never found a bug according to a wrongly placed newline during the last ~10 years writing some multiple 10k LoC in Ruby, while I often get nerved by the C/C++ compiler due to missing semicolons. Actually, IMHO any C-style syntax has much more sever problems leading to hard to find bugs: if (a) s1; s2; vs. if (a) { s1; s2; } vs. in Ruby (Eiffel/Ada/Modula-style syntax) if a s1 s2 end Another example which leads to hard to read code and potential bugs is (ignoring compiler warnings): class A { int i; // // add some 25 lines of code here // void foo(int i) { // what is "i" here? } } This is solved in Ruby by using a separate namespace for instance variables (" i" for instance variable "i", and "i" for local variable "i"). I regard this as one of the most important features found in Ruby to prevent such issues and increase readability (and no, " " has nothing to do with the " " used by Perl :). I wouldn't suggest to remove semicolons from D, as the syntax it uses makes it somewhat harder than the syntax used by Ruby (Python etc.). But I'd suggest to introduce variable as a synonym to this.variable. Regards, Michael
May 08 2008
"Nick Sabalausky" <a a.a> writes:
"Michael Neumann" <mneumann ntecs.de> wrote in message 
news:48231B20.1080009 ntecs.de...
 Actually, IMHO any C-style syntax has much more sever problems leading
 to hard to find bugs:

     if (a)
       s1;
     s2;

I can't say I've ever found that to be a problem. But maybe that's just me.
May 08 2008
terranium <spam here.lot> writes:
Nick Sabalausky Wrote:

 to hard to find bugs:

     if (a)
       s1;
     s2;

I can't say I've ever found that to be a problem. But maybe that's just me.

Programmer, who got used to one language finds it difficult to switch to another language, because different languages require different styles of thinking. Thus for C programmer it's difficult to understand block statement without braces :) and for basic programmer it's difficult to delimit block statement with braces.
May 08 2008
→ Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Janice Caron wrote:
 Programmer, who got used to one language finds it difficult to switch to
another language, because different languages require different styles of
thinking. Thus for C programmer it's difficult to understand block statement
without braces :) and for basic programmer it's difficult to delimit block
statement with braces.

Ah yes - that's probably true. I wonder if it's possible to write a standalone tool that doesn't know or care about language grammar (except maybe some general rules about what constitutes a quote or a comment), that can freely convert between Lorem ipsum (dolor sit amet) { consectetur!(adipisicing)(elit, sed); do { eiusmod tempor incididunt; ut labore; et dolore; } magna(aliqua); } and Lorem ipsum (dolor sit amet): consectetur!(adipisicing)(elit, sed) do: eiusmod tempor incididunt ut labore et dolore magna aliqua If so, we can have not only D-in-Python-style (which I'd never use), but also Python-in-D-style (which I actually might). It sounds like it ought to be feasible.

I have translated the passages above from Cicero's Latin and it says: "It is a pleasure to read everybody's views about language coding conventions but it is painful to realize that some people believe that they know the one perfect way of using syntax and indentation." That 'do' in there was causing a problem, since I could not find the Latin equivalent, but I took it as Cicero's singing the beginning of "do re mi..." in his Roman bath while he was composing his learned treatises on computer language morality.
May 08 2008
"Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Thu, 08 May 2008 18:20:15 +0100, Janice Caron <caron800 googlemail.com>  
wrote:

 Programmer, who got used to one language finds it difficult to switch  
 to another language, because different languages require different  
 styles of thinking. Thus for C programmer it's difficult to understand  
 block statement without braces :) and for basic programmer it's  
 difficult to delimit block statement with braces.

Ah yes - that's probably true. I wonder if it's possible to write a standalone tool that doesn't know or care about language grammar (except maybe some general rules about what constitutes a quote or a comment), that can freely convert between Lorem ipsum (dolor sit amet) { consectetur!(adipisicing)(elit, sed); do { eiusmod tempor incididunt; ut labore; et dolore; } magna(aliqua); } and Lorem ipsum (dolor sit amet): consectetur!(adipisicing)(elit, sed) do: eiusmod tempor incididunt ut labore et dolore magna aliqua If so, we can have not only D-in-Python-style (which I'd never use), but also Python-in-D-style (which I actually might). It sounds like it ought to be feasible.

That's actually quite a clever way to enter a code obfuscation contest. My grasp of latin is just sufficient to want to make me try to interpret what your saying (and fail because I dropped Latin in favour of Chemistry) and ignore your code.
May 09 2008
↑ ↓ → user domain.invalid writes:
Bruce Adams wrote:
     Lorem ipsum (dolor sit amet):
         consectetur!(adipisicing)(elit, sed)
         do:
             eiusmod tempor incididunt
             ut labore
             et dolore
         magna aliqua

is just sufficient to want to make me try to interpret what your saying

Check out http://www.lipsum.com/ for an explanation. HTH Dennis Cote
May 14 2008
Michael Neumann <mneumann ntecs.de> writes:
Nick Sabalausky wrote:
 "Michael Neumann" <mneumann ntecs.de> wrote in message
 news:48231B20.1080009 ntecs.de...
 Actually, IMHO any C-style syntax has much more sever problems leading
 to hard to find bugs:

     if (a)
       s1;
     s2;

I can't say I've ever found that to be a problem. But maybe that's

Me neither. But it's annoying to have at least 3 different style guidelines for C-style syntaxes. if (a) b; if (a) b; if (a) { b; } if (a) { b; } if (a) { b; } if (a) { b; } And so on :). Compare that with how many choices you have when using "if ... end"! Regards, Michael
May 08 2008
→ "Nick Sabalausky" <a a.a> writes:
"Michael Neumann" <mneumann ntecs.de> wrote in message 
news:fvvd7r$882$1 digitalmars.com...
 Me neither. But it's annoying to have at least 3 different style 
 guidelines for C-style syntaxes.

   if (a) b;

   if (a)
     b;

   if (a) {
     b;
   }

   if (a)
   {
     b;
   }

 And so on :).

 Compare that with how many choices you have when using "if ... end"!

That's a very good point, I hadn't really thought about that (Personaly, I would want to keep the first two and just merge the rest of them into an "if...end"). Although that is more of a "{}" vs. "end" issue, and not directly related to "with or without semicolon".
May 08 2008
"Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Thu, 08 May 2008 18:28:23 +0100, Michael Neumann <mneumann ntecs.de>  
wrote:

 Nick Sabalausky wrote:
  > "Michael Neumann" <mneumann ntecs.de> wrote in message
  > news:48231B20.1080009 ntecs.de...
  >> Actually, IMHO any C-style syntax has much more sever problems  
 leading
  >> to hard to find bugs:
  >>
  >>     if (a)
  >>       s1;
  >>     s2;
  >>
  >
  > I can't say I've ever found that to be a problem. But maybe that's  
 just me.

 Me neither. But it's annoying to have at least 3 different style  
 guidelines for C-style syntaxes.

    if (a) b;

    if (a)
      b;

    if (a) {
      b;
    }

    if (a)
    {
      b;
    }

    if (a)
      {
      b;
      }

    if (a)
      {
        b;
      }

 And so on :).

 Compare that with how many choices you have when using "if ... end"!

 Regards,

    Michael

I thought D had dropped single statement if's for this very reason. I must be mistaken. Many a (C) coding style guide strongly encourages embracing even single statements in constructs like this. You can go further with the idea. After all you can casuse ambiguity between e.g nested loops as well. if (a) { while(b) {c} } versus if (a) while(b) c wend fi or whatever. You can mess around with this stuff forever without increasing programmer productivity signficantly. The real gains are when you hit on improvements to semantic expressiveness. I'd much rather have the next foreach than waste time worrying about } versus fi, endif etc. Regards, Bruce.
May 09 2008
↑ ↓ Michael Neumann <mneumann ntecs.de> writes:
Bruce Adams wrote:
 I thought D had dropped single statement if's for this very reason. I
 must be mistaken. Many a (C) coding
 style guide strongly encourages embracing even single statements in
 constructs like this.

 You can go further with the idea. After all you can casuse ambiguity
 between e.g nested loops as well.

 if (a) {
   while(b) {c}
 }

 versus

 if (a)
    while(b)
       c
    wend
 fi

 or whatever.
 You can mess around with this stuff forever without increasing
 programmer productivity signficantly.

It's not about programm productivity, but about redundancy :) But then there is still Ada for those that need that redundancy to prevent bugs. Or just don't write too deeply nested code ;-) Regards, Michael
May 10 2008
↑ ↓ → "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Sat, 10 May 2008 11:58:41 +0100, Michael Neumann <mneumann ntecs.de>  
wrote:

 Bruce Adams wrote:
  > I thought D had dropped single statement if's for this very reason. I
  > must be mistaken. Many a (C) coding
  > style guide strongly encourages embracing even single statements in
  > constructs like this.
  >
  > You can go further with the idea. After all you can casuse ambiguity
  > between e.g nested loops as well.
  >
  > if (a) {
  >   while(b) {c}
  > }
  >
  > versus
  >
  > if (a)
  >    while(b)
  >       c
  >    wend
  > fi
  >
  > or whatever.
  > You can mess around with this stuff forever without increasing
  > programmer productivity signficantly.

 It's not about programm productivity, but about redundancy :)

 But then there is still Ada for those that need that redundancy to
 prevent bugs. Or just don't write too deeply nested code ;-)

 Regards,

    Michael

Reducing bugs from syntax errors is one of several ways to improve programmer productivity. Its much less important than good semantics though.
May 10 2008
terranium <spam here.lot> writes:
Michael Neumann Wrote:

 Another example which leads to hard to read code and potential
 bugs is (ignoring compiler warnings):
 
      class A
      {
        int i;
 
        //
        // add some 25 lines of code here
        //
 
        void foo(int i)
        {
          // what is "i" here?
        }
      }
 
 This is solved in Ruby by using a separate namespace for instance
 variables (" i" for instance variable "i", and "i" for local variable
 "i").

In C family languages this is ruled out by naming convention.
May 08 2008
↑ ↓ Michael Neumann <mneumann ntecs.de> writes:
terranium wrote:
 Michael Neumann Wrote:

 Another example which leads to hard to read code and potential
 bugs is (ignoring compiler warnings):

      class A
      {
        int i;

        //
        // add some 25 lines of code here
        //

        void foo(int i)
        {
          // what is "i" here?
        }
      }

 This is solved in Ruby by using a separate namespace for instance
 variables (" i" for instance variable "i", and "i" for local variable
 "i").

In C family languages this is ruled out by naming convention.

Which in the case of using a m_ prefix leads to hard(er) to read code. And then there is no standard naming convention, and who actually uses such a naming convention? Without that, you can't easily distinguish a local variable from an instance variable from a global variable. Regards, Michael
May 08 2008
"Nick Sabalausky" <a a.a> writes:
"Michael Neumann" <mneumann ntecs.de> wrote in message 
news:fvvd1a$7p3$1 digitalmars.com...
 terranium wrote:
 Michael Neumann Wrote:

 Another example which leads to hard to read code and potential
 bugs is (ignoring compiler warnings):

      class A
      {
        int i;

        //
        // add some 25 lines of code here
        //

        void foo(int i)
        {
          // what is "i" here?
        }
      }

 This is solved in Ruby by using a separate namespace for instance
 variables (" i" for instance variable "i", and "i" for local variable
 "i").

In C family languages this is ruled out by naming convention.

Which in the case of using a m_ prefix leads to hard(er) to read code. And then there is no standard naming convention, and who actually uses such a naming convention? Without that, you can't easily distinguish a local variable from an instance variable from a global variable.

In "good" C family languages, the instance variable is referred to by prefixing it with something like "this.". I think there are some that do it differently (ECMAScript, IIRC), but I'd argue those ones are making a big mistake. However, that does bring up an inconsistancy inherent to the C-style. Following your example, if I do this: class A{ int i; void foo(int i) {} void foo() {} void bar() {} } In that case, "i" means one thing if you're in "foo(int)", and another thing if you're in "foo()" or "bar()". Of course, you could decide to *always* use "this." when referring to an instance variable, but that's kinda long, and you still end up with a hidden bug if you decide to use a local var named "i" and forget to declare it. There are things about Ruby I don't like, but the instanceVar syntax is one of the things I think it got spot-on. I would be totally in favor of adopting that.
May 08 2008
Michael Neumann <mneumann ntecs.de> writes:
Nick Sabalausky wrote:
 "Michael Neumann" <mneumann ntecs.de> wrote in message
 news:fvvd1a$7p3$1 digitalmars.com...
 terranium wrote:
 Michael Neumann Wrote:

 Another example which leads to hard to read code and potential
 bugs is (ignoring compiler warnings):

      class A
      {
        int i;

        //
        // add some 25 lines of code here
        //

        void foo(int i)
        {
          // what is "i" here?
        }
      }

 This is solved in Ruby by using a separate namespace for instance
 variables (" i" for instance variable "i", and "i" for local variable
 "i").


And then there is no standard naming convention, and who actually uses such a naming convention? Without that, you can't easily distinguish a local variable from an instance variable from a global variable.

In "good" C family languages, the instance variable is referred to by prefixing it with something like "this.". I think there are some that

 differently (ECMAScript, IIRC), but I'd argue those ones are making a 

 mistake.

 However, that does bring up an inconsistancy inherent to the C-style.
 Following your example, if I do this:

 class A{
 int i;
 void foo(int i) {}
 void foo() {}
 void bar() {}
 }

 In that case, "i" means one thing if you're in "foo(int)", and 

 if you're in "foo()" or "bar()". Of course, you could decide to 

 "this." when referring to an instance variable, but that's kinda 

 you still end up with a hidden bug if you decide to use a local var 

 "i" and forget to declare it.

Yeah, you are right. It is inconsitent to define the instance variable with "i" while accessing it with " i": class A { int i; void foo(int i) { i = i; } }; But, then it's no less inconsistent than using "this.i".
 There are things about Ruby I don't like, but the  instanceVar syntax 

 of the things I think it got spot-on. I would be totally in favor of
 adopting that.

Btw, I wrote a C++ preprocessor script that during compilation transparently replaces every occurence of " " by "this->". Would be nice to have this build into D directly. Regards, Michael
May 08 2008
"Nick Sabalausky" <a a.a> writes:
"Michael Neumann" <mneumann ntecs.de> wrote in message 
news:48236605.9050806 ntecs.de...
 Yeah, you are right. It is inconsitent to define the instance variable
 with "i" while accessing it with " i":

   class A {
     int i;

     void foo(int i) {  i = i; }
   };

That's not really what I meant (See below for clarification of what I meant). Actually, I hadn't even thought of that, but it is a good point.
 Btw, I wrote a C++ preprocessor script that during compilation
 transparently replaces every occurence of " " by "this->".
 Would be nice to have this build into D directly.

I agree, that would be nice (provided, of course, it didn't interfere with deliberate uses of " ", such as within a string). Unfortunately, in C++ or D it still wouldn't solve the problem of accidentially clobbering the instance variable "i" by intending trying to use a local var "i", but forgetting to declare it: // Note: untested class A { int i=0; void foo() { // Accidentially clobbers "this.i" aka " i" for(i=0; i<77; i++) {/* Do stuff */} } invariant() { assert(this.i==0); // Fails after foo() is called } } I still like the thing, though.
May 08 2008
↑ ↓ Michael Neumann <mneumann ntecs.de> writes:
Nick Sabalausky wrote:
 // Note: untested
 class A {
   int i=0;

   void foo() {
     // Accidentially clobbers "this.i" aka " i"
     for(i=0; i<77; i++)
       {/* Do stuff */}
   }

   invariant() {
     assert(this.i==0); // Fails after foo() is called
   }
 }

 I still like the   thing, though.

Very good example! A solution could be to force the programmer to use the "this." notation or at least issuing a compiler warning if not done. The latter could be implemented in the compiler without any changes to the syntax/language. The next step would be to have " " as a synonym for "this.", as typing "this." all the time is either annoying and as such is ignored or leads to less readable code (IMHO). Regards, Michael
May 09 2008
↑ ↓ "Nick Sabalausky" <a a.a> writes:
"Michael Neumann" <mneumann ntecs.de> wrote in message 
news:g01mtk$1nvj$1 digitalmars.com...
 Nick Sabalausky wrote:
 // Note: untested
 class A {
   int i=0;

   void foo() {
     // Accidentially clobbers "this.i" aka " i"
     for(i=0; i<77; i++)
       {/* Do stuff */}
   }

   invariant() {
     assert(this.i==0); // Fails after foo() is called
   }
 }

 I still like the   thing, though.

Very good example! A solution could be to force the programmer to use the "this." notation or at least issuing a compiler warning if not done. The latter could be implemented in the compiler without any changes to the syntax/language.

I had been thinking of this feature as a pipe dream (at least for D), just because it would mean changing the language to always require "this." or " ". Implimenting it as an optional warning hadn't occurred to me. That makes it sound much more possible. Good call on that (no pun intended).
 The next step would be to have " " as a synonym for "this.", as typing
 "this." all the time is either annoying and as such is ignored or leads
 to less readable code (IMHO).

Agreed. I would love to see this actually happen. Although, I do wonder if maybe we're chasing too rare of a problem to bother, or maybe it would segregate the D scene into " D" people and "raw D" people (I hope not, 'cause I do like it). Any comments from Walter? I'm curious what his take is on the original problem.
May 09 2008
↑ ↓ → "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Fri, 09 May 2008 21:20:30 +0100, Nick Sabalausky <a a.a> wrote:

 "Michael Neumann" <mneumann ntecs.de> wrote in message
 news:g01mtk$1nvj$1 digitalmars.com...
 Nick Sabalausky wrote:
 // Note: untested
 class A {
   int i=3D0;

   void foo() {
     // Accidentially clobbers "this.i" aka " i"
     for(i=3D0; i<77; i++)
       {/* Do stuff */}
   }

   invariant() {
     assert(this.i=3D=3D0); // Fails after foo() is called
   }
 }

 I still like the   thing, though.

Very good example! A solution could be to force the programmer to use the "this." notati=


 or at least issuing a compiler warning if not done.  The latter could=


 implemented in the compiler without any changes to the syntax/languag=




er = an error or it isn't. I tend to disagree but on the otherhand I always code with -Werror and = frown at any warnings emitted by anything so I guess deep down I really agree with him.
May 09 2008
→ "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Thu, 08 May 2008 21:43:49 +0100, Michael Neumann <mneumann ntecs.de> =
 =

wrote:

 Yeah, you are right. It is inconsitent to define the instance variable=

 with "i" while accessing it with " i":

    class A {
      int i;

      void foo(int i) {  i =3D i; }
    };

 But, then it's no less inconsistent than using "this.i".

= value from a variable? ;-> <cue evil laughter />
May 09 2008
→ "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Thu, 08 May 2008 19:19:23 +0100, Nick Sabalausky <a a.a> wrote:

 "Michael Neumann" <mneumann ntecs.de> wrote in message
 news:fvvd1a$7p3$1 digitalmars.com...
 terranium wrote:
 Michael Neumann Wrote:

 Another example which leads to hard to read code and potential
 bugs is (ignoring compiler warnings):

      class A
      {
        int i;

        //
        // add some 25 lines of code here
        //

        void foo(int i)
        {
          // what is "i" here?
        }
      }

 This is solved in Ruby by using a separate namespace for instance
 variables (" i" for instance variable "i", and "i" for local variable
 "i").

In C family languages this is ruled out by naming convention.

Which in the case of using a m_ prefix leads to hard(er) to read code. And then there is no standard naming convention, and who actually uses such a naming convention? Without that, you can't easily distinguish a local variable from an instance variable from a global variable.

In "good" C family languages, the instance variable is referred to by prefixing it with something like "this.". I think there are some that do it differently (ECMAScript, IIRC), but I'd argue those ones are making a big mistake.

type/context of a variable because of tool-tips and syntax highlighting. Its just us old-timers stuck in a world of ASCII editing.
May 09 2008
terranium <spam here.lot> writes:
Michael Neumann Wrote:

 In C family languages this is ruled out by naming convention.

Which in the case of using a m_ prefix leads to hard(er) to read code.

Yes, Hungarian prefixes are considered a bad practice in modern C family languages. It was good in old times.
 And then there is no standard naming convention

As to java and .net standard naming convention is provided by standard library.
 and who actually uses such a naming convention?

Those, who care about good programming pactices.
 Without that, you can't easily distinguish a
 local variable from an instance variable from a global variable.

Who is keeping you from using a naming convention?
May 08 2008
↑ ↓ terranium <spam here.lot> writes:
terranium Wrote:

 As to java and .net standard naming convention is provided by standard library.
 

They say, ruby's code is very good... hmm... maybe, but I've seen its C sources too... :) they're not just bad, they're chaotic evil :)))
May 09 2008
↑ ↓ Michael Neumann <mneumann ntecs.de> writes:
terranium wrote:
 terranium Wrote:

 As to java and .net standard naming convention is provided by 



They say, ruby's code is very good... hmm... maybe, but I've seen its

After working a while with the C sources of Ruby they'll become less evil, even so they might be evil :). But hey, it's C! Just wondering if the sources of the .NET of Java compiler/runtimes are any better. For sure they are 10x as much code ;-) And then, there is a lot of bad ruby code out there as well! But if you have the choice between 500 lines of bad java code and 50 lines bad ruby code, I'd just take the 50 lines bad ruby code and rewrite it myself ;-) Regards, Michael
May 09 2008
terranium <spam here.lot> writes:
Michael Neumann Wrote:

 But hey, it's C!

It's not an excuse for writing junk. The excuse is this was written by one man.
May 09 2008
↑ ↓ "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Fri, 09 May 2008 15:45:47 +0100, terranium <spam here.lot> wrote:

 Michael Neumann Wrote:

 But hey, it's C!

It's not an excuse for writing junk. The excuse is this was written by one man.

That's no excuse either. Code for yourself as you would for others, if not better.
May 09 2008
↑ ↓ → Michael Neumann <mneumann ntecs.de> writes:
Bruce Adams wrote:
 On Fri, 09 May 2008 15:45:47 +0100, terranium <spam here.lot> wrote:

 Michael Neumann Wrote:

 But hey, it's C!

It's not an excuse for writing junk. The excuse is this was written by one man.

That's no excuse either. Code for yourself as you would for others, if not better.

Okay, it's not junk, definitvely not. It's just that some parts like eval.c are not commented at all and for a newbie very hard to understand. Another reason might be, because it origins from Japan, so we wouldn't be able to read the comments anyway :). To clarify: I'd actually call Ruby one of the best commented projects I've ever seen, with the highest code/comment ratio. But only for the parts that the programmer uses, not the very low-level implementation. See this as just one example: http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/object.c?revision=15758&view=markup Btw, I'd like to see this style of documentation in languages like Java. Java has a lot of documentation, but actually very little (if any) examples in the documentation, so you have to figure out yourself how to use it, which costs a lot of time. "An example is worth a 1000 words." Regards, Michael
May 10 2008
→ bearophile <bearophileHUGS lycos.com> writes:
Michael Neumann:

 After working a while with the C sources of Ruby they'll become less
 evil, even so they might be evil :). But hey, it's C!
 Just wondering if the sources of the .NET of Java compiler/runtimes are
 any better. For sure they are 10x as much code ;-)

Perl source code looks messy to me, but C too can be written in a good and readable way, you may take a look at Python C sources, for example the deque module, written by a photographer (the good R. Hettinger): http://svn.python.org/view/python/trunk/Modules/_collectionsmodule.c?rev=60749&view=markup Bye, bearophile
May 09 2008
→ "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Thu, 08 May 2008 18:24:54 +0100, Michael Neumann <mneumann ntecs.de>  
wrote:

 terranium wrote:
  > Michael Neumann Wrote:
  >
  >> Another example which leads to hard to read code and potential
  >> bugs is (ignoring compiler warnings):
  >>
  >>      class A
  >>      {
  >>        int i;
  >>
  >>        //
  >>        // add some 25 lines of code here
  >>        //
  >>
  >>        void foo(int i)
  >>        {
  >>          // what is "i" here?
  >>        }
  >>      }
  >>
  >> This is solved in Ruby by using a separate namespace for instance
  >> variables (" i" for instance variable "i", and "i" for local variable
  >> "i").
  >
  > In C family languages this is ruled out by naming convention.

being shadowed. gcc is good like that.
May 09 2008
→ "Janice Caron" <caron800 googlemail.com> writes:
On 08/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
  Please remove " shitty and" in my previous mail and tell me what
  flaws you find in my proposal?

Sure, but I think it's kinda obvious. In answer to your question: "What's the point of putting unreal examples to prove a point?", the reason is /to prove a point/. The onus is on you to prove that no examples are ambiguous. I only have to provide a single counterexample. That, I have done, as have many other people. Whether or not an example is "real" or "unreal" is in the eye of the beholder, but certainly I simplified my examples so as to demonstrate /only/ the point being made. Superflous information just sidetracks the issue. I'm not sure there's anything further to say, however. The reason is, when you said "Yes, in my suggestion you need to escape false-newline-end-of-statement", you effectively closed all ambiguities. My arguments were predicated on the assumption that there would be no newline-escaping. That means, your plan /is/ workable - but the price (having to escape newlines) is higher than I want to pay. It becomes a matter of taste. I prefer C-style; you prefer Python-style. Maybe you (or someone else who wants this) can write that conversion tool I mentioned somewhere. But even with the "you need to escape escape false-newline-end-of-statement" rule, there is still room for silent bugs to creep in. For example: foo(int x) // Danger! { /* stuff */ } Under your scheme that would have to be rewritten as either foo(int x) { /* stuff */ } or foo(int x) \ { /* stuff */ } or else run the risk of being misparsed as foo(int x); { /* stuff */ } which often times will be valid D. (Not always, but sometimes - e.g. as an inner function). So unless you go "all the way" and aim for full Python style, you run the risk of introducing some very hard to find bugs.
May 08 2008
→ "Janice Caron" <caron800 googlemail.com> writes:
On 12/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
  >     foo(int x)  // Danger!
  >     {
  >         /* stuff */
  >     }

  Is this valid D?

I missed out the word "void". I meant void foo(int x) // Danger! { /* stuff */ } or else run the risk of being misparsed as void foo(int x); { /* stuff */ } And, yes, I'm sure you can invent some arbitrary ad hoc rule which disambiguates in this case, but there are always going to be more cases. I'm not the only one to have demonstrated an ambiguity which would result from semicolons being optional. Doubtless there are many more ambiguities lying in wait. But I don't want to get into an endless cycle of "Here's another ambiguity" followed by "Here's the next ad hoc rule to disambiguate". Let's just not go there.
May 12 2008
→ "Janice Caron" <caron800 googlemail.com> writes:
2008/5/8 Nick Sabalausky <a a.a>:
  Not that I'm advocating any "non-compulsory semicolon" syntax, but couldn't
  the first one work fine by saying "Newline and semicolon are BOTH
  interpreted as end-of-statement"? (aside from the issue of "with or without
  a continue-on-next-line symbol"). Or am I just taking the discusion in a
  circle?

Yeah, we're going round and round. If I break a line because it's too long, I absolutely do not want the compiler assuming that means "end of statement". As numerous examples have shown, it is perfectly possible for the compiler to misinterpret the programmers intent, and produce code that does completely the wrong thing. There are only two ways to avoid this problem: (1) require semicolons at end of statement (2) require line breaks which are not end-of-statement to be escaped Since I don't like (2), I must support (1).
May 08 2008
→ "Janice Caron" <caron800 googlemail.com> writes:
2008/5/8 Leandro Lucarella <llucax gmail.com>:
 I don't know what's the
  point of putting shitty and unreal examples to prove a point

You won't win any arguments by calling examples "shitty". All that will achieve is that people who don't want to be insulted will stop debating with you, and D won't change.
May 08 2008
→ Jesse Phillips <jessekphillips gmail.com> writes:
On Thu, 08 May 2008 15:51:27 +0100, Janice Caron wrote:

 2008/5/8 Leandro Lucarella <llucax gmail.com>:
 I don't know what's the
  point of putting shitty and unreal examples to prove a point

You won't win any arguments by calling examples "shitty". All that will achieve is that people who don't want to be insulted will stop debating with you, and D won't change.

I should point out that your argument was a little flawed, the suggestion is to use new lines to mark the end of statement not replace ; In my thoughts I will just say I don't want the compiler to define rules based on white-space.
May 08 2008
→ "Nick Sabalausky" <a a.a> writes:
"Tomasz Sowinski" <tomeksowi gmail.com> wrote in message 
news:fvmgn8$s5d$1 digitalmars.com...
 Robert Fraser Wrote:
 I usually like to keep my lines under 80 characters long for
 readability, and occasionally have long statements (especially if
 there's a ternary operator in there somewhere), so my vote is "nay".

Maybe a breakline symbol like in Ruby or VB for long statements?

I can fully appreciate the reasoning behind "optional semicolon" syntax. Ie, there's a one-to-one relationship between "line" and "statement" for most lines and statements, therefore if an extra symbol is going to be used it should be for the border case (multi-line statement) rather than the typical case (single-line statement). But, in my experience, I find that there's another practicality-related issue that ends up trumping that one: I'm constantly readjusting statements back and forth between "all on one line" and "spanned over multiple lines" (for instance, "if" statements with lots of clauses, and functions calls/definitions with lots of arguments). Every time something changes, I rearrange to make it more readable, which often involves moving parts of a multi-line statement from one line to another, or changing a statement back and forth between single-line and multi-line. End-of-line symbols don't prevent me from doing that, but they do get in the way and make it a regular pain-in-the-ass. End of statement symbols, however, are very easy to get accustomed to, quickly become second nature, and never really get in the way.
May 06 2008
→ terranium <spam here.lot> writes:
Tomasz Sowinski Wrote:

 I was just curious about those "other various arguments".

May 07 2008
downs <default_357-line yahoo.de> writes:
Robert Fraser wrote:
 Tomasz Sowinski wrote:
 Just another feature thought. Never gonna happen, but still...

 What's the reason of having lines end with a semicolon? Anything else
 than a legacy issue with C/C++?

 The only thing I can think of is having multiple statements in one
 line, but that only makes code unreadable. Wouldn't getting rid of ;
 improve readability?


 Tomek

So the end of a statement would be marked by a newline character a la Python?

Why mark the end of statements at all? Couldn't it be possible to have the compiler deduce the end of a statement automatically, by parsing as much as it can and then stopping? void main() { writefln("Hello World") int a float b = 4 writefln(a, " - ", b) return 0 }
 
 I usually like to keep my lines under 80 characters long for
 readability, and occasionally have long statements (especially if
 there's a ternary operator in there somewhere), so my vote is "nay".
 There are various other arguments against it, too (especially in that it
 makes parsing easier).

I vote in favor, as long as I can do multiple statements per line. It's useful sometimes. Maybe support "; " as a fallback? --downs
May 05 2008
↑ ↓ → BCS <BCS pathlink.com> writes:
downs wrote:

 void main() { writefln("Hello World") int a float b = 4 writefln(a, " - ", b)
return 0 }
 

eyes.. bleeding.. Please don't do that. Another (non style) reason to have the ; is that it provides a bit of redundancy in the code. This results in you needing 2 errors before it compile wrong rather than just one int j = 6; void main() { bob(); writef("%d", j); // 5 or 6? } void bob() { int i j = 5 // this could be //int i, j = 5; // declare i and j as local var //int i; j = 5; // declare i and modify .j }
May 05 2008
→ naryl <cy ngs.ru> writes:
On Mon, 05 May 2008 13:25:17 +0400, downs <default_357-line yahoo.de>  
wrote:

 I vote in favor, as long as I can do multiple statements per line. It's  
 useful sometimes. Maybe support "; "  as a fallback?

  --downs

<g> You are reinventing the Scala language here.
May 05 2008
"Janice Caron" <caron800 googlemail.com> writes:
On 07/05/2008, Daniel Giddings <daniel.giddings gmail.com> wrote:
 while you might need a \ line break char for some code, it is
 very much the exception to the rule

Not if you are obliged (against your will) to write maximum-80-column code, it isn't. In that circumstance, wrapping lines is very, very common. You are also forgetting that any statement block { ... } is effectively a single statement, and that, if (...) { ... } else { ... } is also a single statement. And within any statement, passing a delegate literal to a function - e.g foo(delegate int(int x){ ... }); is still a single expression. In fact the whole concept of what is or is not a "single statement" is really quite nebulous. I suppose you could always make indentation significant too. But here's an idea - how about, let's not. Please let's keep our semicolons.
May 06 2008
↑ ↓ → sambeau <sambeau-nospam mac.com> writes:
Janice Caron Wrote:

 I suppose you could always make indentation significant too. But
 here's an idea - how about, let's not.

:-D
May 06 2008
→ Leandro Lucarella <llucax gmail.com> writes:
Janice Caron, el  7 de mayo a las 05:22 me escribiste:
 On 07/05/2008, Daniel Giddings <daniel.giddings gmail.com> wrote:
 while you might need a \ line break char for some code, it is
 very much the exception to the rule

Not if you are obliged (against your will) to write maximum-80-column code, it isn't. In that circumstance, wrapping lines is very, very common.

Only if you make a lot of steps in the same line or use incredibly long variables or have a very deep nesting of blocks. Avoiding that usually improves code readability and maintainability.
 You are also forgetting that any statement block { ... } is
 effectively a single statement, and that, if (...) { ... } else { ...
 } is also a single statement. And within any statement, passing a
 delegate literal to a function - e.g foo(delegate int(int x){ ... });
 is still a single expression. In fact the whole concept of what is or
 is not a "single statement" is really quite nebulous.

*This* is the real problem with making ';' and '{}' optional and why I stop suggesting this change myself =) I think Python syntax is way much more elegant and readable than C-like syntax, but D has some constructions that are very dependant on '{}' and ';'. Even so, making them *optional* it's maybe possible. You can mark blocks with indentation *or* '{}', let's say: void main() auto x = some_func((int i) { return i + 5 }) // {} are mandatory for delegates while (x) x = 0 { auto x = 1; writefln("this is a new block") } A statement is parsed until ';' *or* EOL, a block is defined either by deeper indentation *or* '{}'. Some constructs have mandatory block delimitation using '{}'. This syntax should not be hard to parse, you can give meaningfull errors, and you get backward compatibility. Everybody should be happy, except from Walter, who has to touch the parser =) -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Cada movimiento que no se hace, es un movimiento que se pierde. Y cada movimiento que se pierde, se transforma en una mochila. Y las mochilas nos alejan, de nuestros amigos y nuestras amigas. Y nuestros amigos se transforman, en enemigos y en enemigas. Cada movimiento que se hace, es una mochila que se deja.
May 07 2008
"Janice Caron" <caron800 googlemail.com> writes:
On 07/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
 Even so, making them *optional* it's maybe possible.
 <snip>
 Everybody should be happy, except from Walter, who has to touch the
 parser =)

Absolutely not. I deeply, deeply want semicolons to remain compulsory. Lose that, and you lose redundancy. Lose redundancy and you lose meaningful error messages.
May 07 2008
↑ ↓ → "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Janice Caron" <caron800 googlemail.com> wrote in message 
news:mailman.547.1210179260.2351.digitalmars-d puremagic.com...
 On 07/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
 Even so, making them *optional* it's maybe possible.
 <snip>
 Everybody should be happy, except from Walter, who has to touch the
 parser =)

Absolutely not. I deeply, deeply want semicolons to remain compulsory. Lose that, and you lose redundancy. Lose redundancy and you lose meaningful error messages.

It always seems funny that your opinions are exactly the same as Walter's. I mean, I think that's almost word-for-word what he said. As I explained about my experience making semicolons optional in MiniD, I haven't run into any situations where skipping semicolons has been a problem. The compiler still gives fine error messages. They're unneccessary in virtually every case. In the (one!) case where there's an ambiguity (though there might be a couple more in D), the compiler doesn't silently choose one, unintuitively; it gives a reasonable error. I'd be interested to know your views on the issue if Walter was ambivalent on the issue or if he was for it.
May 07 2008
→ Leandro Lucarella <llucax gmail.com> writes:
Janice Caron, el  7 de mayo a las 17:54 me escribiste:
 On 07/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
 Even so, making them *optional* it's maybe possible.
 <snip>
 Everybody should be happy, except from Walter, who has to touch the
 parser =)

Absolutely not. I deeply, deeply want semicolons to remain compulsory. Lose that, and you lose redundancy. Lose redundancy and you lose meaningful error messages.

No you don't, \n is your redundancy. So you still get meaningful messages. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- When I was a child I caught a fleeting glimpse Out of the corner of my eye. I turned to look but it was gone I cannot put my finger on it now The child is grown, The dream is gone. I have become comfortably numb.
May 07 2008
"Janice Caron" <caron800 googlemail.com> writes:
On 08/05/2008, Leandro Lucarella <llucax gmail.com> wrote:
 No you don't, \n is your redundancy. So you still get meaningful messages.

That would be true IF AND ONLY IF we were forced to escape newlines that didn't mean end-of-statement. e.g. auto a = b \ (c) I wasn't aware that requiring me to escaping newlines was part of the suggestion. If it was, then I'm even more against it. Besides which, how would that work with statements like if (a == b) { ++i; ++j } else { --i; --j } If newlines were to take over the role of semicolons, then that would turn into if (a == b) { ++i ++j } else { --i --j } Yuk.
May 07 2008
↑ ↓ → "Nick Sabalausky" <a a.a> writes:
"Janice Caron" <caron800 googlemail.com> wrote in message 
news:mailman.550.1210220618.2351.digitalmars-d puremagic.com...
 Besides which, how would that work with statements like

    if (a == b) { ++i; ++j } else { --i; --j }

 If newlines were to take over the role of semicolons, then that would turn 
 into

    if (a == b) { ++i
    ++j } else { --i
    --j }

Not that I'm advocating any "non-compulsory semicolon" syntax, but couldn't the first one work fine by saying "Newline and semicolon are BOTH interpreted as end-of-statement"? (aside from the issue of "with or without a continue-on-next-line symbol"). Or am I just taking the discusion in a circle?
May 07 2008
Sascha Katzner <sorry.no spam.invalid> writes:
Tomasz Sowinski wrote:
 What's the reason of having lines end with a semicolon? Anything else
 than a legacy issue with C/C++?
 
 The only thing I can think of is having multiple statements in one
 line, but that only makes code unreadable. Wouldn't getting rid of ;
 improve readability?

No, you would never know if a statement is just a continuation from the previous line or actually a new one. An example: int i for (i=0; i<10; i++) writefln(i) Should this print all numbers from 1 to 9 or simply increment i ten times and print "10"? The only exception to this are IMO inline assembly statements, the semicolons there are unnecessary and ugly. And since I'm accustomed to write assembly without semicolons at the end I continuously forget them. ;) [X] Vote to kick semicolons in asm statements! LLAP, Sascha
May 05 2008
Tomasz Sowinski <tomeksowi gmail.com> writes:
Sascha Katzner Wrote:

 An example:
 
 	int i
 	for (i=0; i<10; i++)
 	writefln(i)
 
 Should this print all numbers from 1 to 9 or simply increment i ten 
 times and print "10"?

The former. For the latter the it should be for (i=0; i<10; i++) {} writefln(i) btw, can you make a loop without any statement in D? I think no... Anyway, I don't see the benefit of putting or not putting a semicolon there.
May 05 2008
↑ ↓ BCS <BCS pathlink.com> writes:
Tomasz Sowinski wrote:

 btw, can you make a loop without any statement in D? I think no...

correct, and the same for C. In "for(;;);" the trailing ; is a null statement.
May 05 2008
↑ ↓ Tomasz Sowinski <tomeksowi gmail.com> writes:
BCS Wrote:

 In "for(;;);" the trailing ; is a null statement.

I just did that and the compiler said: "use '{ }' for an empty statement, not a ';' "
May 05 2008
Robert Fraser <fraserofthenight gmail.com> writes:
Tomasz Sowinski wrote:
 BCS Wrote:
 
 In "for(;;);" the trailing ; is a null statement.

I just did that and the compiler said: "use '{ }' for an empty statement, not a ';' "

I'm very glad of that protection there. Where I used to work, an accidental semicolon on an if statement ended up causing a production bug.
May 05 2008
↑ ↓ → Walter Bright <newshound1 digitalmars.com> writes:
Robert Fraser wrote:
 Where I used to work, an 
 accidental semicolon on an if statement ended up causing a production bug.

I've seen people waste several hours trying to figure out why their loop bodies would execute exactly once.
May 06 2008
→ BCS <BCS pathlink.com> writes:
Tomasz Sowinski wrote:
 BCS Wrote:
 
 
In "for(;;);" the trailing ; is a null statement.

I just did that and the compiler said: "use '{ }' for an empty statement, not a ';' "

it works in C.
May 05 2008
→ Jesse Phillips <jessekphillips gmail.com> writes:
On Mon, 05 May 2008 12:32:09 -0400, Tomasz Sowinski wrote:

 BCS Wrote:
 
 In "for(;;);" the trailing ; is a null statement.

I just did that and the compiler said: "use '{ }' for an empty statement, not a ';' "

Since putting ; at the end of statements is common writing a for (...;...;...); would be common, and so D makes this invalid, using a ; to make an empty loop, that is why it says to use {} if you want one. BCS's example is just the same as doing a while(true){} though would not compile because of the ; at the end.
May 05 2008
"Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Mon, 05 May 2008 09:13:48 +0100, Tomasz Sowinski <tomeksowi gmail.com>  
wrote:

 Just another feature thought. Never gonna happen, but still...

 What's the reason of having lines end with a semicolon? Anything else  
 than a legacy issue with C/C++?

 The only thing I can think of is having multiple statements in one line,  
 but that only makes code unreadable. Wouldn't getting rid of ; improve  
 readability?


 Tomek

There is always going to be a trade off between having to mark the end of a statement using ";" or having to escape newlines. Otherwise a language becomes horrendously difficult to parse. The rules for when you really need to end a statement would look even stranger if you only needed to do it for particular statements in particular contexts. Perhaps you could have the best of both worlds with a statementiser that knew more about typography and layout. Then your heading back along the python path. Either way the keep is simple rule applies. If its easier for a compiler to grok it might well be easier for a human to grok too and visa versa.
May 05 2008
↑ ↓ Tomasz Sowinski <tomeksowi gmail.com> writes:
Bruce Adams Wrote:

 There is always going to be a trade off between having to mark the end of  
 a statement using ";"
 or having to escape newlines. Otherwise a language becomes horrendously  
 difficult to parse.

Can you give some examples of the difficulties? I'm not into parsing issues really, so maybe I'll learn a thing or two.
May 05 2008
↑ ↓ → Walter Bright <newshound1 digitalmars.com> writes:
Tomasz Sowinski wrote:
 Can you give some examples of the difficulties?
 I'm not into parsing issues really, so maybe I'll learn a thing or two.

How should: f() *g() parse?
May 06 2008
"Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Tomasz Sowinski" <tomeksowi gmail.com> wrote in message 
news:fvmfjs$q4n$1 digitalmars.com...
 Just another feature thought. Never gonna happen, but still...

 What's the reason of having lines end with a semicolon? Anything else than 
 a legacy issue with C/C++?

 The only thing I can think of is having multiple statements in one line, 
 but that only makes code unreadable. Wouldn't getting rid of ; improve 
 readability?

I don't like semicolons. To that end, I have changed statement terminators in my scripting language to accept semicolons or newlines. Having a C-style syntax, it's been a sort of interesting experiment to see what ambiguities arise in the C syntax without them. The language has not dropped semicolons entirely, it's just made it possible to skip them at the end of lines. If you want multiple statements on one line, you still have to separate them with semicolons. There are really only two places in the grammar where there are possible parsing ambiguities: 1) Return statements. Does: return f() parse as "return f();", or does it parse as a "return;" followed by a function call? I have it parse as the latter, as that makes the most sense to me. 2) Function calls vs. parenthesized expressions. Does: x = f (g + h).i() parse as "x = f(g + h).i();" or as "x = f; (g + h).i();" ? I have this give a parsing error since one way or the other doesn't really make sense. In order to resolve the ambiguity, you either have to put a semicolon after the first statement to make it 2 statements, or move the open paren up to the first line to make it one. Other than these two cases, I haven't run into any other tricky parsing spots. Granted, the language is simpler than D and doesn't have nearly as many statements, but it doesn't seem like there would be any other difficulties in parsing. The one major downside to this change in the grammar, however, is that it makes lexical analysis dependent upon syntactic analysis, since the significance of newlines depends upon the current construct being parsed. D prides itself on having no such interdependencies, and you'd be hard-pressed to convince Walter to do otherwise.
May 05 2008
↑ ↓ → Walter Bright <newshound1 digitalmars.com> writes:
Jarrett Billingsley wrote:
 The one major downside to this change in the grammar, however, is that it 
 makes lexical analysis dependent upon syntactic analysis, since the 
 significance of newlines depends upon the current construct being parsed.  D 
 prides itself on having no such interdependencies, and you'd be hard-pressed 
 to convince Walter to do otherwise. 

It's not pride based. There are sound technical reasons.
May 05 2008
bearophile <bearophileHUGS lycos.com> writes:
Tomasz Sowinski Wrote:

As you say such things of D probably aren't going to change, but with some
careful design most (I think all) of those problems can be solved.
And you can even go all the way :-)

This is a little old D example code of mine:

import std.stdio, std.stream, std.string, std.ctype, std.gc;

void traduct(char[] n, char[] digits, int start, char[][] words,
char[][][char[]] gdict) {
    if (start >= digits.length)
        writefln(n, ": ", words.join(" "));
    else {
        auto found_word = false;
        for(auto i = start; i < digits.length; i++)
            if (digits[start .. i+1] in gdict) {
                found_word = true;
                foreach(hit; gdict[digits[start .. i+1]])
                    traduct(n, digits, i+1, words ~ [hit], gdict);
            }
        if (!found_word && (!words || (words &&
!std.ctype.isdigit(words[words.length-1][0]))))
            traduct(n, digits, start+1, words ~ [digits[start..start+1]],
gdict);
    }
}

void main() {
    std.gc.disable();
    auto gtable = maketrans("ejnqrwxdsyftamcivbkulopghzEJNQRWXDSYFTAMCIVBKULOPGHZ",
                           
"0111222333445566677788899901112223334455666777888999");

    size_t line_start;
    char[][][char[]] gdict;
    auto input_dict = cast(char[])std.file.read("dictionary.txt");

    foreach (current_pos, c; input_dict)
        if (c == '\n') { // words with DOS newlines too
            auto word = input_dict[line_start .. current_pos].strip();
            // word isn't a string, it's just a reference (start-end index) to
            //   the input_dict string, despite being stripped.
            gdict[word.translate(gtable, "\"")] ~= word;
            line_start = current_pos+1;
        }
    auto word = input_dict[line_start .. input_dict.length].strip();
    if (word.length > 0)
        gdict[word.translate(gtable, "\"")] ~= word;

    foreach(char[] n; new BufferedFile("input.txt"))
        traduct(n, n.removechars("/-"), 0, [], gdict);
}


The alternative version without ; and braces may look unusual for C programmers:


import std.stdio, std.stream, std.string, std.ctype, std.gc

void traduct(char[] n, char[] digits, int start, char[][] words,
char[][][char[]] gdict):
    if (start >= digits.length):
        writefln(n, ": ", words.join(" "))
    else:
        auto found_word = false
        foreach(i; range(start, digits.length)):
            if (digits[start .. i+1] in gdict):
                found_word = true
                foreach(hit; gdict[digits[start .. i+1]]):
                    traduct(n, digits, i+1, words ~ [hit], gdict)
        if (!found_word && (!words || (words &&
!std.ctype.isdigit(words[words.length-1][0])))):
            traduct(n, digits, start+1, words ~ [digits[start..start+1]], gdict)

void main():
    std.gc.disable()
    auto gtable = maketrans("ejnqrwxdsyftamcivbkulopghzEJNQRWXDSYFTAMCIVBKULOPGHZ",
                           
"0111222333445566677788899901112223334455666777888999")

    char[][][char[]] gdict
    foreach(char[] w; new BufferedFile("dictionary.txt")):
        gdict[w.translate(gtable, "\"")] ~= w.dup

    foreach(char[] n; new BufferedFile("input.txt")):
        traduct(n, n.removechars("/-"), 0, [], gdict)


It seems some people have tried that:

http://www.imitationpickles.org/pyplus/
http://blog.micropledge.com/2007/09/nobraces/
http://micropledge.com/projects/nobraces

But they use very simple means, so they fail in certain situations.
To solve the problem better a pymeta (OMeta parser) may be useful:
http://washort.twistedmatrix.com/

Bye,
bearophile
May 05 2008
↑ ↓ Tomasz Sowinski <tomeksowi gmail.com> writes:
bearophile Wrote:

 Tomasz Sowinski Wrote:
 
 As you say such things of D probably aren't going to change, but with some
careful design most (I think all) of those problems can be solved.
 And you can even go all the way :-)
 
 This is a little old D example code of mine:
 
 import std.stdio, std.stream, std.string, std.ctype, std.gc;
 
 void traduct(char[] n, char[] digits, int start, char[][] words,
char[][][char[]] gdict) {
     if (start >= digits.length)
         writefln(n, ": ", words.join(" "));
     else {
         auto found_word = false;
         for(auto i = start; i < digits.length; i++)
             if (digits[start .. i+1] in gdict) {
                 found_word = true;
                 foreach(hit; gdict[digits[start .. i+1]])
                     traduct(n, digits, i+1, words ~ [hit], gdict);
             }
         if (!found_word && (!words || (words &&
!std.ctype.isdigit(words[words.length-1][0]))))
             traduct(n, digits, start+1, words ~ [digits[start..start+1]],
gdict);
     }
 }
 
 void main() {
     std.gc.disable();
     auto gtable = maketrans("ejnqrwxdsyftamcivbkulopghzEJNQRWXDSYFTAMCIVBKULOPGHZ",
                            
"0111222333445566677788899901112223334455666777888999");
 
     size_t line_start;
     char[][][char[]] gdict;
     auto input_dict = cast(char[])std.file.read("dictionary.txt");
 
     foreach (current_pos, c; input_dict)
         if (c == '\n') { // words with DOS newlines too
             auto word = input_dict[line_start .. current_pos].strip();
             // word isn't a string, it's just a reference (start-end index) to
             //   the input_dict string, despite being stripped.
             gdict[word.translate(gtable, "\"")] ~= word;
             line_start = current_pos+1;
         }
     auto word = input_dict[line_start .. input_dict.length].strip();
     if (word.length > 0)
         gdict[word.translate(gtable, "\"")] ~= word;
 
     foreach(char[] n; new BufferedFile("input.txt"))
         traduct(n, n.removechars("/-"), 0, [], gdict);
 }
 
 
 The alternative version without ; and braces may look unusual for C
programmers:
 
 
 import std.stdio, std.stream, std.string, std.ctype, std.gc
 
 void traduct(char[] n, char[] digits, int start, char[][] words,
char[][][char[]] gdict):
     if (start >= digits.length):
         writefln(n, ": ", words.join(" "))
     else:
         auto found_word = false
         foreach(i; range(start, digits.length)):
             if (digits[start .. i+1] in gdict):
                 found_word = true
                 foreach(hit; gdict[digits[start .. i+1]]):
                     traduct(n, digits, i+1, words ~ [hit], gdict)
         if (!found_word && (!words || (words &&
!std.ctype.isdigit(words[words.length-1][0])))):
             traduct(n, digits, start+1, words ~ [digits[start..start+1]],
gdict)
 
 void main():
     std.gc.disable()
     auto gtable = maketrans("ejnqrwxdsyftamcivbkulopghzEJNQRWXDSYFTAMCIVBKULOPGHZ",
                            
"0111222333445566677788899901112223334455666777888999")
 
     char[][][char[]] gdict
     foreach(char[] w; new BufferedFile("dictionary.txt")):
         gdict[w.translate(gtable, "\"")] ~= w.dup
 
     foreach(char[] n; new BufferedFile("input.txt")):
         traduct(n, n.removechars("/-"), 0, [], gdict)
 

I like the version without ; but how can you tell where a block ends without braces? indents?
May 05 2008
↑ ↓ bearophile <bearophileHUGS lycos.com> writes:
Tomasz Sowinski:
 I like the version without ; but how can you tell where a block ends without
braces? indents?

Where there is a de-dent. There's a known language that's designed like this ;-) Bye, bearophile
May 05 2008
↑ ↓ "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:fvnk34$m27$1 digitalmars.com...
 Tomasz Sowinski:
 I like the version without ; but how can you tell where a block ends 
 without braces? indents?

Where there is a de-dent. There's a known language that's designed like this ;-)

Oh man, now you've got me started on one of my pet peeves... Semantically-meaningful indentation: That is exactly the reason I truly, truly hate Python (Well, that and a complete lack of variable declarations. Hello, hidden bugs!). Python's semantically-meaningful indentation was intended to fix the problem of poorly-indented code by enforcing proper indentation in the language and compiler. But the problem is, it *doesn't* actually enforce it. In fact, it *can't* enforce it because it doesn't have enough information to enforce it. All it really does (and all it's able to do) is run around *assuming* your code is properly indented while silently drawing semantic conclusions from those (obviously not always correct) assumptions. In fact it's really the same root problem as "no variable declarations". In both cases, the compiler does nothing but assume that what you wrote is what you meant, thus silently introducing hidden bugs 1. Whenever you didn't *really* want the new variables "my_reponse" and "my_responce" in additon to "my_response" (VB/VBScript coders use "option explicit" *for a reason*), and 2. Whenever you didn't *really* want to break out of that loop/conditional.
May 06 2008
→ Bill Baxter <dnewsgroup billbaxter.com> writes:
Nick Sabalausky wrote:
 "bearophile" <bearophileHUGS lycos.com> wrote in message 
 news:fvnk34$m27$1 digitalmars.com...
 Tomasz Sowinski:
 I like the version without ; but how can you tell where a block ends 
 without braces? indents?

There's a known language that's designed like this ;-)

Oh man, now you've got me started on one of my pet peeves... Semantically-meaningful indentation: That is exactly the reason I truly, truly hate Python (Well, that and a complete lack of variable declarations. Hello, hidden bugs!). Python's semantically-meaningful indentation was intended to fix the problem of poorly-indented code by enforcing proper indentation in the language and compiler. But the problem is, it *doesn't* actually enforce it. In fact, it *can't* enf