FPGARelated.com
Forums

Which to learn: Verilog vs. VHDL?

Started by Michael April 14, 2008
On Thu, 03 Jan 2013 17:27:14 +0000, glen herrmannsfeldt wrote:

> But VHDL seems to be verbose, especially in its declarations, in ways > that both C and verilog are not. > > Both C and verilog use &, |, and ^ for and, or, and xor operators. Maybe > VHDL does, too.
...
> As well as I remember them, the VHDL operators are somewhat different, > and not easy for C programmers to remember.
Not so easy? When you wanted to communicate the meaning of &, |, ^ above, I see you called them and, or, xor. Well, so does VHDL. I find it a whole lot easier to read. And sufficiently more powerful that if you learn to use it (e.g. the type system) instead of fighting it, you can do things a lot more concisely. Using records for ports and hierarchical signals, for example, rather than passing lots of wires around. Not that you could tell that concise VHDL was possible from any of the tutorial examples floating around, let alone an FPGA vendor's own code... - Brian
On Thu, 03 Jan 2013 11:42:29 -0600, Tim Wescott wrote:

> On Thu, 03 Jan 2013 17:27:14 +0000, glen herrmannsfeldt wrote:
> I have to admit, the biggest problem that I have as a C++ programmer > when writing in either VHDL or Verilog is envy: in both (IIRC) VHDL or > Verilog, > when you have a module with a bazzilion input and output signals, you > can invoke it with a syntax something like > > module_name(module_signal_name = local_signal_name, ...) > > In C++, when, for reasons of utility, you are forced to design a class > whose constructor has a bazzilion inputs, you have to hold your breath, > close your eyes, cross your fingers, and hope that whoever uses that > constructor call gets all the right things in all the right places: I'd > Much Rather be able to invoke the syntax above and have it all self- > document.
You mean named association? If you want the option of named association in your object oriented software, that's easy : take a look at Ada-2005 (or now, Ada-2012). It gives you a lot of other good stuff too - including a remarkably sane object-oriented programming model (where everything ISN'T a pointer), and spookily accurate reports from runtime faults that would just say "segfault" in a C++ program. The one positive thing C++ has given us: you can't say Ada is too complex any more! - Brian.
Tim Wescott wrote:

> I have to admit, the biggest problem that I have as a C++ programmer when > writing in either VHDL or Verilog is envy: in both (IIRC) VHDL or Verilog, > when you have a module with a bazzilion input and output signals, you can > invoke it with a syntax something like > > module_name(module_signal_name = local_signal_name, ...) > > In C++, when, for reasons of utility, you are forced to design a class > whose constructor has a bazzilion inputs, you have to hold your breath, > close your eyes, cross your fingers, and hope that whoever uses that > constructor call gets all the right things in all the right places: I'd > Much Rather be able to invoke the syntax above and have it all self- > document.
There's no need to hold your breath. You can still do that, and more, with C++, by employing the named parameter idiom. http://www.parashift.com/c++-faq/named-parameter-idiom.html Rui Maciel
On 04/01/13 02:11, Rui Maciel wrote:
> Tim Wescott wrote: > >> I have to admit, the biggest problem that I have as a C++ programmer when >> writing in either VHDL or Verilog is envy: in both (IIRC) VHDL or Verilog, >> when you have a module with a bazzilion input and output signals, you can >> invoke it with a syntax something like >> >> module_name(module_signal_name = local_signal_name, ...) >> >> In C++, when, for reasons of utility, you are forced to design a class >> whose constructor has a bazzilion inputs, you have to hold your breath, >> close your eyes, cross your fingers, and hope that whoever uses that >> constructor call gets all the right things in all the right places: I'd >> Much Rather be able to invoke the syntax above and have it all self- >> document. > > There's no need to hold your breath. You can still do that, and more, with > C++, by employing the named parameter idiom. > > http://www.parashift.com/c++-faq/named-parameter-idiom.html > > > Rui Maciel >
I'm with Tim on this one... C and C++ programmers who have experience with other programming languages and know what named parameters are, /will/ hold their breaths and hope that they get implemented properly in the languages. (C would need support for C++ - style default parameters first, of course.) The link you gave illustrates the problem perfectly. Here there is an "OpenFile" class with lots of inline member functions to act as pretend named parameters. It's a lot of mess for no good reason - if named parameters were part of the language, then it would all be implemented in a single simple constructor: OpenFile::OpenFile(std::string const& filename, readonly = false, createIfNotExist = false, blockSize = 4096u) ... And it would be called with something like: f = OpenFile("foo.txt", blockSize = 1024); This would be much easier to write, much easier to use, and much more efficient - it is just syntactic sugar for normal function calling as the compiler would re-arrange the parameters in the correct non-named order. In fact, the OpenFile class would not be needed at all - it is just an artificial class to get pseudo named parameters for an OpenFile /function/ (or method of the main File class). One of the strengths of C++ is that you can add a lot of features to the language by using templates, classes, and the pre-processor (just look at boost for examples). And the standards committee is rightly reluctant to add new features to the basic language if the same functionality can be implemented using the existing language. But a big weakness of C++ is that this philosophy is sometimes used as an excuse not to fill in gaps in the language. /Real/ named parameters would be easy to add to the language specifications, and a simple matter to implement for compiler developers. But instead we have got this "named parameter idiom" rather than proper support. mvh., David
David Brown wrote:

> C and C++ programmers who have experience with other programming > languages and know what named parameters are, /will/ hold their breaths > and hope that they get implemented properly in the languages. (C would > need support for C++ - style default parameters first, of course.)
C, since C99, has designated initializers for aggregate types, which helps pull off this syntactic sugar. <code> #include <stdio.h> struct test_parameter { int a; float b; }; void test(struct test_parameter p) { printf("testing a: %d, b: %f\n", p.a, p.b); } int main(void) { test((struct test_parameter){.a = 1, .b = 2.0f}); test((struct test_parameter){.b = 5.0f, .a = 4}); return 0; } </code> C++ doesn't support C's designated initializers, so this trick can't be pulled with it. Nevertheless, as I've mentioned previously, the named parameter idiom can be used for the exact same effect. This means that it isn't true that C++ forces anyone to design a class with a bazzilion parameters. If having to pass more than a couple of parameters to a constructor becomes a problem, there are plenty of ways to avoid that. For example, it is also possible to use Boost's ad-hoc implementation of named parameters: http://www.boost.org/doc/libs/1_44_0/libs/parameter/doc/html/index.html What I tend to use to avoid having to define multiple versions of the same constructor or a constructor with a bazzilion parameters is to use a named parameter idiom to define a parameter class for the constructor, such as: <code> #include <iostream> class Foo { int a; float b; public: struct Parameters { int a; float b; Parameters & length(int const l) {a = l; return *this;} ; Parameters & frequency(float const f) {b = f; return *this;}; }; Foo(Parameters const &param): a(param.a), b(param.b) { std::cout << "a: " << a << ", b: " << b << std::endl;} }; int main(void) { Foo( Foo::Parameters().length(2).frequency(4)); Foo( Foo::Parameters().frequency(6).length(3)); return 0; } </code>
> The link you gave illustrates the problem perfectly. Here there is an > "OpenFile" class with lots of inline member functions to act as pretend > named parameters. It's a lot of mess for no good reason
The member functions don't need to be inline. The only requirement is that they return a reference to the named parameter object. If you believe that having to deal with more than a couple of parameters represents a problem then providing a solution to this problem is a good reason to use them. And the "lot of mess" comment is at best unreasonable.
> - if named > parameters were part of the language, then it would all be implemented > in a single simple constructor: > > OpenFile::OpenFile(std::string const& filename, readonly = false, > createIfNotExist = false, blockSize = 4096u) ... > > And it would be called with something like: > f = OpenFile("foo.txt", blockSize = 1024); > > This would be much easier to write, much easier to use, and much more > efficient - it is just syntactic sugar for normal function calling as > the compiler would re-arrange the parameters in the correct non-named > order.
Adding support in the core language for named parameters would only make them easier to write because there would be no need to define a named parameter idiom class. Yet, they aren't hard to define to begin with. Named parameters in the core language aren't any easier to use than a named parameter idiom class. For example: f = OpenFile("foo.txt", blockSize = 1024); vs f = OpenFile("foo.txt", OpenFile::Param().blockSize(1024) ); or f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); In addition, the named parameter idiom makes it possible to define methods which operate on multiple parameters. For example, in the above example, it's possible to define the following member function: OpenFile::Param &OpenFile::Param::defaultFile(std::string &file) { /*stuff*/} This would mean that the following examples would be equivalent: f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); f = OpenFile(OpenFile::Param().defaultFile("foo.txt") ); You can't do that with named parameters.
> In fact, the OpenFile class would not be needed at all - it is just an > artificial class to get pseudo named parameters for an OpenFile > /function/ (or method of the main File class).
There is no way to be sure about that. For example, OpenFile might be an implementation of a strategy pattern.
> One of the strengths of C++ is that you can add a lot of features to the > language by using templates, classes, and the pre-processor (just look > at boost for examples). And the standards committee is rightly > reluctant to add new features to the basic language if the same > functionality can be implemented using the existing language. But a big > weakness of C++ is that this philosophy is sometimes used as an excuse > not to fill in gaps in the language.
I don't know if the C++ standard committee is reluctant to add new features. If I'm not mistaken, the only instance where new features stopped being considered was near the end of C++0x's standardization process, and even then these suggestions were only postponed so that C++11 could be finally published without any further delay. In addition, if the C++ standard committee was reluctant to add new features then they wouldn't be opened to new proposals: http://isocpp.org/std/submit-a-proposal
> /Real/ named parameters would be > easy to add to the language specifications, and a simple matter to > implement for compiler developers.
I really doubt that named parameters would be easy to add to the language, considering C++'s support for function overloading. Take, for example, the following class: <code> struct Bar { void baz(int a, float b) { /* nothing happens */ } void baz(float b, int a) { /* the enter key blows up */ } }; int main(void) { Bar bar; bar.baz( a = 10, b = 20 ); return 0; } </code> What member function do you expect to be called?
> But instead we have got this "named > parameter idiom" rather than proper support.
C++ doesn't support named parameters in the core language, but to go from there and claim that the named parameter idiom isn't "proper support" is a bit of a stretch. The only claim that you can really make is that named parameters aren't supported directly in the core language, or that C++ isn't exactly like, say, Python. Yet, none of those complains are valid or reasonable. Rui Maciel
(I think we are getting way off topic here, and I also doubt that we'll
get very far in convincing each other of our point of view.  So if you
don't want to bother writing more here, I will not feel snubbed - and if
you /do/ want to carry on, then perhaps we should re-start the thread in
comp.lang.c++).

On 04/01/13 14:36, Rui Maciel wrote:
> David Brown wrote: > >> C and C++ programmers who have experience with other programming >> languages and know what named parameters are, /will/ hold their breaths >> and hope that they get implemented properly in the languages. (C would >> need support for C++ - style default parameters first, of course.) > > C, since C99, has designated initializers for aggregate types, which helps > pull off this syntactic sugar. > > <code> > #include <stdio.h> > > struct test_parameter > { > int a; > float b; > }; > > void test(struct test_parameter p) > { > printf("testing a: %d, b: %f\n", p.a, p.b); > } > > > int main(void) > { > test((struct test_parameter){.a = 1, .b = 2.0f}); > test((struct test_parameter){.b = 5.0f, .a = 4}); > return 0; > } > </code> > > C++ doesn't support C's designated initializers, so this trick can't be > pulled with it. Nevertheless, as I've mentioned previously, the named > parameter idiom can be used for the exact same effect.
The named parameter idiom can give a /similar/ effect - but might be less efficient (code space and run-time speed), and is certainly massively less compact and elegant in the source code. The use of C structs with designated initialisers gives a much more elegant solution than the C++ "named parameter idiom". But it is still far from ideal - as well as requiring a bit more unnecessary coding, you might get a less efficient implementation (depending on the compiler and the target, passing a struct is likely to be less efficient than passing arguments directly, and it limits the compiler's optimiser). And as you note, C++ doesn't support designated initialisers for structs. I can't see any rational reason why it should not, but I suppose the C++ standards people have some reason (other than to annoy people who want to write code that works as C and C++).
> > This means that it isn't true that C++ forces anyone to design a class with > a bazzilion parameters. If having to pass more than a couple of parameters > to a constructor becomes a problem, there are plenty of ways to avoid that. > For example, it is also possible to use Boost's ad-hoc implementation of > named parameters: > > http://www.boost.org/doc/libs/1_44_0/libs/parameter/doc/html/index.html > > What I tend to use to avoid having to define multiple versions of the same > constructor or a constructor with a bazzilion parameters is to use a named > parameter idiom to define a parameter class for the constructor, such as: > > <code> > #include <iostream> > > class Foo > { > int a; > float b; > > public: > struct Parameters > { > int a; > float b; > Parameters & length(int const l) {a = l; return > *this;} ; > Parameters & frequency(float const f) {b = f; return > *this;}; > }; > > Foo(Parameters const &param): a(param.a), b(param.b) { std::cout << > "a: " << a << ", b: " << b << std::endl;} > }; > > > int main(void) > { > Foo( Foo::Parameters().length(2).frequency(4)); > Foo( Foo::Parameters().frequency(6).length(3)); > return 0; > } > </code> >
I can see how this all works - and I can see how the named parameter idiom (or related solutions) can sometimes be better than nothing. But I /cannot/ see why anyone would prefer a solution above instead of: class Foo { int a; float b; public: Foo(int length, float frequency) : a(length), b(frequency) { } }; int main(void) { Foo(length = 2, frequency = 4); Foo(frequency = 5, length = 3); } Is there any good reason why that syntax is not supported by C++ (and C, though it is much more useful if support for default parameters were added)? I suppose it might be argued that "Foo(.length = 2, .frequency = 4);" would be more consistent with C's designated initialisers for structs - I think most users would be happy either way.
> >> The link you gave illustrates the problem perfectly. Here there is an >> "OpenFile" class with lots of inline member functions to act as pretend >> named parameters. It's a lot of mess for no good reason > > The member functions don't need to be inline. The only requirement is that > they return a reference to the named parameter object. > > If you believe that having to deal with more than a couple of parameters > represents a problem then providing a solution to this problem is a good > reason to use them. And the "lot of mess" comment is at best unreasonable. >
Look above at your "Foo" class, and my "Foo" class. Every character that you wrote, but that I did not write, fills the source code unnecessarily. In my suggested code, /nothing/ extra needs to be added to support designated parameters - they are totally free to the programmer (both in the source code, and in generated code space and time). So I think a "lot of mess" is justified - your solution uses more lines of code to implement the named parameters than to implement the class (though clearly the relative impact would be less in real code). As always, extra code like this means less readability and more effort in programming.
> >> - if named >> parameters were part of the language, then it would all be implemented >> in a single simple constructor: >> >> OpenFile::OpenFile(std::string const& filename, readonly = false, >> createIfNotExist = false, blockSize = 4096u) ... >> >> And it would be called with something like: >> f = OpenFile("foo.txt", blockSize = 1024); >> >> This would be much easier to write, much easier to use, and much more >> efficient - it is just syntactic sugar for normal function calling as >> the compiler would re-arrange the parameters in the correct non-named >> order. > > Adding support in the core language for named parameters would only make > them easier to write because there would be no need to define a named > parameter idiom class. Yet, they aren't hard to define to begin with. > > Named parameters in the core language aren't any easier to use than a named > parameter idiom class. For example: > > f = OpenFile("foo.txt", blockSize = 1024); > > vs > > f = OpenFile("foo.txt", OpenFile::Param().blockSize(1024) ); > > or > > f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); >
Can't you see that my suggestion is shorter and clearer? You could argue that it is not /much/ shorter, or not /much/ clearer - that's a question of taste and experience. Can't you see that my suggestion is completely /free/ for the programmer - they get the benefits of named parameters for /every/ function and method, without any changes or additions to the source code? Clearly, adding named parameter idiom classes to a significant number of functions in your code would overwhelm your code with "bookkeeping" code to enable the idiom. I can well agree that the current named parameter idiom has some uses, where the clarity for the caller over normal positional parameters justifies the effort of implementing it. But adding it to the core language would be far better.
> > In addition, the named parameter idiom makes it possible to define methods > which operate on multiple parameters. For example, in the above example, > it's possible to define the following member function: > > OpenFile::Param &OpenFile::Param::defaultFile(std::string &file) { > /*stuff*/} > > > This would mean that the following examples would be equivalent: > > f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); > f = OpenFile(OpenFile::Param().defaultFile("foo.txt") ); > > You can't do that with named parameters. >
I don't quite get your example here, but I can certainly see that there are times you might still want to use the idiom. Perhaps setting the parameter would have other side-effects, or perhaps you want multiple arguments in the parameter function. But obviously there is nothing in my suggested language change that would limit the use of named parameter idiom classes. Simple named parameters would cover 99% of the use cases - and you can still use the old idiom classes for the remaining 1%.
> >> In fact, the OpenFile class would not be needed at all - it is just an >> artificial class to get pseudo named parameters for an OpenFile >> /function/ (or method of the main File class). > > There is no way to be sure about that. For example, OpenFile might be an > implementation of a strategy pattern. > > >> One of the strengths of C++ is that you can add a lot of features to the >> language by using templates, classes, and the pre-processor (just look >> at boost for examples). And the standards committee is rightly >> reluctant to add new features to the basic language if the same >> functionality can be implemented using the existing language. But a big >> weakness of C++ is that this philosophy is sometimes used as an excuse >> not to fill in gaps in the language. > > I don't know if the C++ standard committee is reluctant to add new features. > If I'm not mistaken, the only instance where new features stopped being > considered was near the end of C++0x's standardization process, and even > then these suggestions were only postponed so that C++11 could be finally > published without any further delay. > > In addition, if the C++ standard committee was reluctant to add new features > then they wouldn't be opened to new proposals: > > http://isocpp.org/std/submit-a-proposal
They /are/ reluctant to add new features to the core language - and that is normally a good thing, as the language is complicated enough as it is. They will add new features if they feel they need to - such as lambdas and new reference types in C++11. But they insist on a lot of justification. Perhaps no one has submitted a proposal for named parameters to the committee - I know /I/ certainly have not done so. Maybe everyone thinks it is such an obvious, cost-free and useful feature that someone else must have submitted it already.
> > >> /Real/ named parameters would be >> easy to add to the language specifications, and a simple matter to >> implement for compiler developers. > > I really doubt that named parameters would be easy to add to the language, > considering C++'s support for function overloading. Take, for example, the > following class: > > <code> > struct Bar > { > void baz(int a, float b) { /* nothing happens */ } > void baz(float b, int a) { /* the enter key blows up */ } > }; > > int main(void) > { > Bar bar; > bar.baz( a = 10, b = 20 ); > return 0; > } > </code> > > What member function do you expect to be called?
Code like that is already broken - which member function should be called for bar.baz(10, 20)? (Even if the answer is well-defined in C++ at the moment, it is still wrong IMHO because the code is unclear.) But you are certainly right here - there will be complications in the face of function overloading, that will make it harder to implement than I first imagined. I can't see it being an impossible problem, however - but there will be some cases (like that example) when the only decent thing the compiler can do is issue an error about ambiguous overloads.
> > > >> But instead we have got this "named >> parameter idiom" rather than proper support. > > C++ doesn't support named parameters in the core language, but to go from > there and claim that the named parameter idiom isn't "proper support" is a > bit of a stretch. The only claim that you can really make is that named > parameters aren't supported directly in the core language, or that C++ isn't > exactly like, say, Python. Yet, none of those complains are valid or > reasonable.
Well, I think the second and third claims here /are/ valid and reasonable - named parameters are clearly not supported in the core C++ language, and the way you make named parameters work in today's C++ is clearly not the same as in Python. And as for my main claim that the named parameter idiom is not "proper support" for named parameters - that's a matter of opinion, and our opinions obviously differ here. mvh., David
> > > Rui Maciel >
On Fri, 04 Jan 2013 16:35:14 +0100, David Brown wrote:

> (I think we are getting way off topic here, and I also doubt that we'll > get very far in convincing each other of our point of view. So if you > don't want to bother writing more here, I will not feel snubbed - and if > you /do/ want to carry on, then perhaps we should re-start the thread in > comp.lang.c++). > > On 04/01/13 14:36, Rui Maciel wrote: >> David Brown wrote: >> >>> C and C++ programmers who have experience with other programming >>> languages and know what named parameters are, /will/ hold their >>> breaths and hope that they get implemented properly in the languages. >>> (C would need support for C++ - style default parameters first, of >>> course.) >> >> C, since C99, has designated initializers for aggregate types, which >> helps pull off this syntactic sugar. >> >> <code> >> #include <stdio.h> >> >> struct test_parameter { >> int a; >> float b; >> }; >> >> void test(struct test_parameter p) >> { >> printf("testing a: %d, b: %f\n", p.a, p.b); >> } >> >> >> int main(void) >> { >> test((struct test_parameter){.a = 1, .b = 2.0f}); >> test((struct test_parameter){.b = 5.0f, .a = 4}); >> return 0; >> } >> </code> >> >> C++ doesn't support C's designated initializers, so this trick can't be >> pulled with it. Nevertheless, as I've mentioned previously, the named >> parameter idiom can be used for the exact same effect. > > The named parameter idiom can give a /similar/ effect - but might be > less efficient (code space and run-time speed), and is certainly > massively less compact and elegant in the source code. > > The use of C structs with designated initialisers gives a much more > elegant solution than the C++ "named parameter idiom". But it is still > far from ideal - as well as requiring a bit more unnecessary coding, you > might get a less efficient implementation (depending on the compiler and > the target, passing a struct is likely to be less efficient than passing > arguments directly, and it limits the compiler's optimiser). > > And as you note, C++ doesn't support designated initialisers for > structs. I can't see any rational reason why it should not, but I > suppose the C++ standards people have some reason (other than to annoy > people who want to write code that works as C and C++). > > > >> This means that it isn't true that C++ forces anyone to design a class >> with a bazzilion parameters. If having to pass more than a couple of >> parameters to a constructor becomes a problem, there are plenty of ways >> to avoid that. For example, it is also possible to use Boost's ad-hoc >> implementation of named parameters: >> >> http://www.boost.org/doc/libs/1_44_0/libs/parameter/doc/html/index.html >> >> What I tend to use to avoid having to define multiple versions of the >> same constructor or a constructor with a bazzilion parameters is to use >> a named parameter idiom to define a parameter class for the >> constructor, such as: >> >> <code> >> #include <iostream> >> >> class Foo { >> int a; >> float b; >> >> public: >> struct Parameters { >> int a; >> float b; >> Parameters & length(int const l) {a = l; return >> *this;} ; >> Parameters & frequency(float const f) {b = f; return >> *this;}; >> }; >> >> Foo(Parameters const &param): a(param.a), b(param.b) { >> std::cout << >> "a: " << a << ", b: " << b << std::endl;} >> }; >> >> >> int main(void) >> { >> Foo( Foo::Parameters().length(2).frequency(4)); >> Foo( Foo::Parameters().frequency(6).length(3)); >> return 0; >> } >> </code> >> >> > I can see how this all works - and I can see how the named parameter > idiom (or related solutions) can sometimes be better than nothing. > > But I /cannot/ see why anyone would prefer a solution above instead of: > > class Foo { > int a; > float b; > public: > Foo(int length, float frequency) : a(length), b(frequency) { } > }; > > int main(void) { > Foo(length = 2, frequency = 4); > Foo(frequency = 5, length = 3); > } > > > Is there any good reason why that syntax is not supported by C++ (and C, > though it is much more useful if support for default parameters were > added)? > > I suppose it might be argued that "Foo(.length = 2, .frequency = 4);" > would be more consistent with C's designated initialisers for structs - > I think most users would be happy either way. > > > > > >>> The link you gave illustrates the problem perfectly. Here there is an >>> "OpenFile" class with lots of inline member functions to act as >>> pretend named parameters. It's a lot of mess for no good reason >> >> The member functions don't need to be inline. The only requirement is >> that they return a reference to the named parameter object. >> >> If you believe that having to deal with more than a couple of >> parameters represents a problem then providing a solution to this >> problem is a good reason to use them. And the "lot of mess" comment is >> at best unreasonable. >> >> > Look above at your "Foo" class, and my "Foo" class. Every character > that you wrote, but that I did not write, fills the source code > unnecessarily. In my suggested code, /nothing/ extra needs to be added > to support designated parameters - they are totally free to the > programmer (both in the source code, and in generated code space and > time). So I think a "lot of mess" is justified - your solution uses > more lines of code to implement the named parameters than to implement > the class (though clearly the relative impact would be less in real > code). As always, extra code like this means less readability and more > effort in programming. > > >>> - if named parameters were part of the language, then it would all be >>> implemented in a single simple constructor: >>> >>> OpenFile::OpenFile(std::string const& filename, readonly = false, >>> createIfNotExist = false, blockSize = 4096u) ... >>> >>> And it would be called with something like: >>> f = OpenFile("foo.txt", blockSize = 1024); >>> >>> This would be much easier to write, much easier to use, and much more >>> efficient - it is just syntactic sugar for normal function calling as >>> the compiler would re-arrange the parameters in the correct non-named >>> order. >> >> Adding support in the core language for named parameters would only >> make them easier to write because there would be no need to define a >> named parameter idiom class. Yet, they aren't hard to define to begin >> with. >> >> Named parameters in the core language aren't any easier to use than a >> named parameter idiom class. For example: >> >> f = OpenFile("foo.txt", blockSize = 1024); >> >> vs >> >> f = OpenFile("foo.txt", OpenFile::Param().blockSize(1024) ); >> >> or >> >> f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); >> >> > Can't you see that my suggestion is shorter and clearer? You could > argue that it is not /much/ shorter, or not /much/ clearer - that's a > question of taste and experience. > > Can't you see that my suggestion is completely /free/ for the programmer > - they get the benefits of named parameters for /every/ function and > method, without any changes or additions to the source code? Clearly, > adding named parameter idiom classes to a significant number of > functions in your code would overwhelm your code with "bookkeeping" code > to enable the idiom. > > > I can well agree that the current named parameter idiom has some uses, > where the clarity for the caller over normal positional parameters > justifies the effort of implementing it. But adding it to the core > language would be far better. > > >> In addition, the named parameter idiom makes it possible to define >> methods which operate on multiple parameters. For example, in the >> above example, it's possible to define the following member function: >> >> OpenFile::Param &OpenFile::Param::defaultFile(std::string &file) { >> /*stuff*/} >> >> >> This would mean that the following examples would be equivalent: >> >> f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); >> f = OpenFile(OpenFile::Param().defaultFile("foo.txt") ); >> >> You can't do that with named parameters. >> >> > I don't quite get your example here, but I can certainly see that there > are times you might still want to use the idiom. Perhaps setting the > parameter would have other side-effects, or perhaps you want multiple > arguments in the parameter function. > > But obviously there is nothing in my suggested language change that > would limit the use of named parameter idiom classes. Simple named > parameters would cover 99% of the use cases - and you can still use the > old idiom classes for the remaining 1%. > > > >>> In fact, the OpenFile class would not be needed at all - it is just an >>> artificial class to get pseudo named parameters for an OpenFile >>> /function/ (or method of the main File class). >> >> There is no way to be sure about that. For example, OpenFile might be >> an implementation of a strategy pattern. >> >> >>> One of the strengths of C++ is that you can add a lot of features to >>> the language by using templates, classes, and the pre-processor (just >>> look at boost for examples). And the standards committee is rightly >>> reluctant to add new features to the basic language if the same >>> functionality can be implemented using the existing language. But a >>> big weakness of C++ is that this philosophy is sometimes used as an >>> excuse not to fill in gaps in the language. >> >> I don't know if the C++ standard committee is reluctant to add new >> features. >> If I'm not mistaken, the only instance where new features stopped being >> considered was near the end of C++0x's standardization process, and >> even then these suggestions were only postponed so that C++11 could be >> finally published without any further delay. >> >> In addition, if the C++ standard committee was reluctant to add new >> features then they wouldn't be opened to new proposals: >> >> http://isocpp.org/std/submit-a-proposal > > They /are/ reluctant to add new features to the core language - and that > is normally a good thing, as the language is complicated enough as it > is. They will add new features if they feel they need to - such as > lambdas and new reference types in C++11. But they insist on a lot of > justification. > > Perhaps no one has submitted a proposal for named parameters to the > committee - I know /I/ certainly have not done so. Maybe everyone > thinks it is such an obvious, cost-free and useful feature that someone > else must have submitted it already. > > >> >>> /Real/ named parameters would be easy to add to the language >>> specifications, and a simple matter to implement for compiler >>> developers. >> >> I really doubt that named parameters would be easy to add to the >> language, considering C++'s support for function overloading. Take, >> for example, the following class: >> >> <code> >> struct Bar { >> void baz(int a, float b) { /* nothing happens */ } >> void baz(float b, int a) { /* the enter key blows up */ } >> }; >> >> int main(void) >> { >> Bar bar; >> bar.baz( a = 10, b = 20 ); >> return 0; >> } >> </code> >> >> What member function do you expect to be called? > > Code like that is already broken - which member function should be > called for bar.baz(10, 20)? (Even if the answer is well-defined in C++ > at the moment, it is still wrong IMHO because the code is unclear.) > > But you are certainly right here - there will be complications in the > face of function overloading, that will make it harder to implement than > I first imagined. I can't see it being an impossible problem, however - > but there will be some cases (like that example) when the only decent > thing the compiler can do is issue an error about ambiguous overloads. > > > >> >> >>> But instead we have got this "named parameter idiom" rather than >>> proper support. >> >> C++ doesn't support named parameters in the core language, but to go >> from there and claim that the named parameter idiom isn't "proper >> support" is a bit of a stretch. The only claim that you can really >> make is that named parameters aren't supported directly in the core >> language, or that C++ isn't exactly like, say, Python. Yet, none of >> those complains are valid or reasonable. > > Well, I think the second and third claims here /are/ valid and > reasonable - named parameters are clearly not supported in the core C++ > language, and the way you make named parameters work in today's C++ is > clearly not the same as in Python. > > And as for my main claim that the named parameter idiom is not "proper > support" for named parameters - that's a matter of opinion, and our > opinions obviously differ here.
I agree. I do embedded programming. I can't afford to bloat my code, or slow down my execution, with workarounds like this. -- Tim Wescott Control system and signal processing consulting www.wescottdesign.com
David Brown <david@westcontrol.removethisbit.com> wrote:
 
(snip)

> The named parameter idiom can give a /similar/ effect - but might be > less efficient (code space and run-time speed), and is certainly > massively less compact and elegant in the source code.
(snip)
> Foo(length = 2, frequency = 4); > Foo(frequency = 5, length = 3); > }
> Is there any good reason why that syntax is not supported by C++ (and C, > though it is much more useful if support for default parameters were added)?
Because it already has a different meaning in C. Remember that = is an operator with a value, so the above assigns the value 2 to length, 4 to frequency, then passes (2, 4) to Foo.
> I suppose it might be argued that "Foo(.length = 2, .frequency = 4);" > would be more consistent with C's designated initialisers for structs - > I think most users would be happy either way.
This might work. Someone should post to comp.lang.c to see what they say about it. -- glen
On 04/01/13 17:54, glen herrmannsfeldt wrote:
> David Brown <david@westcontrol.removethisbit.com> wrote: > > (snip) > >> The named parameter idiom can give a /similar/ effect - but might be >> less efficient (code space and run-time speed), and is certainly >> massively less compact and elegant in the source code. > > (snip) > >> Foo(length = 2, frequency = 4); >> Foo(frequency = 5, length = 3); >> } > > >> Is there any good reason why that syntax is not supported by C++ (and C, >> though it is much more useful if support for default parameters were added)? > > Because it already has a different meaning in C. > > Remember that = is an operator with a value, so the above assigns > the value 2 to length, 4 to frequency, then passes (2, 4) to Foo. >
That is correct. So what is needed here is for the "length" and "frequency" to refer to the parameters, rather than whatever is in scope at the time. That would be a change to the language, and theoretically could break existing valid code - but you would be unlikely to find such code outside the IOCCC. But obviously such a change would need a lot of thought from the language lawyers and the compiler implementers to see if there are any other non-obvious issues.
>> I suppose it might be argued that "Foo(.length = 2, .frequency = 4);" >> would be more consistent with C's designated initialisers for structs - >> I think most users would be happy either way. > > This might work. > > Someone should post to comp.lang.c to see what they say about it. > > -- glen >
Having developed in VHDL (RTL and verification) for over 20 yrs, I recently=
 took a two week intensive course in Verilog, SystemVerilog and UVM. I have=
 a newfound appreciation for just how nice VHDL really is! Verilog has so m=
any rabbit holes that look like they should work, but don't, and if you don=
't use a separate linter, you'll never find them. Add to that the lack of s=
ubprogram overloading, unconstrained array types (including inspection of a=
rguments to determine array range, etc.) and a host of other features I've =
taken for granted for so many years, and its a now brainer.=20

If systemverilog did not have all the baggage of verilog, it might be a pre=
tty good language. Take a look and the scheduling model for SystemVerilog: =
it is a total mish-mash of bolted-on steps to handle this problem or that. =
And if systemverilog is so powerfull, why is the preprocessor so integral t=
o a standard class library and use model like UVM? Pre-processors are crutc=
hes for hobbling along on the broken limbs of ill-conceived or incomplete l=
anguages.=20

Perhaps the most glaring ommission of verilog/SV is the lack of bounds chec=
king on array indices and scalar arguments to subprograms. This feature alo=
ne allows VHDL to give you an error message that identifies where the probl=
ems is, rather than simply strange behavior, or a segmentation fault in ver=
ilog/SV.

Take this example: try doing what the synthesizeable, standard VHDL fixed a=
nd floating point packages do, in verilog or even system verilog. And keep =
in mind that the first versions (complete functionality) were all done in t=
he 20 year old '93 version of VHDL! The 2008 version only added generics to=
 the packages for default handling of saturation, rounding, etc.=20

The other issue that struck me during the course was the common reliance up=
on the pre-processor in the lab examples to ensure compatibility with sever=
al different brands of  simulators. What works in one simulator, doesn't al=
ways work in another! And these are all "compliant" simulators! A leisurely=
 stroll through the VHDL and SystemVerilog LRMs reveals the difference: The=
 VHDL strictly defines what the language does and what is not allowed, with=
 very few ambiguities. The SV LRM replaces strict specification with usage =
examples, and hopes that each developer gets the same idea about what to su=
pport and what to disallow. Ever seen an SV compliance suite?=20

Does VHDL have room for improvement? Absolutely! It needs an object-oriente=
d capability complete with inheritance. Existing protected types are a star=
t (see OSVVM.org for an example of what can be accomplished with them), but=
 no substitute for a complete OO implementation. An interface capability fo=
r multi-directional elements on ports of record type is also needed (one of=
 the nice features of systemverilog). The good news is these and other issu=
es are being worked today for the next version of VHDL.

Andy