digitalmars.D - We need to kill C syntax for declaring function types
- Don (28/28) Oct 04 2010 A great example of how C syntax is hurting us.
- bearophile (18/24) Oct 04 2010 Don:
- Don (11/44) Oct 04 2010 Yes, I included that in the patch as well. It makes them deprecated, so
- bearophile (6/8) Oct 04 2010 It seems this little patch of yours fixes something like 4 different bug...
- Jesse Phillips (2/15) Oct 04 2010 I still think it is important to resolve bugs related to C syntax, if yo...
- bearophile (4/5) Oct 04 2010 Keep in mind that so far the main purpose of the -d in DMD2 was (I think...
- Jesse Phillips (2/10) Oct 04 2010 Yes, and I think that if the code still exists and can be compiled then ...
- Don (2/13) Oct 04 2010 Don't worry, that happens.
- Steven Schveighoffer (17/36) Oct 04 2010 I'm really confused here. I could have sworn I've seen compile time
- Don (8/54) Oct 04 2010 I agree, I use it for the same thing. In the patch, I made C-style
- Steven Schveighoffer (3/13) Oct 04 2010 Perfect solution, thanks!
- BCS (5/62) Oct 04 2010 I.e. the use of C-style function pointer syntax is deprecated, the synta...
- Marianne Gagnon (3/15) Oct 04 2010 I don't have much weight, but... seconded, definitely :) D needs to be a...
- Andrei Alexandrescu (4/19) Oct 04 2010 Don's post was quoted on reddit:
- Lars T. Kyllingstad (4/12) Oct 05 2010 http://dsource.org/projects/dmd/changeset/703
- Walter Bright (2/5) Oct 05 2010 Don, as usual, made a compelling case.
- Bruno Medeiros (4/9) Oct 26 2010 Programs going down in flames is always a compelling argument... ^_^'
- Bruno Medeiros (18/39) Oct 26 2010 Whoa. I considered myself completely knowledgeable of the C language,
A great example of how C syntax is hurting us. --- I found this bit of code in std.container, inside BinaryHeap: size_t insert(ElementType!Store value) { static if (is(_store.insertBack(value))) { ... } else ... What does the static if do? It's *intended* to check if _store has a member function insertBack(), which accepts type of a 'value'. But instead, it ALWAYS silently does the 'else' clause. Unless _store.insertBack is a valid *type*, (eg, alias int insertBack;). In which case it gives an error "declaration value is already defined". Why? This happens because x(y); is valid C syntax for declaring a type 'y', such that &y is of type 'x function()'. The C syntax is unspeakably ridiculous, useless, and downright dangerous. It shouldn't compile. In the past, Walter has mentioned a weak argument for retaining C-style array declaration syntax, although I personally find it very unconvincing. But C's hideous function pointer syntax is on a whole other level. It's really hurting us. I believe it should be deprecated immediately. But the 'function type' syntax shouldn't be allowed even as a deprecated syntax. It's horrible. Patch included in Bug 4987.
Oct 04 2010
Don: Thank you for bringing up this topic, Don :-) In D, beside the C syntax for function types, there also is the C syntax for function pointers. I presume it gives less problems than the first one. See also: http://d.puremagic.com/issues/show_bug.cgi?id=4530In the past, Walter has mentioned a weak argument for retaining C-style array declaration syntax, although I personally find it very unconvincing. But C's hideous function pointer syntax is on a whole other level. It's really hurting us. I believe it should be deprecated immediately. But the 'function type' syntax shouldn't be allowed even as a deprecated syntax. It's horrible.One of the faults of C++, that increases its useless complexity a lot, is to have in many cases two ways (the C way and the C++ way) to do something. Generally the idea of duplicated syntax is bad. But I have translated lot of C code to D1 and I've seen that the possibility that D1 gives me to leave matrix definitions as they are helps me reduce the amount of changes to the C code needed to perform the translation (and I think this may help avoid some translation bugs, but I have no proof of this). So I leave declarations like: int mat[5][16]; And only later, when the D1 programs works correctly, I replace them by code like: int[16][5] mat; To merge such two needs, I have suggested a compilation switch, it may be named "-cstyle". It's designed to help translation of C code to D. If a module is compiled with -cstyle then DMD accepts C-style array declarations and C-style functions pointers, and it also gives warnings against passing by value large fixed-sized arrays and against the usage of global floating floating values before their initialization (those are two things that may trip a person that translates C code to D, because D passes fixed-sized arrays by value and doesn't initialize global floats to 0 but to NaN). The idea is, when you need to translate C code to D you use the -cstyle switch, that allows some C syntax and gives those two extra warnings. When your code works, you may finish the translation to D and stop using the -cstyle switch. See: http://d.puremagic.com/issues/show_bug.cgi?id=4580 What kind of error message does your patch gives for 4962? Bye, bearophile
Oct 04 2010
bearophile wrote:Don: Thank you for bringing up this topic, Don :-) In D, beside the C syntax for function types, there also is the C syntax for function pointers. I presume it gives less problems than the first one.Yes, I included that in the patch as well. It makes them deprecated, so they compile if and only if the -d command line switch is used.See also: http://d.puremagic.com/issues/show_bug.cgi?id=4530bug.d(6): function declaration without return type. (Note that constructors are always named 'this') That is, it doesn't work out if it was intended to be a constructor, it gives the same error message for any function with no return type. Making a dedicated error message for constructors would require longer-range changes to the parser. But I believe that that the C++/Java/C# constructor syntax is by far the most common syntax where it will happen.In the past, Walter has mentioned a weak argument for retaining C-style array declaration syntax, although I personally find it very unconvincing. But C's hideous function pointer syntax is on a whole other level. It's really hurting us. I believe it should be deprecated immediately. But the 'function type' syntax shouldn't be allowed even as a deprecated syntax. It's horrible.One of the faults of C++, that increases its useless complexity a lot, is to have in many cases two ways (the C way and the C++ way) to do something. Generally the idea of duplicated syntax is bad. But I have translated lot of C code to D1 and I've seen that the possibility that D1 gives me to leave matrix definitions as they are helps me reduce the amount of changes to the C code needed to perform the translation (and I think this may help avoid some translation bugs, but I have no proof of this). So I leave declarations like: int mat[5][16]; And only later, when the D1 programs works correctly, I replace them by code like: int[16][5] mat; To merge such two needs, I have suggested a compilation switch, it may be named "-cstyle". It's designed to help translation of C code to D. If a module is compiled with -cstyle then DMD accepts C-style array declarations and C-style functions pointers, and it also gives warnings against passing by value large fixed-sized arrays and against the usage of global floating floating values before their initialization (those are two things that may trip a person that translates C code to D, because D passes fixed-sized arrays by value and doesn't initialize global floats to 0 but to NaN). The idea is, when you need to translate C code to D you use the -cstyle switch, that allows some C syntax and gives those two extra warnings. When your code works, you may finish the translation to D and stop using the -cstyle switch. See: http://d.puremagic.com/issues/show_bug.cgi?id=4580 What kind of error message does your patch gives for 4962?
Oct 04 2010
Don:That is, it doesn't work out if it was intended to be a constructor, it gives the same error message for any function with no return type.It seems this little patch of yours fixes something like 4 different bug reports present in Bugzilla :-) I suggest to add to the D docs a note that lists all the purposes of the -d command line switch, including accepting C function pointers. So the -cstyle command line switch may be replaced by the -d. Regarding bug 4580, is it possible to use the -d switch to deprecate (and re-enable when it is used) C-style array declarations too? (Bug 4580 talks about two extra warnings too, they too may be tied to the -d switch, but they are less important). Bye and thank you, bearophile
Oct 04 2010
bearophile Wrote:Don:I still think it is important to resolve bugs related to C syntax, if you can still compile it. Is any tested done against deprecated features? While they shouldn't be used, it should still be checked that they work while they exist.That is, it doesn't work out if it was intended to be a constructor, it gives the same error message for any function with no return type.It seems this little patch of yours fixes something like 4 different bug reports present in Bugzilla :-) I suggest to add to the D docs a note that lists all the purposes of the -d command line switch, including accepting C function pointers. So the -cstyle command line switch may be replaced by the -d. Regarding bug 4580, is it possible to use the -d switch to deprecate (and re-enable when it is used) C-style array declarations too? (Bug 4580 talks about two extra warnings too, they too may be tied to the -d switch, but they are less important). Bye and thank you, bearophile
Oct 04 2010
Jesse Phillips:Is any tested done against deprecated features?Keep in mind that so far the main purpose of the -d in DMD2 was (I think) to enable Phobos code marked with "deprecated". Bye, bearophile
Oct 04 2010
bearophile Wrote:Jesse Phillips:Yes, and I think that if the code still exists and can be compiled then it should still be tested. I would agree that adding tests, or fixing bugs, isn't really a good idea, but it would be a good idea to keep existing tests and test with the -d option (that is new functionality isn't broken with -d enabled either).Is any tested done against deprecated features?Keep in mind that so far the main purpose of the -d in DMD2 was (I think) to enable Phobos code marked with "deprecated". Bye, bearophile
Oct 04 2010
Jesse Phillips wrote:bearophile Wrote:Don't worry, that happens.Jesse Phillips:Yes, and I think that if the code still exists and can be compiled then it should still be tested. I would agree that adding tests, or fixing bugs, isn't really a good idea, but it would be a good idea to keep existing tests and test with the -d option (that is new functionality isn't broken with -d enabled either).Is any tested done against deprecated features?Keep in mind that so far the main purpose of the -d in DMD2 was (I think) to enable Phobos code marked with "deprecated". Bye, bearophile
Oct 04 2010
On Mon, 04 Oct 2010 05:07:07 -0400, Don <nospam nospam.com> wrote:A great example of how C syntax is hurting us. --- I found this bit of code in std.container, inside BinaryHeap: size_t insert(ElementType!Store value) { static if (is(_store.insertBack(value))) { ... } else ... What does the static if do? It's *intended* to check if _store has a member function insertBack(), which accepts type of a 'value'. But instead, it ALWAYS silently does the 'else' clause. Unless _store.insertBack is a valid *type*, (eg, alias int insertBack;). In which case it gives an error "declaration value is already defined".I'm really confused here. I could have sworn I've seen compile time checks like this everywhere. Is the "bug" that's unflagged by the compiler that you are missing a typeof(...)?Why? This happens because x(y); is valid C syntax for declaring a type 'y', such that &y is of type 'x function()'.Wait, I thought when declaring a function pointer, you had to have the (*) in there? Plus I thought you had to have an extra set of parentheses? I've never seen this before. Trying... Oh, that's freaking awful. x(y); silently compiles into something useless, you need to declare it with a typedef in order to use it (and even then, it's horrible). It's like accepting the line int; Yes, 100% agree, get rid of this. Does that mean we need to get rid of C-style function pointer declarations? Because I recently saw a use for them (deciphering C-style function pointer syntax). Even if that has to go, I'm fine with it. -Steve
Oct 04 2010
Steven Schveighoffer wrote:On Mon, 04 Oct 2010 05:07:07 -0400, Don <nospam nospam.com> wrote:Yes.A great example of how C syntax is hurting us. --- I found this bit of code in std.container, inside BinaryHeap: size_t insert(ElementType!Store value) { static if (is(_store.insertBack(value))) { ... } else ... What does the static if do? It's *intended* to check if _store has a member function insertBack(), which accepts type of a 'value'. But instead, it ALWAYS silently does the 'else' clause. Unless _store.insertBack is a valid *type*, (eg, alias int insertBack;). In which case it gives an error "declaration value is already defined".I'm really confused here. I could have sworn I've seen compile time checks like this everywhere. Is the "bug" that's unflagged by the compiler that you are missing a typeof(...)?I agree, I use it for the same thing. In the patch, I made C-style function pointers deprecated (so you can still compile it with the -d switch) and C-style abominable x(y) types illegal. I would expect that it always remains a deprecated syntax, to aid conversion of C-style code. But in my experience, you always want to get rid of them eventually.Why? This happens because x(y); is valid C syntax for declaring a type 'y', such that &y is of type 'x function()'.Wait, I thought when declaring a function pointer, you had to have the (*) in there? Plus I thought you had to have an extra set of parentheses? I've never seen this before. Trying... Oh, that's freaking awful. x(y); silently compiles into something useless, you need to declare it with a typedef in order to use it (and even then, it's horrible). It's like accepting the line int; Yes, 100% agree, get rid of this. Does that mean we need to get rid of C-style function pointer declarations? Because I recently saw a use for them (deciphering C-style function pointer syntax).
Oct 04 2010
On Mon, 04 Oct 2010 08:55:55 -0400, Don <nospam nospam.com> wrote:Steven Schveighoffer wrote:Perfect solution, thanks! -SteveYes, 100% agree, get rid of this. Does that mean we need to get rid of C-style function pointer declarations? Because I recently saw a use for them (deciphering C-style function pointer syntax).I agree, I use it for the same thing. In the patch, I made C-style function pointers deprecated (so you can still compile it with the -d switch) and C-style abominable x(y) types illegal. I would expect that it always remains a deprecated syntax, to aid conversion of C-style code. But in my experience, you always want to get rid of them eventually.
Oct 04 2010
Hello Don,Steven Schveighoffer wrote:I.e. the use of C-style function pointer syntax is deprecated, the syntax it self is not. Got it, nice. -- ... <IXOYE><On Mon, 04 Oct 2010 05:07:07 -0400, Don <nospam nospam.com> wrote:Yes.A great example of how C syntax is hurting us. --- I found this bit of code in std.container, inside BinaryHeap: size_t insert(ElementType!Store value) { static if (is(_store.insertBack(value))) { ... } else ... What does the static if do? It's *intended* to check if _store has a member function insertBack(), which accepts type of a 'value'. But instead, it ALWAYS silently does the 'else' clause. Unless _store.insertBack is a valid *type*, (eg, alias int insertBack;). In which case it gives an error "declaration value is already defined".I'm really confused here. I could have sworn I've seen compile time checks like this everywhere. Is the "bug" that's unflagged by the compiler that you are missing a typeof(...)?I agree, I use it for the same thing. In the patch, I made C-style function pointers deprecated (so you can still compile it with the -d switch) and C-style abominable x(y) types illegal. I would expect that it always remains a deprecated syntax, to aid conversion of C-style code. But in my experience, you always want to get rid of them eventually.Why? This happens because x(y); is valid C syntax for declaring a type 'y', such that &y is of type 'x function()'.Wait, I thought when declaring a function pointer, you had to have the (*) in there? Plus I thought you had to have an extra set of parentheses? I've never seen this before. Trying... Oh, that's freaking awful. x(y); silently compiles into something useless, you need to declare it with a typedef in order to use it (and even then, it's horrible). It's like accepting the line int; Yes, 100% agree, get rid of this. Does that mean we need to get rid of C-style function pointer declarations? Because I recently saw a use for them (deciphering C-style function pointer syntax).
Oct 04 2010
Hi,The C syntax is unspeakably ridiculous, useless, and downright dangerous. It shouldn't compile. In the past, Walter has mentioned a weak argument for retaining C-style array declaration syntax, although I personally find it very unconvincing. But C's hideous function pointer syntax is on a whole other level. It's really hurting us. I believe it should be deprecated immediately. But the 'function type' syntax shouldn't be allowed even as a deprecated syntax. It's horrible. Patch included in Bug 4987.I don't have much weight, but... seconded, definitely :) D needs to be as clean as possible, bad C syntax needs to go. -- Auria
Oct 04 2010
On 10/4/10 10:06 CDT, Marianne Gagnon wrote:Hi,Don's post was quoted on reddit: http://www.reddit.com/r/programming/comments/dm8n8/the_many_faces_of_d_slides_pdf/ AndreiThe C syntax is unspeakably ridiculous, useless, and downright dangerous. It shouldn't compile. In the past, Walter has mentioned a weak argument for retaining C-style array declaration syntax, although I personally find it very unconvincing. But C's hideous function pointer syntax is on a whole other level. It's really hurting us. I believe it should be deprecated immediately. But the 'function type' syntax shouldn't be allowed even as a deprecated syntax. It's horrible. Patch included in Bug 4987.I don't have much weight, but... seconded, definitely :) D needs to be as clean as possible, bad C syntax needs to go. -- Auria
Oct 04 2010
On Mon, 04 Oct 2010 11:07:07 +0200, Don wrote:[...] The C syntax is unspeakably ridiculous, useless, and downright dangerous. It shouldn't compile. [...] Patch included in Bug 4987.http://dsource.org/projects/dmd/changeset/703 :) -Lars
Oct 05 2010
Lars T. Kyllingstad wrote:http://dsource.org/projects/dmd/changeset/703 :)Don, as usual, made a compelling case.
Oct 05 2010
On 05/10/2010 10:50, Walter Bright wrote:Lars T. Kyllingstad wrote:Programs going down in flames is always a compelling argument... ^_^' -- Bruno Medeiros - Software Engineerhttp://dsource.org/projects/dmd/changeset/703 :)Don, as usual, made a compelling case.
Oct 26 2010
On 04/10/2010 10:07, Don wrote:A great example of how C syntax is hurting us. --- I found this bit of code in std.container, inside BinaryHeap: size_t insert(ElementType!Store value) { static if (is(_store.insertBack(value))) { ... } else ... What does the static if do? It's *intended* to check if _store has a member function insertBack(), which accepts type of a 'value'. But instead, it ALWAYS silently does the 'else' clause. Unless _store.insertBack is a valid *type*, (eg, alias int insertBack;). In which case it gives an error "declaration value is already defined". Why? This happens because x(y); is valid C syntax for declaring a type 'y', such that &y is of type 'x function()'. The C syntax is unspeakably ridiculous, useless, and downright dangerous. It shouldn't compile.Whoa. I considered myself completely knowledgeable of the C language, but I had no idea about this syntax. (Note: by "completely knowledgeable" I don't mean I could recite the spec by memory, but rather that at least I knew what features, syntax and semantics ANSI C 89 had available.) Hum, your description of what "x(y);" means seems slightly incorrect though. Both in C and D, if x is a type, then it is the same as "x y;", that is, it declares a variable y with type x. If x is not a type but y is, it seems to be the same as "void x(y);", that is, it declares a function prototype named x. If both are not types, then it declares that strange thing I don't quite understand nor am I interested to... I do vaguely recall learning about the first scenario, where a variable is declared, but I had not idea about the others. Is this mentioned in K&R TCPL 2nd edition? Not that it matters, it's still horrid! I'm glad we're nuking it from D. -- Bruno Medeiros - Software Engineer
Oct 26 2010