www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - One document about Go

reply bearophile <bearophileHUGS lycos.com> writes:
I have just found it through Reddit, "Some Trucs and Machins about Google Go",
by Narbel:
http://dept-info.labri.fr/~narbel/Lect/go-lecture.pdf

Few comments about the text.

----------------

In Go you can omit semicolons at the end of lines, so I presume it's not a
terrible thing for C-like languages:

package main
import " fmt " // formatted I/O.
func main() {
    fmt.Printf ("Hello Hello\n")
}

----------------

In Go you can omit some () for example in "if":

if !*omitNewline {
    s += Newline
}


Generally I don't like to remove the parentheses of function calls (as done in
Ruby), but in this case of the 'if' syntax I think removing them helps remove
some useless visual noise from the code.

----------------

The multiple return values is the Go feature I'd like most for D3 (beside named
arguments):


func f(int i) (int, string) {
    return (i+1) ("supergenial")
}
x, y := f(3);

----------------

Page 15-26 shows that there is polymorphism in Go too. Go designers are trying
to invent/adopt something simpler than C++-style templates.

----------------

Bye,
bearophile
Jun 01 2010
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
I haven't read the document.

bearophile wrote:

 In Go you can omit semicolons at the end of lines
I never understood what people had against them. I've probably had trouble with a stray semicolon once or twice, but no big deal.
 In Go you can omit some () for example in "if":

 if !*omitNewline {
     s += Newline
 }
Just like the curly braces should always be there, the parenthesis should always be there as well. :)
 Generally I don't like to remove the parentheses of function
 calls (as done in Ruby)
Same here. I am just starting to get used to omitting the parenthesis for properties. But that's it for me. :) For example I don't like array.sort.
 but in this case of the 'if' syntax I think removing them helps
 remove some useless visual noise from the code.
I don't see it as noise. Consistency is important for me.
 Go designers are trying to invent/adopt something simpler than
 C++-style templates
I will not be surprised when they "invent" the same syntax of a language Dat Dey've never hearD of... ;) Ali
Jun 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Ali Çehreli:

  > Go designers are trying to invent/adopt something simpler than
  > C++-style templates
 
 I will not be surprised when they "invent" the same syntax of a language 
 Dat Dey've never hearD of... ;)
It's not just a matter of syntax, it's something quite different from C++/D style templates. Bye, bearophile
Jun 01 2010
prev sibling next sibling parent reply Lurker <nospam spamfree.net> writes:
== Quote from bearophile (bearophileHUGS lycos.com)'s article

 In Go you can omit semicolons at the end of lines, so I presume it's not a
terrible thing for C-like languages:
 package main
 import " fmt " // formatted I/O.
 func main() {
     fmt.Printf ("Hello Hello\n")
 }
When will D support that? Removing unnecessary semis really pretties up the code.
 ----------------
 In Go you can omit some () for example in "if":
 if !*omitNewline {
     s += Newline
 }
 Generally I don't like to remove the parentheses of function calls (as
done in Ruby), but in this case of the 'if' syntax I think removing them helps remove some useless visual noise from the code. I disagree.
 ----------------
 The multiple return values is the Go feature I'd like most for D3 (beside
named arguments):
 func f(int i) (int, string) {
     return (i+1) ("supergenial")
 }
 x, y := f(3);
Combine the 2 things into one struct and return by value. Multi-value return makes for hard to comprehend code. So, IMO, it's hardly syntactic sugar: it's syntactic grafitti.
 ----------------
 Page 15-26 shows that there is polymorphism in Go too. Go designers are
trying to invent/adopt something simpler than C++-style templates.
 ----------------
"Compile-time polymorhism": you were thinking "generics/templates"? When seeing or using the term 'polymorphism' without additional modifiers, I tend to think of "inclusion polymorphism".
Jun 01 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Lurker wrote:
 == Quote from bearophile (bearophileHUGS lycos.com)'s article
 
 In Go you can omit semicolons at the end of lines, so I presume it's not a
terrible thing for C-like languages:
 package main
 import " fmt " // formatted I/O.
 func main() {
     fmt.Printf ("Hello Hello\n")
 }
When will D support that? Removing unnecessary semis really pretties up the code.
This idea reappears every few years, and even gets folded into a language now and then. It started with Pascal, and most recently has appeared in Javascript. The idea basically sux because of the maintenance issue. What maintenance issue? The one where you decide to add a new line of code before the }. You inevitably forget to go back and append the ; to the previous line. Even if you do happen to remember, now your diff visualizer shows 2 lines changed rather than 1. C got it right and it doesn't need fixing. (There are other good reasons for the ; I outlined in my blog http://www.drdobbs.com/blog/archives/2010/05/improving_compi.html )
Jun 01 2010
next sibling parent reply Alex Makhotin <alex bitprox.com> writes:
Walter Bright wrote:
 You inevitably forget to go back and append the ; to the 
 previous line. 
Current DMD compiler version outputs on attempt to make empty statement:
 use '{ }' for an empty statement, not a ';'
Is there a reason? -- Alex Makhotin, the founder of BITPROX, http://bitprox.com
Jun 02 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Alex Makhotin:
 Current DMD compiler version outputs on attempt to make empty statement:
 use '{ }' for an empty statement, not a ';'
Is there a reason?
Yes, it avoids a common type of bug: for (int i = 0; i < 10; i++); writeln(i); I have seen students waste minutes locating that bug. Bye, bearophile
Jun 01 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
 for (int i = 0; i < 10; i++);
   writeln(i);
That's a bad example, sorry :-( Bye, bearophile
Jun 01 2010
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 Alex Makhotin:
 Current DMD compiler version outputs on attempt to make empty statement:
 use '{ }' for an empty statement, not a ';'
Is there a reason?
Yes, it avoids a common type of bug: for (int i = 0; i < 10; i++); writeln(i); I have seen students waste minutes locating that bug.
I've seen a whole afternoon lost on that one.
Jun 01 2010
parent reply =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= <jeberger free.fr> writes:
Walter Bright wrote:
 bearophile wrote:
 Alex Makhotin:
 Current DMD compiler version outputs on attempt to make empty stateme=
nt:
 use '{ }' for an empty statement, not a ';'
Is there a reason?
Yes, it avoids a common type of bug: for (int i =3D 0; i < 10; i++); writeln(i); I have seen students waste minutes locating that bug.
=20 I've seen a whole afternoon lost on that one.
Of course, using a decent editor will prevent it: if the editor is able to handle indentation correctly, it will indent the writeln in the same column as the for which makes the problem appear immediately. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jun 01 2010
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jérôme M. Berger wrote:
 	Of course, using a decent editor will prevent it: if the editor is
 able to handle indentation correctly, it will indent the writeln in
 the same column as the for which makes the problem appear immediately.
I think it is a serious mistake to design a language that requires a syntax-aware editor.
Jun 01 2010
next sibling parent reply Bill Baxter <wbaxter gmail.com> writes:
On Tue, Jun 1, 2010 at 2:24 PM, Walter Bright
<newshound1 digitalmars.com> wrote:
 J=E9r=F4me M. Berger wrote:
 =A0 =A0 =A0 =A0Of course, using a decent editor will prevent it: if the =
editor is
 able to handle indentation correctly, it will indent the writeln in
 the same column as the for which makes the problem appear immediately.
I think it is a serious mistake to design a language that requires a syntax-aware editor.
Computer languages exist to make life easier for their human users. So I keep thinking that rather than limit the language's options in terms of grammar, it would be better to just provide an easy-to-use parsing library for the language that makes adding editor support simple. What would be the problem with that? --bb
Jun 01 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Bill Baxter wrote:
 Computer languages exist to make life easier for their human users.
 So I keep thinking that rather than limit the language's options in
 terms of grammar, it would be better to just provide an easy-to-use
 parsing library for the language that makes adding editor support
 simple.  What would be the problem with that?
I've thought many times about adding a D lexer & parser to the standard library. It's a good idea.
Jun 01 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
 I've thought many times about adding a D lexer & parser to the standard
library. 
 It's a good idea.
So a D (front-end) written in D can use it while it compiles itself :-) Bye, bearophile
Jun 01 2010
prev sibling next sibling parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 06/01/2010 06:27 PM, Walter Bright wrote:
 Bill Baxter wrote:
 Computer languages exist to make life easier for their human users.
 So I keep thinking that rather than limit the language's options in
 terms of grammar, it would be better to just provide an easy-to-use
 parsing library for the language that makes adding editor support
 simple. What would be the problem with that?
I've thought many times about adding a D lexer & parser to the standard library. It's a good idea.
Please do. OTish: would it make sense to extend mixin() to accept arrays or whatever of Tokens?
Jun 01 2010
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2010-06-02 01:27, Walter Bright wrote:
 Bill Baxter wrote:
 Computer languages exist to make life easier for their human users.
 So I keep thinking that rather than limit the language's options in
 terms of grammar, it would be better to just provide an easy-to-use
 parsing library for the language that makes adding editor support
 simple. What would be the problem with that?
I've thought many times about adding a D lexer & parser to the standard library. It's a good idea.
Yes, please, that would be awesome. -- /Jacob Carlborg
Jun 02 2010
prev sibling parent reply BCS <none anon.com> writes:
Hello Walter,

 Jérôme M. Berger wrote:
 
 Of course, using a decent editor will prevent it: if the editor is
 able to handle indentation correctly, it will indent the writeln in
 the same column as the for which makes the problem appear
 immediately.
 
I think it is a serious mistake to design a language that requires a syntax-aware editor.
and by the time the editor is pushy enough to force that, it starts annoying me for other reasons. Format what I'm typing, sure, reformat what I already types, not unless I ask you to. -- ... <IXOYE><
Jun 01 2010
parent reply =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= <jeberger free.fr> writes:
BCS wrote:
 Hello Walter,
=20
 J=E9r=F4me M. Berger wrote:

 Of course, using a decent editor will prevent it: if the editor is
 able to handle indentation correctly, it will indent the writeln in
 the same column as the for which makes the problem appear
 immediately.
I think it is a serious mistake to design a language that requires a syntax-aware editor.
=20 and by the time the editor is pushy enough to force that, it starts annoying me for other reasons.
If it's any good, it will allow you to configure everything, including disabling whatever is annoying you.
 Format what I'm typing, sure, reformat
 what I already types, not unless I ask you to.
=20
Of course, that should be a given. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jun 02 2010
parent BCS <none anon.com> writes:
Hello Jérôme,

 BCS wrote:
 
 Hello Walter,
 
 Jérôme M. Berger wrote:
 
 Of course, using a decent editor will prevent it: if the editor is
 able to handle indentation correctly, it will indent the writeln in
 the same column as the for which makes the problem appear
 immediately.
 
I think it is a serious mistake to design a language that requires a syntax-aware editor.
and by the time the editor is pushy enough to force that, it starts annoying me for other reasons.
If it's any good, it will allow you to configure everything, including disabling whatever is annoying you.
The benefit talked about above can only be had by allowing the exact feature I don't want.
 Format what I'm typing, sure, reformat
 what I already types, not unless I ask you to.
Of course, that should be a given. Jerome
-- ... <IXOYE><
Jun 02 2010
prev sibling next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
J=C3=A9r=C3=B4me M. Berger <jeberger free.fr> wrote:

 for (int i =3D 0; i < 10; i++);
   writeln(i);

 I have seen students waste minutes locating that bug.
I've seen a whole afternoon lost on that one.
Of course, using a decent editor will prevent it: if the editor is able to handle indentation correctly, it will indent the writeln in the same column as the for which makes the problem appear immediately.=
No. Having been a programming teacher, I can assure you that beginners /will/ make this mistake, no matter how much the IDE helps them. If the = IDE does not indent things the way they expect it to, they will 'fix' it. Having worked with auto-indenting editors myself, I have to say they are= the work of devils. They tend to indent seemingly at random, and choose = the most unpleasant ways if they feel they can get away with it. And should you for some obscure reason want to use a different indentati= on style (say, you've downloaded some code), it will be as confused as a non-geek doing the motherboard dance. -- = Simen
Jun 01 2010
parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Simen kjaeraas wrote:
 J=C3=A9r=C3=B4me M. Berger <jeberger free.fr> wrote:
=20
 for (int i =3D 0; i < 10; i++);
   writeln(i);

 I have seen students waste minutes locating that bug.
I've seen a whole afternoon lost on that one.
Of course, using a decent editor will prevent it: if the editor is=
 able to handle indentation correctly, it will indent the writeln in
 the same column as the for which makes the problem appear immediately.=
=20
 No. Having been a programming teacher, I can assure you that beginners
 /will/ make this mistake, no matter how much the IDE helps them. If the=
IDE
 does not indent things the way they expect it to, they will 'fix' it.
=20
 Having worked with auto-indenting editors myself, I have to say they ar=
e
 the work of devils. They tend to indent seemingly at random, and choose=
the
 most unpleasant ways if they feel they can get away with it.
 And should you for some obscure reason want to use a different indentat=
ion
 style (say, you've downloaded some code), it will be as confused as a
 non-geek doing the motherboard dance.
=20
Either (X)Emacs or Vim indent things properly, have completely configurable style and work fine. For all others, I would tend to agree. Since you use the word "IDE" in the first part of your message, I'd say you haven't tried what I call a *decent* editor ;) Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jun 02 2010
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Jérôme M. Berger"" <jeberger free.fr> wrote in message 
news:hu3r8t$1t3$1 digitalmars.com...

I've used editors that keep trying to re-arrange my code as I type (ex, 
Visual Studio) and I find it to be annoying as hell. It just gets in my way, 
even when it does correctly guess what I want. And often it doesn't, because 
I tend to type code in a very non-linear way which confuses the hell out of 
those "smart" editors.

To me, using an editor like that is like playing [Klondike] solitaire with 
some asshole hovering over your shoulder trying to "help out" by yammering 
"Ooh, ooh!! Put that one there! No no! The 3 on the 4, the 3 on the 4!!".
Jun 01 2010
next sibling parent reply Alex Makhotin <alex bitprox.com> writes:
Nick Sabalausky wrote:
  
 I've used editors that keep trying to re-arrange my code as I type (ex, 
 Visual Studio) and I find it to be annoying as hell. It just gets in my way, 
 even when it does correctly guess what I want. And often it doesn't, because 
 I tend to type code in a very non-linear way which confuses the hell out of 
 those "smart" editors.
Why didn't you turn it off? Could you, please, give some examples on what should be done with the 'smart' indentation option to work for you? -- Alex Makhotin, the founder of BITPROX, http://bitprox.com
Jun 01 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Alex Makhotin" <alex bitprox.com> wrote in message 
news:hu438s$jcb$1 digitalmars.com...
 Nick Sabalausky wrote:
  I've used editors that keep trying to re-arrange my code as I type (ex, 
 Visual Studio) and I find it to be annoying as hell. It just gets in my 
 way, even when it does correctly guess what I want. And often it doesn't, 
 because I tend to type code in a very non-linear way which confuses the 
 hell out of those "smart" editors.
Why didn't you turn it off?
Umm, not really sure, it's been a while since I've used an editor that did it. Could be that I just never thought to look for a setting. Or it could be that I did end up turning it off and just don't remember. Not really sure.
 Could you, please, give some examples on what should be done with the 
 'smart' indentation option to work for you?
I'm pretty much convinced that it would have to be able to read my mind. And probably write to my mind too. It's just that it keeps surprising me, doing things I don't expect it to do or that I just don't want it to do. And the way I want to go about writing something tends to change from moment to moment anyway. Plus, I've never found formatting my own code to be difficult or time-consuming enough to really need automated assistance anyway. What I do like is what Programmer's Notepad 2 does: when I hit "Enter", it auto-indents the new line exactly the same as the line above it. And then it stays out of my way and doesn't change a thing until the next time I hit "Enter", at which point it'll do just like before: auto-indent the new line to however the previous line was indented, and leave everything else alone. Nice, simple, predictable, frequently helpful, never gets in my way (and *especially* never tries to decide that it knows better than me how my code should be formatted, like VS tends to do). The "smart" ones have much more complex behavior that's not as easy to anticipate when my mind is preoccupied with the programming task at hand. ------------------------------- Not sent from an iPhone.
Jun 01 2010
parent reply Adam Ruppe <destructionator gmail.com> writes:
On 6/1/10, Nick Sabalausky <a a.a> wrote:
 What I do like is what Programmer's Notepad 2 does: when I hit "Enter", it
 auto-indents the new line exactly the same as the line above it.
Vim does the same. When I'm using some other editor, I always end up hitting tab or backspace too many times, expecting this auto-indent and ending up getting something else!
Jun 01 2010
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
On Tue, 01 Jun 2010 21:15:45 -0400, Adam Ruppe wrote:

 On 6/1/10, Nick Sabalausky <a a.a> wrote:
 What I do like is what Programmer's Notepad 2 does: when I hit "Enter",
 it auto-indents the new line exactly the same as the line above it.
Vim does the same. When I'm using some other editor, I always end up hitting tab or backspace too many times, expecting this auto-indent and ending up getting something else!
to get the "smart" indent in vim cindent is used. This can be customized in many ways but obviously not what Nick wants. Personally if vim indents something in a manner I didn't expect is because my expectations were wrong not the indentation. Also it doesn't do alignment how I want so that is annoying but has little to do with indentation.
Jun 01 2010
parent reply Alex Makhotin <alex bitprox.com> writes:
Jesse Phillips wrote:
 
 Also it doesn't 
 do alignment how I want so that is annoying but has little to do with 
 indentation.
Jesse, Could you please, explain, what exactly is annoying? -- Alex Makhotin, the founder of BITPROX, http://bitprox.com
Jun 02 2010
parent Jesse Phillips <jessekphillips+D gmail.com> writes:
On Wed, 02 Jun 2010 11:15:16 +0300, Alex Makhotin wrote:

On Wed, 02 Jun 2010 11:15:16 +0300, Alex Makhotin wrote:

 Jesse Phillips wrote:
 
 Also it doesn't
 do alignment how I want so that is annoying but has little to do with
 indentation.
Jesse, Could you please, explain, what exactly is annoying?
I think part of the problem is I'm not consistent sometimes I align with the () I'm working in or the outer ones, a few spaces from the indentation level, or some other text on the line. Also (while many may disagree) I use tabs for indentation, but not for alignment. I do avoid having lines run so long with is the reason I haven't looked into fixing the issue and just turned off the feature.
Jun 02 2010
prev sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Nick Sabalausky wrote:
 "J=EF=BF=BDr=EF=BF=BDme M. Berger"" <jeberger free.fr> wrote in message=
=20
 news:hu3r8t$1t3$1 digitalmars.com...
=20
 I've used editors that keep trying to re-arrange my code as I type (ex,=
=20
 Visual Studio)
I said a *decent* editor... Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jun 02 2010
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 02 Jun 2010 15:39:16 -0400, Alex Makhotin <alex bitprox.com> wrote:

 Walter Bright wrote:
 You inevitably forget to go back and append the ; to the previous line.
Current DMD compiler version outputs on attempt to make empty statement:
 use '{ }' for an empty statement, not a ';'
Is there a reason?
Yes, this: if(x == 5 || x == 6); n = 4; Typing a semi-colon is so automatic, that we will accidentally put one where we don't want to (I've done it many times). This is one of those rare cases where people can easily type valid code that does not do what they want. -Steve
Jun 01 2010
parent reply Alex Makhotin <alex bitprox.com> writes:
Steven Schveighoffer wrote:
 where we don't want to (I've done it many times).  This is one of those 
 rare cases where people can easily type valid code that does not do what 
 they want.
The reason I ask is because I sometimes do empty statements intentionally by placing a semicolon (surprised?). DMD doesn't allow me to do it, so I put {} as it asks. In contrast, Microsoft C/C++ does(with opt. /Wall):
 warning C4390: ';' : empty controlled statement found; is this the intent?
I think it's correct way it should be done. And about the question of omitting semicolon. I don't like the optional use of it. In this respect I don't like the GO's way it inserts semicolons automatically by the lexer(!). Just one excerpt from http://golang.org/doc/effective_go.html
 One caveat. You should never put the opening brace of a control structure (if,
for, switch, or select) on the next line. If you do, a semicolon will be
inserted before the brace, which could cause unwanted effects. Write them like
this
 
 if i < f() {
     g()
 }
 
 not like this
 
 if i < f()  // wrong!
 {           // wrong!
     g()
 }
I prefer ANSI(Allman) style(second example, wrong). They want to force Java-like style which I dislike much. -- Alex Makhotin, the founder of BITPROX, http://bitprox.com
Jun 02 2010
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 02 Jun 2010 16:50:05 -0400, Alex Makhotin <alex bitprox.com> wrote:

 Steven Schveighoffer wrote:
 where we don't want to (I've done it many times).  This is one of those  
 rare cases where people can easily type valid code that does not do  
 what they want.
The reason I ask is because I sometimes do empty statements intentionally by placing a semicolon (surprised?). DMD doesn't allow me to do it, so I put {} as it asks.
No, not surprised. But compare the ratio of how many times someone wants to have an empty loop/if statement to how many times someone accidentally forms one. Empty loops are sometimes desired, and I think the pain of requiring {} is worth the savings of not having accidents interpreted as intentions.
 In contrast, Microsoft C/C++ does(with opt. /Wall):
 warning C4390: ';' : empty controlled statement found; is this the  
 intent?
I think it's correct way it should be done.
It is a judgement call, I think D made the right decision on disallowing it, even without warnings turned on. In a couple weeks you will forget about that one time you had to write an empty loop :)
 And about the question of omitting semicolon. I don't like the optional  
 use of it. In this respect I don't like the GO's way it inserts  
 semicolons automatically by the lexer(!).

 Just one excerpt from http://golang.org/doc/effective_go.html
 One caveat. You should never put the opening brace of a control  
 structure (if, for, switch, or select) on the next line. If you do, a  
 semicolon will be inserted before the brace, which could cause unwanted  
 effects. Write them like this
  if i < f() {
     g()
 }
  not like this
  if i < f()  // wrong!
 {           // wrong!
     g()
 }
Oh, my, god. This is horrendous. Their *default* interpretation is "hey, this guy obviously wants an if statement that does nothing"?
 I prefer ANSI(Allman) style(second example, wrong).
 They want to force Java-like style which I dislike much.
I do too. You will not find me using go until they change this. -Steve
Jun 01 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message 
news:op.vdm3e1fbeav7ka localhost.localdomain...
 On Wed, 02 Jun 2010 16:50:05 -0400, Alex Makhotin <alex bitprox.com> 
 wrote:
 I prefer ANSI(Allman) style(second example, wrong).
 They want to force Java-like style which I dislike much.
I do too. You will not find me using go until they change this.
This is something I've probably given *way* too much thought to. First of all, my style is generally like this: void foo(int num, bool doBigLoop) { if(num < 7) writeln("Under 7"); if(doBigLoop) foreach(int x; 0..10) // Don't do this "stacking" often, foreach(int y; 0..10) // but it's handy once in a while. if(x+y < 9) { writefln("Under 9"); if(num == x) writefln("num == x"); } } I never liked having the opening and closing curly braces not line up. Just bugs me. Makes it slightly harder to read too. And even harder still if "} else {" is used. I *really* don't like that, when it's used, half the time I don't even see the "else". But, at the same time, the opening-brace-alone-on-it's-own-line often seems like a real waste that (visually) stretches the code out needlessly. So, for a language like D, I just use the '{'-on-a-separate-line style and just deal with the extra line since it seems to be the lesser of the evils. Sometimes it helps readability with long functions anyway. Now, I was happy with that for a long time, but now that I'm learning and loving a lot of functional-like stuff, I'm more and more coming across situations like this: void funcWithLongHeader(SomeTempl!int alpha, SomeTempl!int beta, SomeTempl!int gamma, SomeTempl!int delta, int SomeTempl!epsilon = epsilonDefault) { auto foo = [["a":1, "b":2, "c":3], ["z1":0, "z2":7, "z3":4], ["hi":5, "b":3, "c":3]]; if(alpha + beta == 0 || beta + gamma == 3 || gamma + delta == 6 || alpha = beta + gamma) { writeln("Whee"); whatever(); } someHighOrderFunc((int i) { if(i==77) return 1; else return i; }); } Obviously I have to add some newlines in there, but how should I do it? I could stay consistent with my curly-brace usage: void funcWithLongHeader ( SomeTempl!int alpha, SomeTempl!int beta, SomeTempl!int gamma, SomeTempl!int delta, int SomeTempl!epsilon = epsilonDefault ) { auto foo = [ ["a":1, "b":2, "c":3], ["z1":0, "z2":7, "z3":4], ["hi":5, "b":3, "c":3] ]; if ( alpha + beta == 0 || beta + gamma == 3 || gamma + delta == 6 || alpha = beta + gamma ) { writeln("Whee"); whatever(); } someHighOrderFunc ( (int i) { if(i==77) return 1; else return i; } ); } The arrays look ok. The lambda looks maybe a bit too spread out. The rest looks like crap. I could do this: void funcWithLongHeader( SomeTempl!int alpha, SomeTempl!int beta, SomeTempl!int gamma, SomeTempl!int delta, int SomeTempl!epsilon = epsilonDefault) { auto foo = [ ["a":1, "b":2, "c":3], ["z1":0, "z2":7, "z3":4], ["hi":5, "b":3, "c":3] ]; if(alpha + beta == 0 || beta + gamma == 3 || gamma + delta == 6 || alpha = beta + gamma) { writeln("Whee"); whatever(); } someHighOrderFunc( (int i) { if(i==77) return 1; else return i; } ); } That looks a little better, but there's still some issues. The closing parenthesis on the function header and the if statement are difficult to see. Also, terms in the if conditional are all misaligned now, and in a way that can't be solved in a cross-editor way without eliminating all tabs (which shows a blatant disregard for other people's indentation preferences), or using a very careful, deliberate and brittle mix of spaces and tabs. Also, that now introduces an annoying bit of inconsistency: some grouping symbols start at the end of a line, and others exist on a newline. Parts of it look very Java-style, and other parts look very non-Java-style. So at this point, I can't help thinking: Why not just take the plunge and go 'always-at-the-end-of-the-line' all the way? And while I'm at it, I'll put the closing-parenthesis at the start of a new line, just like a closing curly-brace: void funcWithLongHeader( SomeTempl!int alpha, SomeTempl!int beta, SomeTempl!int gamma, SomeTempl!int delta, int SomeTempl!epsilon = epsilonDefault ) { // snip if( alpha + beta == 0 || beta + gamma == 3 || gamma + delta == 6 || alpha = beta + gamma ) { writeln("Whee"); whatever(); } // snip } Eeeww!!! Also, note that I haven't even tossed call-chaining or templates into the mix. So at this point, I'm convinced that there is no ideal indentation style for C/D/Java-style languages. So what about different languages? If you adopt a LISP-like style, you could have vertically-aligned-braces and also omit the useless "opening curly brace" line: { if(x+y < 9); whatever(); } But that places much more visual emphasis on the '{' than the 'if', which IMO is completely backwards since the 'if' is much more important. In other words, too hard to read. And the weird alignment of the 'if' compared to the 'whatever' is, well...weird. There's another C-derived natively-compiled language out there (I forget what it's called) that has a rather interesting approach. It just simply doesn't use (or even allow, AIUI) an opening brace: if(x+y < 9) whatever(); } It introduces a certain lack of symmetry, and maybe could cause parsing problems for certain things (ex, D2-style template constraints probably wouldn't work, at least not as-is), but it solves the other problems. Although the approach doesn't really scale to parenthesis. There's BASIC/Perl-style keyword approaches: if BLAH then whatever end if if(BLAH) whatever fi These also have the added bonus of avoiding the following unreadable crap that probably every C/D/Java-style programmer is all too familiar with: } } } } } } But of course, this approach is annoyingly verbose, especially in the case of BASIC (why should the ending keywords of a block be more verbose then the starting keyword? just seems pointless and unbalanced). And the Perl-style approach doesn't scale particularly well to other constructs (such as 'while' or user-defined constructs). Then there's the Python approach. But all I'm going to say about that is: Those who dislike it already know why they dislike it, and those who do like it have probably already heard all the complaints before. The only conclusion I can come up with is that all syntaxes suck ;)
Jun 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:
 Also, note that I haven't even tossed call-chaining or templates into the 
 mix.
You can also add to the mix the C labels used by goto and break, the in{} out{} body{} contract programming syntax, and the private:/public: attributes too, they give me code formatting troubles :-) Bye, bearophile
Jun 01 2010
prev sibling next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Alex Makhotin wrote:
 In contrast, Microsoft C/C++ does(with opt. /Wall):
 warning C4390: ';' : empty controlled statement found; is this the 
 intent?
I think it's correct way it should be done.
Warnings are wishy-washy language design. Code should pass, or it should not. Not sort of, kind of, maybe, depending on switch settings. Let's say you publish your code with the ; that way. Random users sees your code in an article. Is it a bug or not? Who knows? Random user downloads your code and it compiles with warning messages. Is this the intent or not? Who knows?
Jun 01 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/01/2010 04:36 PM, Walter Bright wrote:
 Alex Makhotin wrote:
 In contrast, Microsoft C/C++ does(with opt. /Wall):
 warning C4390: ';' : empty controlled statement found; is this the
 intent?
I think it's correct way it should be done.
Warnings are wishy-washy language design. Code should pass, or it should not. Not sort of, kind of, maybe, depending on switch settings.
Then let's eliminate warnings from dmd and make them all errors. It's about time! Andrei
Jun 01 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 On 06/01/2010 04:36 PM, Walter Bright wrote:
 Alex Makhotin wrote:
 In contrast, Microsoft C/C++ does(with opt. /Wall):
 warning C4390: ';' : empty controlled statement found; is this the
 intent?
I think it's correct way it should be done.
Warnings are wishy-washy language design. Code should pass, or it should not. Not sort of, kind of, maybe, depending on switch settings.
Then let's eliminate warnings from dmd and make them all errors. It's about time!
Before you joined us, there were huge flamefests about this.
Jun 01 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
 Before you joined us, there were huge flamefests about this.
I don't know about turning them all into errors, but the missing "override" http://d.puremagic.com/issues/show_bug.cgi?id=383 The warnings generated by the examples here can become errors: http://www.digitalmars.com/d/2.0/hijack.html Bye, bearophile
Jun 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
 http://d.puremagic.com/issues/show_bug.cgi?id=383
Sorry, I meant: http://d.puremagic.com/issues/show_bug.cgi?id=3836
Jun 01 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/01/2010 05:06 PM, Walter Bright wrote:
 Andrei Alexandrescu wrote:
 On 06/01/2010 04:36 PM, Walter Bright wrote:
 Alex Makhotin wrote:
 In contrast, Microsoft C/C++ does(with opt. /Wall):
 warning C4390: ';' : empty controlled statement found; is this the
 intent?
I think it's correct way it should be done.
Warnings are wishy-washy language design. Code should pass, or it should not. Not sort of, kind of, maybe, depending on switch settings.
Then let's eliminate warnings from dmd and make them all errors. It's about time!
Before you joined us, there were huge flamefests about this.
We've accumulated a lot of experience in the meantime. Besides, as far as I remember, in the early days there were huge flamefests just about anything :o). Andrei
Jun 01 2010
prev sibling parent Alex Makhotin <alex bitprox.com> writes:
Walter Bright wrote:
  
 Code should pass, or it should 
 not. Not sort of, kind of, maybe, depending on switch settings.
I agree. That is what option /WX (treat warning as errors) is about. Excuse me for the broken clock(messages seems to appear incorrectly again :(, I should fix this soon). Why doesn't the news server place correct stamp on arrival? I'm confused a bit(the problem seems in Linux custom built kernel without some RTC option)... -- Alex Makhotin, the founder of BITPROX, http://bitprox.com
Jun 01 2010
prev sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Wed, 02 Jun 2010 23:50:05 +0300, Alex Makhotin wrote:
 Just one excerpt from http://golang.org/doc/effective_go.html
 One caveat. You should never put the opening brace of a control
 structure (if, for, switch, or select) on the next line. If you do, a
 semicolon will be inserted before the brace, which could cause unwanted
 effects. Write them like this
 
 if i < f() {
     g()
 }
 
 not like this
 
 if i < f()  // wrong!
 {           // wrong!
     g()
 }
Words fail me. That design is so horrible, at first I thought it was a joke. -Lars
Jun 02 2010
prev sibling next sibling parent reply Lurker <nospam spamfree.net> writes:
== Quote from Walter Bright (newshound1 digitalmars.com)'s article
 Lurker wrote:
 When will D support that? Removing unnecessary semis really pretties up
the
 code.
This idea reappears every few years, and even gets folded into a language
now
 and then. It started with Pascal, and most recently has appeared in
Javascript.
 The idea basically sux because of the maintenance issue. What maintenance
issue?
 The one where you decide to add a new line of code before the }. You
inevitably
 forget to go back and append the ; to the previous line. Even if you do
happen
 to remember, now your diff visualizer shows 2 lines changed rather than 1.
While I've not coded in a language without semis, I don't think that adding the semi on a multi-statement line is something easy to forget to do. Did I grok your example correctly?
 C got it right and it doesn't need fixing.
 (There are other good reasons for the ; I outlined in my blog
 http://www.drdobbs.com/blog/archives/2010/05/improving_compi.html )
I think that when people suggest removing semis, they mean that the compiler will put them in automagically, in place of an end-of-line character. So on your blog, where you suggest that semis are important as synching tokens, it's really the same thing, because you either work with the EOLs or the compiler converts them to semis on statement lines. Maybe it opens a can of worms, but maybe semis proliferate to new languages (obviously Go jettisoned the semis) just because someone picked the "wrong" way to do it with C(?) and maybe you didn't step back an eval that issue when you created D so long ago and/or just wanted backwards compatibility with C (?) instead of a "drastic" departure from it (?). So, we have a semi-new language (no pun intended), D that embraces semis, and we have a new language Go that rejects them. The thing is though, C- compatibility was not a goal of Go but some level of C-likeness was an important goal for D (right?). Therefore, I think I'd have to weight Go's decision more, at least for now unless they decide it was a bad decision and go back and change to semis. And I do like what the the unnecessary "missing" semis do for code readability. .02 (Just aloud off the top of my head).
Jun 01 2010
parent Adam Ruppe <destructionator gmail.com> writes:
On 6/1/10, Lurker <nospam spamfree.net> wrote:
 And I do like what the the
 unnecessary "missing" semis do for code readability.
To me, missing semicolons look like sentence fragments. I tend to toss them in even on languages that don't require it, since it just looks wrong otherwise :S
Jun 01 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Lurker:

Combine the 2 things into one struct and return by value. Multi-value return
makes for hard to comprehend code. So, IMO, it's hardly syntactic sugar: it's
syntactic grafitti.<
You are very wrong, multiple return values are good, if they have a good enough better. Multiple return values make code simpler to write, simpler to read and remove the need for silly and logically ridiculous features like "out" arguments (an input value that is a return? This is making things go backwards). D language isn't even able to tell if an "out" argument has being used before it is uninitialized variables is an error) This is awful and surely worse than multiple return values. import std.stdio: writeln; import std.conv: to; int foo(int x, out string s) { writeln(s); int result = x * x; s = to!string(result); return result; } void main () { string s; writeln(s); int r = foo(10, s); writeln(r); } A possible syntax for D multiple return values: import std.stdio: writeln; import std.conv: to; (int, string) foo(int x) { int result = x * x; return (result, to!string(result)); } void main () { (int r, string s) = foo(10); writeln(s); writeln(r); } The second is simpler to understand code and less bug-prone than the first. An alternative syntax: import std.stdio: writeln; import std.conv: to; [int, string] foo(int x) { int result = x * x; return [result, to!string(result)]; } void main () { [int r, string s] = foo(10); writeln(s); writeln(r); } ------------ Walter Bright:
 C got it right and it doesn't need fixing.
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people. Anyway, this is not so important. Named arguments and multiple return values are quite more important (for D3). Bye, bearophile
Jun 01 2010
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 Walter Bright:
 C got it right and it doesn't need fixing.
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people.
Even experts make mistakes.
Jun 01 2010
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/01/2010 03:37 PM, Walter Bright wrote:
 bearophile wrote:
 Walter Bright:
 C got it right and it doesn't need fixing.
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people.
Even experts make mistakes.
With all due respect, I don't think Go's designers are expert language designers. (Let me haste to add that I don't consider myself a language designer, and much less an expert one.) Andrei
Jun 01 2010
parent Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 On 06/01/2010 03:37 PM, Walter Bright wrote:
 bearophile wrote:
 Walter Bright:
 C got it right and it doesn't need fixing.
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people.
Even experts make mistakes.
With all due respect, I don't think Go's designers are expert language designers. (Let me haste to add that I don't consider myself a language designer, and much less an expert one.)
Back to my hackneyed experience at Boeing designing airplanes - even Boeing did not rely on experts not making mistakes. The design process involved independent groups reviewing the designs, and nobody's design was taken for granted. Everything had to be justified with facts, never "trust me, I'm an expert."
Jun 01 2010
prev sibling parent reply BCS <none anon.com> writes:
Hello Walter,

 bearophile wrote:
 
 Walter Bright:
 
 C got it right and it doesn't need fixing.
 
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people.
Even experts make mistakes.
For that matter, how many expert language designers are there in the world? To make that have an answer, I've heard it said that to be an expert you need to have done something consistently (like as a part time job or more) for about 10 years. So Walter's and expert compiler writer and might be an expert language designers sometime next year (assuming IIRC he started designing D in '01). -- ... <IXOYE><
Jun 01 2010
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
BCS wrote:
 For that matter, how many expert language designers are there in the 
 world? To make that have an answer, I've heard it said that to be an 
 expert you need to have done something consistently (like as a part time 
 job or more) for about 10 years. So Walter's and expert compiler writer 
 and might be an expert language designers sometime next year (assuming 
 IIRC he started designing D in '01).
Well, I did design the ABEL language back in the 80's.
Jun 01 2010
parent BCS <none anon.com> writes:
Hello Walter,

 BCS wrote:
 
 For that matter, how many expert language designers are there in the
 world? To make that have an answer, I've heard it said that to be an
 expert you need to have done something consistently (like as a part
 time job or more) for about 10 years. So Walter's and expert compiler
 writer and might be an expert language designers sometime next year
 (assuming IIRC he started designing D in '01).
 
Well, I did design the ABEL language back in the 80's.
?? http://en.wikipedia.org/wiki/Abel_(programming_language) Walter Bright, a.k.a. Walter Hill OTOH: http://en.wikipedia.org/wiki/Advanced_Boolean_Expression_Language -- ... <IXOYE><
Jun 01 2010
prev sibling parent reply Bane <branimir.milosavljevic gmail.com> writes:
BCS Wrote:

 Hello Walter,
 
 bearophile wrote:
 
 Walter Bright:
 
 C got it right and it doesn't need fixing.
 
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people.
Even experts make mistakes.
Even Forest Gump knows 'stupid is who stupid does'.
 
 For that matter, how many expert language designers are there in the world? 
 To make that have an answer, I've heard it said that to be an expert you 
 need to have done something consistently (like as a part time job or more) 
 for about 10 years. So Walter's and expert compiler writer and might be an 
 expert language designers sometime next year (assuming IIRC he started
designing 
 D in '01).
Does this makes me expert for beer consumption ? It was a full time job for me, often during weekend days? Does 10 years of banging your fingers with hammer makes you expert carpenter ? I don't think here on Walther, but on that hilarious definition of 'expert'.
Jun 02 2010
parent BCS <none anon.com> writes:
Hello Bane,

 BCS Wrote:
 
 Hello Walter,
 
 bearophile wrote:
 
 Walter Bright:
 
 C got it right and it doesn't need fixing.
 
I have never programmed in Go, but keep in mind that Go designers are expert language designers and programmers. They aren't stupid people.
Even experts make mistakes.
Even Forest Gump knows 'stupid is who stupid does'.
 For that matter, how many expert language designers are there in the
 world? To make that have an answer, I've heard it said that to be an
 expert you need to have done something consistently (like as a part
 time job or more) for about 10 years. So Walter's and expert compiler
 writer and might be an expert language designers sometime next year
 (assuming IIRC he started designing D in '01).
 
Does this makes me expert for beer consumption ? It was a full time job for me, often during weekend days?
If you did it more than about 20 hr a week, I'd say you may well be.
 Does 10 years of banging your
 fingers with hammer makes you expert carpenter ?
No but it could make you an expert at banging your fingers with hammer
 
 I don't think here on Walther, but on that hilarious definition of
 'expert'.
 
Keep in mind that it's not a definition, but a minimum requirement. -- ... <IXOYE><
Jun 02 2010
prev sibling next sibling parent Lurker <nospam spamfree.net> writes:
== Quote from bearophile (bearophileHUGS lycos.com)'s article
 Lurker:
 Combine the 2 things into one struct and return by value. Multi-value
return makes for hard to comprehend code. So, IMO, it's hardly syntactic sugar: it's syntactic grafitti. "You are very wrong, multiple return values are good, if they have a good enough syntax." Maybe. Or maybe just your personal opinion/preference. Your first example looked ugly to me, but I'll see what you did further here and "decide" for myself if I'd go that far with the "standard C syntax". It does seem like a complete rethinking of the whole function call syntax and behavior and the multiple return concept is just one of many if someone was going to start with a clean slate. Another person may argue that only error codes should be returned from functions and everything else gets passed as arguments: no return values, basically then. Since I'm thinking aloud, I will say that I think the issue in isolation probably can't be effectively dealt with. At least I would approach it from a higher level to see where the suggestion fits-in in the grand scheme of things. Multiple return values make code simpler to write, simpler to read and remove the need for silly and logically ridiculous features like "out" arguments (an input value that is a return? This is making things go backwards)." Or so it would seem "backwards" if you decide to view what's in-between the parens to a called function as "in" args. Which of course they are not, by design. In C, from where much of existing syntax is derived, "reference args" are not hard to grasp. "D language isn't even able to tell if an "out" argument has being used surely worse than multiple return values." The closest I have come to "in" or "out" keywords has been reading of MS "managed code" documentation, so I can't see the value in that nor multiple return values (yet?). I'll probably learn more by lurking in this thread, so don't waste too much of your time responding to me if I'm not "getting it".
 import std.stdio: writeln;
 import std.conv: to;
 int foo(int x, out string s) {
     writeln(s);
     int result = x * x;
     s = to!string(result);
     return result;
 }
 void main () {
     string s;
     writeln(s);
     int r = foo(10, s);
     writeln(r);
 }
 A possible syntax for D multiple return values:
 import std.stdio: writeln;
 import std.conv: to;
 (int, string) foo(int x) {
     int result = x * x;
     return (result, to!string(result));
 }
 void main () {
     (int r, string s) = foo(10);
     writeln(s);
     writeln(r);
 }
Looks too foreign, and like it has too much ramification for parsing (not that I'd know though). This kind of thing seems like something to work out at language design time and not years after language introduction.
 The second is simpler to understand code and less bug-prone than the first.
That's a weak case at best. While D's "in" and "out" modifiers are surely to help the compiler in some way mostly, I don't have any issue with the old way of doing it. It seems more stylistic than anything else.
 An alternative syntax:
 import std.stdio: writeln;
 import std.conv: to;
 [int, string] foo(int x) {
     int result = x * x;
     return [result, to!string(result)];
 }
 void main () {
     [int r, string s] = foo(10);
     writeln(s);
     writeln(r);
 }
I'm not a big fan of overloading parens and brackets yet another way. I think conceptually, multiple return values may be another straw the tips the scale toward D becoming unacceptably cryptic (it'a already very cryptic) rather than useable, especially to those who have never programmed before. Again though, this all sounds like first thoughts on a new programming language rather than an existing one.
 ------------
 Walter Bright:
 C got it right and it doesn't need fixing.
I have never programmed in Go, but keep in mind that Go designers are
expert language designers and programmers. They aren't stupid people.
 Anyway, this is not so important. Named arguments and multiple return
values are quite more important (for D3).
 Bye,
 bearophile
Jun 01 2010
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 D language
 isn't even able to tell if an "out" argument has being used before it is

 uninitialized variables is an error) This is awful and surely worse than
 multiple return values.
That's a misunderstanding of how "out" parameters work in D. All out parameters are default initialized upon entry to the function. Therefore, the user cannot access an uninitialized out parameter.
Jun 01 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:

 bearophile wrote:
 D language
 isn't even able to tell if an "out" argument has being used before it is

 uninitialized variables is an error) This is awful and surely worse than
 multiple return values.
That's a misunderstanding of how "out" parameters work in D. All out parameters are default initialized upon entry to the function. Therefore, the user cannot access an uninitialized out parameter.
I know how out parameters work in D, I've probably written more D1 code than you :-) But a function argument that "comes out" is quite unnatural, it's like washing yourself with a towel and then drying up yourself with a water shower :-) It's better to use multiple return values. Currently in D2 I prefer to return a std.typecons.Tuple instead of using out arguments. Out parameters are initialized at function entry, so in theory all is good and there are no bugs, but this is a *workaround*, a language kludge, a hack, something dirty that is done because of language limitation, or to keep the language compatible with an ancient C design, or because the design is old. Because (as you can see in my example) you can use/read/write an out argument before calling the function (if you write it before function call, such value gets overwritten), or just after the function entry, and such usages while "safe" are not nice. "out arguments" are results, and a result is not meant to be used or read before the call of the function or before you have put act here), but in the case of out arguments this D design decision leads to bad code. Allowing multiple return values in D3 can improve this. Bye, bearophile
Jun 01 2010
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 Walter Bright:
 
 bearophile wrote:
 D language isn't even able to tell if an "out" argument has being used


 and surely worse than multiple return values.
That's a misunderstanding of how "out" parameters work in D. All out parameters are default initialized upon entry to the function. Therefore, the user cannot access an uninitialized out parameter.
Out parameters are initialized at function entry, so in theory all is good and there are no bugs, but this is a *workaround*, a language kludge, a hack, something dirty that is done because of language limitation, or to keep the language compatible with an ancient C design, or because the design is old.
I don't agree. For one thing, C and C++ do not even have out parameters.
Jun 01 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
 Out parameters are initialized at function entry, so in theory all is good
 and there are no bugs, but this is a *workaround*, a language kludge, a hack,
 something dirty that is done because of language limitation, or to keep the
 language compatible with an ancient C design, or because the design is old.
I don't agree. For one thing, C and C++ do not even have out parameters.
In C and C++ you use pointers and & arguments to perform the same thing, in an even less safe way (they don't get initialized). But if you think that "out arguments" aren't something logically backwards, something that looks like a hack that is present just to work around some kind of language/compiler/design/brain limit, then there is something profoundly different in how our brains are designed :-) For me function arguments are something that goes in a function, and the results are something that comes out. In a real language there can be exceptions to this (like ref return values of D2), but I have always assumed out arguments are just a kind of hack done because of some compiler limit, I have never thought of them as something "nice" or safe, or logically good. Bye, bearophile
Jun 01 2010
parent reply Jonathan M Davis <jmdavisProg gmail.com> writes:
bearophile wrote:

 Walter Bright:
 Out parameters are initialized at function entry, so in theory all is
 good and there are no bugs, but this is a *workaround*, a language
 kludge, a hack, something dirty that is done because of language
 limitation, or to keep the language compatible with an ancient C
 design, or because the design is old.
I don't agree. For one thing, C and C++ do not even have out parameters.
In C and C++ you use pointers and & arguments to perform the same thing, in an even less safe way (they don't get initialized). But if you think that "out arguments" aren't something logically backwards, something that looks like a hack that is present just to work around some kind of language/compiler/design/brain limit, then there is something profoundly different in how our brains are designed :-) For me function arguments are something that goes in a function, and the results are something that comes out. In a real language there can be exceptions to this (like ref return values of D2), but I have always assumed out arguments are just a kind of hack done because of some compiler limit, I have never thought of them as something "nice" or safe, or logically good. Bye, bearophile
There are definitely times that I'd like multiple return values. It would be a great feature to have - though doing it with a tuple type or something similar works well enough for the most part. However, there are cases where you really want the function to be returning a single value - particularly when you're feeding the result into an expression - and it's nice to be able to still get other values out of the function with out or ref parameters. Which is better depends in part on how your mind works and in part on what you're actually trying to do. - Jonathan M Davis
Jun 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:
 However, there are cases where you really want the function to be returning 
 a single value - particularly when you're feeding the result into an 
 expression - and it's nice to be able to still get other values out of the 
 function with out or ref parameters.
I have not asked to remove out arguments from D, but they are for special situations only. In normal situations they aren't the best/most tidy way to return more than one item. Bye, bearophile
Jun 01 2010
prev sibling parent BCS <none anon.com> writes:
Hello bearophile,

 Because (as you can see in my
 example) you can use/read/write an out argument before calling the
 function (if you write it before function call, such value gets
 overwritten), or just after the function entry, and such usages while
 "safe" are not nice.
nagging me with regards to initializing variables and can never remember be happy it did so. The best I can say for it was that sometimes, it wasn't annoying. -- ... <IXOYE><
Jun 01 2010
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2010-06-01 21:15, Walter Bright wrote:
 Lurker wrote:
 == Quote from bearophile (bearophileHUGS lycos.com)'s article

 In Go you can omit semicolons at the end of lines, so I presume it's
 not a
terrible thing for C-like languages:
 package main
 import " fmt " // formatted I/O.
 func main() {
 fmt.Printf ("Hello Hello\n")
 }
When will D support that? Removing unnecessary semis really pretties up the code.
This idea reappears every few years, and even gets folded into a language now and then. It started with Pascal, and most recently has appeared in Javascript.
Making parenthesis optional in function calls and semicolons make quite a nice delegate literal syntax: loop { // do something } The above is taken from Scala, it calls the "loop" function passing in a delegate literal. The function will loop indefinitely and call the delegate at each iteration.
 The idea basically sux because of the maintenance issue. What
 maintenance issue? The one where you decide to add a new line of code
 before the }. You inevitably forget to go back and append the ; to the
 previous line. Even if you do happen to remember, now your diff
 visualizer shows 2 lines changed rather than 1.

 C got it right and it doesn't need fixing.

 (There are other good reasons for the ; I outlined in my blog
 http://www.drdobbs.com/blog/archives/2010/05/improving_compi.html )
-- /Jacob Carlborg
Jun 01 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Jacob Carlborg:
 Making parenthesis optional in function calls and semicolons make quite 
 a nice delegate literal syntax:
 
 loop {
 	// do something
 }
It looks also like the Ruby blocks. But D seems designed to work with a simpler back-end in mind, unable to "digest" delegates. Bye, bearophile
Jun 01 2010
next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
On 6/1/10, bearophile <bearophileHUGS lycos.com> wrote:
 It looks also like the Ruby blocks. But D seems designed to work with a
 simpler back-end in mind, unable to "digest" delegates.
But, D can do the given example, only with parens and an semi thrown in. The back end can obviously handle delegates.
Jun 01 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam Ruppe:
 The back end can obviously handle delegates.
I meant that D seems designed to not assume that the back-end is able to inline delegates, and indeed at the moment usually not even LLVM is able to do it (while Scala compiler is able to often perform this optimization, and gives the JavaVM code already optimized in this regard). Bye, bearophile
Jun 01 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 I meant that D seems designed to not assume that the back-end is able to
 inline delegates, and indeed at the moment usually not even LLVM is able to
 do it (while Scala compiler is able to often perform this optimization, and
 gives the JavaVM code already optimized in this regard).
D does inlining entirely in the front end.
Jun 01 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:

 bearophile wrote:
 I meant that D seems designed to not assume that the back-end is able to
 inline delegates, and indeed at the moment usually not even LLVM is able to
 do it (while Scala compiler is able to often perform this optimization, and
 gives the JavaVM code already optimized in this regard).
D does inlining entirely in the front end.
I think LDC has totally disabled the inlining of the front-end and uses just the LLVM inliner, because despite it unfortunately has less semantics to work with, it gives better results anyway. Bye, bearophile
Jun 01 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 Walter Bright:
 
 bearophile wrote:
 I meant that D seems designed to not assume that the back-end is able to 
 inline delegates, and indeed at the moment usually not even LLVM is able
 to do it (while Scala compiler is able to often perform this
 optimization, and gives the JavaVM code already optimized in this
 regard).
D does inlining entirely in the front end.
I think LDC has totally disabled the inlining of the front-end and uses just the LLVM inliner, because despite it unfortunately has less semantics to work with, it gives better results anyway.
Firstly, this is not a back end vs front end issue. A compiler can do it in either place, neither is inherently better than the other. Secondly, in what way does LLVM give better inline results?
Jun 01 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:

Firstly, this is not a back end vs front end issue. A compiler can do it in
either place, neither is inherently better than the other.< You are right. This thread has gone in wrong directions. What I meant was: Scala language is designed to use delegates often. For example the map maps a delegate on a collection, it never uses a string as Phobos2 map(). Scala compiler keeps its language efficent, despite all those delegates, because it contains a "large" amount of logic (separated from the large amount of optimization logic in the JavaVM itself) that allows it to often inline those delegates. LLVM developers have started to work on this problem too, and maybe eventually LLVM too (so LDC too) will enjoy some of such optimizations. The end result is that if you map a delegate on a Scala collection, it often gets inlined and this improves performance, while D LDC currently doesn't.
Secondly, in what way does LLVM give better inline results?<
I am not a LLVM/LDC designer, and in the end I am pretty ignorant about compiler still. Until few days ago DMD didn't inline functions with ref arguments, while the inliner of llvm didn't have this limit, so this is place where LLVM was better. I'd like to give you more examples or a more detailed explanation, but I can't (maybe in D bugzilla there are more examples where the inliner fails, I don't know). Maybe LDC developers can give you a better answer. I find it funny that LDC devs seem to never talk about LDC here, I am not expert enough to talk about LDC, yet it seems no one else that knows more than me is talking about it here :-) Bye, bearophile
Jun 01 2010
parent reply Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 Walter Bright:
 
 Firstly, this is not a back end vs front end issue. A compiler can do it in
 
either place, neither is inherently better than the other.< You are right. This thread has gone in wrong directions. What I meant was: Scala language is designed to use delegates often. For example the map maps a delegate on a collection, it never uses a string as Phobos2 map(). Scala compiler keeps its language efficent, despite all those delegates, because it contains a "large" amount of logic (separated from the large amount of optimization logic in the JavaVM itself) that allows it to often inline those delegates. LLVM developers have started to work on this problem too, and maybe eventually LLVM too (so LDC too) will enjoy some of such optimizations. The end result is that if you map a delegate on a Scala collection, it often gets inlined and this improves performance, while D LDC currently doesn't.
dmd inlines delegates to templates when they are passed as alias parameters.
 Secondly, in what way does LLVM give better inline results?<
I am not a LLVM/LDC designer, and in the end I am pretty ignorant about compiler still. Until few days ago DMD didn't inline functions with ref arguments, while the inliner of llvm didn't have this limit, so this is place where LLVM was better. I'd like to give you more examples or a more detailed explanation, but I can't (maybe in D bugzilla there are more examples where the inliner fails, I don't know). Maybe LDC developers can give you a better answer. I find it funny that LDC devs seem to never talk about LDC here, I am not expert enough to talk about LDC, yet it seems no one else that knows more than me is talking about it here :-)
I know you're a fan of LLVM, but it would be fair to provide examples when saying things like LLVM does a better job on X. I would agree that LLVM does a far better job of marketing. For example, many years ago, Microsoft came out with "incremental linking" as a cool new feature to speed up the link process. This got a lot of buzz in the press. My manager at the time decided we need an "incremental linking" feature in order to catch up to Microsoft. A big all-hands meeting ensued. The thing is, "incremental linking" was a hack that was necessary to work around a very slow linker. Our linker (optlink) was so fast that it ran rings around "incremental linking" even while always doing a full link. We'd failed to get this message out, even to our own management.
Jun 01 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:

dmd inlines delegates to templates when they are passed as alias parameters.<
A functional language (Scala is partially a functional language) uses functions everywhere, so inlining of closures is a desired optimization feature.
I know you're a fan of LLVM,<
With some work LLVM can be used to JIT-compile the D compile-time functions, so they can probably run quite faster. With some more work you can also keep some parts of LLVM around at runtime, to Eventually with more work you can even perform some "lifetime" optimizations, as HotSpot does: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=18420
but it would be fair to provide examples when saying things like LLVM does a
better job on X.<
You are right, I am sorry. You can ask LDC developers why they have preferred the LLVM inliner instead of the D front-end one. Later I can ask to them. Bye, bearophile
Jun 01 2010
parent reply Robert Clipsham <robert octarineparrot.com> writes:
On 02/06/10 00:45, bearophile wrote:
 With some work LLVM can be used to JIT-compile the D compile-time
 functions, so they can probably run quite faster.
This may be true, but the overhead of loading/setting up a JIT environment at compile time will have a horrific effect on compile time for most D apps, it will only show an advantage where there's a lot of CTFE used. Add to this it needs a complete rewrite of how CTFE is done, it's more effort than it's worth... It would be far better to fix the killer CTFE bugs that exist at the moment such as the extremely large memory usage - once that's done CTFE will be a lot faster anyway (though again, this is no small task).
 With some more work you can also keep some parts of LLVM around at

I seem to recall the benefit of runtime optimisation isn't that great, have you got some evidence that shows otherwise?
 You are right, I am sorry. You can ask LDC developers why they have
 preferred the LLVM inliner instead of the D front-end one. Later I
 can ask to them.
If I recall, the issue was dmd inlined away information LDC needed to be able to create binaries of any use, I may be wrong here.
 Bye, bearophile
Jun 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Robert Clipsham:

This may be true, but the overhead of loading/setting up a JIT environment at
compile time will have a horrific effect on compile time for most D apps, it
will only show an advantage where there's a lot of CTFE used.<
A JIT that is not trash is able to start only when it is useful, that is when it is able to reduce the total running time, that is the compile time. I have seen that the Lua JIT 2.0a4 usually starts and does its work in tiny fractions of a second. The JIT based on LLVM is probably quite slower than the fabolous Lua JIT, but you can make it start only on CTFE that require more than 0.1 or 0.5 seconds to run (in practice you use the number of times a function gets called, etc).
Add to this it needs a complete rewrite of how CTFE is done,<
Eventually this can be a good thing. It's the LLVM JIT/garbage collector that does lot of the work.
 With some more work you can also keep some parts of LLVM around at

 I seem to recall the benefit of runtime optimisation isn't that great,
 have you got some evidence that shows otherwise?
I think you have misquoted my post a bit: keeping the compiler as a library that can be used at runtime from normal D code is useful for example to implement an eval() that is able to compile functions or instantiate templates at runtime, to implement a shell that's able to run D commands interactively, to implement Lisp-style run-time macros, and so on and on. While keeping the compiler at runtime beside the program is something different, this isn't a compiler library that is meant to be used from D code, it's used by the runtime to perform optimizations and more. Runtime optimisation is very important (or even essential) if you want to perform good inlining of virtual functions (and probably delegates too), it's better than regular profile-guided optimization because you have real usage data while the program runs. Today Java code is sometimes even faster than C++ code just because of HotSpot, that performs optmizations at run-time. If you try to optimize Java code at compile-time you will probably not reach similar performance levels. So the benefits of runtime optimisation are great. If D will have success, in some years this will probably become the future of D compilation. As they say JIT compilers "have won". Bye, bearophile
Jun 01 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/01/2010 06:09 PM, Walter Bright wrote:
 For example, many years ago, Microsoft came out with "incremental
 linking" as a cool new feature to speed up the link process. This got a
 lot of buzz in the press. My manager at the time decided we need an
 "incremental linking" feature in order to catch up to Microsoft. A big
 all-hands meeting ensued. The thing is, "incremental linking" was a hack
 that was necessary to work around a very slow linker. Our linker
 (optlink) was so fast that it ran rings around "incremental linking"
 even while always doing a full link. We'd failed to get this message
 out, even to our own management.
Sounds a lot like us failing to get the non-null references message out to you :o). Andrei
Jun 01 2010
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2010-06-01 22:27, Adam Ruppe wrote:
 On 6/1/10, bearophile<bearophileHUGS lycos.com>  wrote:
 It looks also like the Ruby blocks. But D seems designed to work with a
 simpler back-end in mind, unable to "digest" delegates.
But, D can do the given example, only with parens and an semi thrown in. The back end can obviously handle delegates.
Yes of course, that's the thing, you have to have the parenthesis and semicolons. If you don't, you can have a nicer syntax and you can create functions that looks like built in language constructs: loop (int i) { println(i) } Or: [1, 5, 3, 5].each (int i) { println(i) } -- /Jacob Carlborg
Jun 02 2010
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:hu3pu5$310o$1 digitalmars.com...
 Jacob Carlborg:
 Making parenthesis optional in function calls and semicolons make quite
 a nice delegate literal syntax:

 loop {
 // do something
 }
It looks also like the Ruby blocks. But D seems designed to work with a simpler back-end in mind, unable to "digest" delegates.
I've done a little bit of Ruby (writing/maintaining some rakefiles). This sort of thing seems like a neat idea, but in practice I found it to be error-prone (ambiguities) and made it a lot harder to visually parse code. I constantly found myself having to "imagine" the omitted syntax, which just made the whole feature a wash. ------------------------------- Not sent from an iPhone.
Jun 01 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I would argue that there will be more people coming to D from languages such as
C and C++, versus Python or similar languages that don't use semicolons as
statement terminators.

And many of them will still use C/C++ because they still have to maintain some
projects written in those languages. If D had no semicolons, it would add
confusion when a person would swap from a D project to a C project and
vice-versa.

I think it's better to keep semicolons, at least for the sake of adoption.
Jun 01 2010
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
bearophile Wrote:

 In Go you can omit semicolons at the end of lines, so I presume it's not a
terrible thing for C-like languages:
 
 In Go you can omit some () for example in "if":
 
Do you like to have more than one way to do the same thing and mix them randomly?
Jun 03 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Kagamin:

 bearophile:
 
 In Go you can omit semicolons at the end of lines, so I presume it's not a
terrible thing for C-like languages:
 
 In Go you can omit some () for example in "if":
 
Do you like to have more than one way to do the same thing and mix them randomly?
I don't. In that summary about the Go document I have listed both feature I'd like to have in D3 (named arguments and multiple return values), and various other things present in Go that I am not interested in or I can live without. Sorry for the confusion, I have to state more clearly what I desire and what I am not interested in at the top of such posts of mine :-) For example, I prefer to avoid final semicolons if possible, but I have seen languages (like JavaScript) where this feature has led to a situation worse than the original C/Pascal situation, so I am not interested. Bye, bearophile
Jun 03 2010
parent Justin Johansson <no spam.com> writes:
bearophile wrote:
 Kagamin:
 
 bearophile:

 In Go you can omit semicolons at the end of lines, so I presume it's not a
terrible thing for C-like languages:

 In Go you can omit some () for example in "if":
Do you like to have more than one way to do the same thing and mix them randomly?
I don't. In that summary about the Go document I have listed both feature I'd like to have in D3 (named arguments and multiple return values), and various other things present in Go that I am not interested in or I can live without. Sorry for the confusion, I have to state more clearly what I desire and what I am not interested in at the top of such posts of mine :-) For example, I prefer to avoid final semicolons if possible, but I have seen languages (like JavaScript) where this feature has led to a situation worse than the original C/Pascal situation, so I am not interested. Bye, bearophile
Ah, so you are a separatist rather than a finalist! Are you left-recursive also? :-) Cheers Justin
Jun 03 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
I have tested dmd v2.047beta and it works. I have seen this bug fix improves
the performance of my code:
http://d.puremagic.com/issues/show_bug.cgi?id=2008

------------------

Walter Bright:

it would be fair to provide examples when saying things like LLVM does a better
job on X.<
This is a D2 program, I compile it with v2.047beta, the total() function doesn't get inlined: import std.c.stdio: printf; int total(int[] data) { int res; foreach (x; data) res += x; return res; } void main() { enum int[] data = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]; printf("%d\n", total(data)); } asm generated by DMD, -O -release -inline (cleaned up a little): _D4test5totalFAiZi comdat push EAX xor ECX,ECX xor EDX,EDX push EBX cmp 0Ch[ESP],ECX je L28 mov 4[ESP],EDX mov EDX,010h[ESP] mov EBX,EDX mov EAX,0Ch[ESP] mov EDX,4[ESP] L1E: add ECX,[EDX*4][EBX] inc EDX cmp EDX,0Ch[ESP] jb L1E L28: pop EBX mov EAX,ECX pop ECX ret 8 __Dmain comdat L0: push EAX push EAX mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ push EBX push 0 push 2 push 1 push 3 push 4 push 8 push 9 push 5 push 6 push 7 push 0Ah push EAX call near ptr __d_arrayliteralT add ESP,030h mov ECX,EAX push ECX mov EBX,0Ah push EBX call near ptr _D4test5totalFAiZi mov EDX,offset FLAT:_DATA push EAX push EDX call near ptr _printf add ESP,8 xor EAX,EAX pop EBX add ESP,8 ret ------------------ This is the same program translated to D1 for Tango: import tango.stdc.stdio: printf; int total(int[] data) { int res; foreach (x; data) res += x; return res; } void main() { const int[] data = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]; printf("%d\n", total(data)); } The asm generated by LDC, -O3 -release -inline: _D4temp5totalFAiZi: pushl %esi movl 8(%esp), %ecx testl %ecx, %ecx je .LBB1_4 movl 12(%esp), %edx xorl %eax, %eax movl %eax, %esi .align 16 .LBB1_2: addl (%edx,%esi,4), %eax incl %esi cmpl %ecx, %esi jne .LBB1_2 .LBB1_3: popl %esi ret $8 .LBB1_4: xorl %eax, %eax jmp .LBB1_3 .type .constarray, object .data .align 16 .constarray: .long 7 .long 6 .long 5 .long 9 .long 8 .long 4 .long 3 .long 1 .long 2 .zero 4 .size .constarray, 40 _Dmain: subl $12, %esp movl .constarray+4, %eax addl .constarray, %eax addl .constarray+8, %eax addl .constarray+12, %eax addl .constarray+16, %eax addl .constarray+20, %eax addl .constarray+24, %eax addl .constarray+28, %eax addl .constarray+32, %eax addl .constarray+36, %eax movl %eax, 4(%esp) movl $.str, (%esp) call printf xorl %eax, %eax addl $12, %esp ret $8 You can see ldc inlined total(), and in this case unrolls the loop too because the array is known at compile time. But it doesn't perform the last optimization. --------------------------- If I use the Link-Time optimization with LDC it optimizes the code better, this is the disassembly of the main: 08049620 <_Dmain>: 8049620: 83 ec 0c sub $0xc,%esp 8049623: c7 44 24 04 2d 00 00 movl $0x2d,0x4(%esp) 804962a: 00 804962b: c7 04 24 48 35 06 08 movl $0x8063548,(%esp) 8049632: e8 85 fd ff ff call 80493bc <printf plt> 8049637: 31 c0 xor %eax,%eax 8049639: 83 c4 0c add $0xc,%esp 804963c: c2 08 00 ret $0x8 804963f: 90 nop That movl $0x2d,0x4(%esp) is the result, 45 in base 10, fully computed. Bye, bearophile
Jun 08 2010