Named parameters?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I'm reading about attribute classes and specifically, named versus positional
parameters. Was this implimented instead of multiple constructors for
flexibility or is there another reason I'm missing?

-Ben
 
Ben R. said:
I'm reading about attribute classes and specifically, named versus
positional
parameters. Was this implimented instead of multiple constructors for
flexibility or is there another reason I'm missing?

It is flexibility more than anything else, I think. Considering the sets of
options an attribute has, multiple constructors would be complicated to say
the least, if not impossible. Named parameters are really no different than
the standard:

X x = new X();
x.Property = 10;

except that they have to be written in a more condensed form.

Consider you have two properties of type string, Name and Description

If you only want to set one of those, assuming the attribute doesn't require
both in the constructor, of course, you can. But if you use multiple
constructors there is no way to define a set of two constructors that will
allow you to set one and only one of the above properties.

Now, consider if you had 20 properties, the chances of being able to
generate all the possible combonations of properties in the constructor are
very very low, its likely you will run into the same problem somewhere. Not
to mention the hideous number of constructors.
 
Hi Daniel,

Thanks for the very thourough response. That was a very interesting example
with not being able to have 2 different constructors for the name and
description fields only. I did some experimenting and it looks like this
feature is only enabled for Attribute classes. Is this accurate? If so, why?
Also, is the key here that the field needs to have a property in order to be
settable in a named parameter or could one do the same with a public field?

Thanks...

-Ben
 
There are already suggestions made to microsoft to include named parameters
as a general language feature and not only as an exception allowed for
Attributes.
The trick is to find the most flexible and performant way to implement it.
 
cody said:
There are already suggestions made to microsoft to include named
parameters
as a general language feature and not only as an exception allowed for
Attributes.
The trick is to find the most flexible and performant way to implement it.

No, the trick is convincing people its a bad idea without optional
parameters, which are a bad idea themselves, IMHO. Attributes do not have
named arguments, they simply have convienent property setters.

Flexiblity and performance are not the issue, the real trouble is
consistency, which you will not achieve. The language just isn't really
going to allow it
 
Ben R. said:
Hi Daniel,

Thanks for the very thourough response. That was a very interesting
example
with not being able to have 2 different constructors for the name and
description fields only. I did some experimenting and it looks like this
feature is only enabled for Attribute classes. Is this accurate? If so,
why?

[sorry, I thought I posted this earlier]

Yes, it is only available in attributes.

There are two reasons really, the first is that it allows for a very compact
syntax. No one would want to have to write out the equivilent non-attribute
code within an attribute block. The second reason is an enabling one,
because the syntax
Prop = Value
is not ambigous within an attribute whereas in normal method code it is
possible that you are trying to assign to a local property or variable and
not to a named attribute.
 
Is the idea really this bad? For example the Graphics.DrawImage method has
about 20 overloads with dozends of parameters. Did you ever have to usse
directX? Most methods have > 10 parameters and are heavyly overloaded. Then
you'd really wish you'd had named parameters.
I wouldn't enable named parameter passing per default: instead you would
have to explicitly mark the arguments as optional, which is, all
non-optional parameters will be positional parameters.
 
cody said:
Is the idea really this bad? For example the Graphics.DrawImage method has
about 20 overloads with dozends of parameters. Did you ever have to usse
directX? Most methods have > 10 parameters and are heavyly overloaded.
Then
you'd really wish you'd had named parameters.

Yes, it is bad. There is nothing like adding a feature that makes what code
says and what code means differ(optional parameters, that is).

If you design a method that requires so many overloads and parameters that
named parameters is the only way to understandably use it, wouldn't you say
the method should be reconsidered? Graphics.DrawImage is one of the most
obnoxious overloads ever created and adding features to make using it easier
is the wrong way to go, IMHO. Fix the interface, not the language.

DirectX is an interesting beast in that its interface was designed with
optional parameters in mind and with overloading disallowed. It has been
argued, well I might add, that the flaws in DirectX and many COM interfaces
are a direct result of the use of optional parameters over overloads. The
interfaces are monolithic and badly structured, making it rather difficult
to convert to .NET directly(managed directX was pretyt poorly designed as
well). Again, its not the languages job to work around bad interfaces,
especially when the features could be the cause of the problem to begin
with.

Now, without any valid reason for optional parameters, named parameters have
little need.

And that still doesn't fix the issues with syntactical consistency. Optional
parameters give you a syntactic problem, namely that they do not work that
well with overloads as you cannot provide overloads that would clash with
optional arguments

consider:

public void Test(string x, optional string y);
public void Test(string x);

That would result in ambigious calling code, how do you get around that
without complicating the language even more?

Named parameters offer another problem, consider

Test("cat", y = "mouse")

and

string y;
Test("cat", y="mouse");

y="mouse" has two different meanings here, how do you get around that?
 
"Daniel O'Connell said:
Yes, it is bad. There is nothing like adding a feature that makes what code
says and what code means differ(optional parameters, that is).

If you design a method that requires so many overloads and parameters that
named parameters is the only way to understandably use it, wouldn't you say
the method should be reconsidered?

I'd agree. If I had a method which had a very large number of
parameters, many of which were optional, rather than having an overload
for each legal permutation I'd consider something along the lines of
passing a single parameter object.
 
Is the idea really this bad? For example the Graphics.DrawImage method
Yes, it is bad. There is nothing like adding a feature that makes what
code says and what code means differ(optional parameters, that is).

If you design a method that requires so many overloads and parameters that
named parameters is the only way to understandably use it, wouldn't you
say the method should be reconsidered? Graphics.DrawImage is one of the
most obnoxious overloads ever created and adding features to make using it
easier is the wrong way to go, IMHO. Fix the interface, not the language.

The questions is what is the alternative. Something like that?

ImageDraw d = new ImageDraw(g);
d.SrcRect = rect;
d.dstRect = rect;
d.DrawFlags = foo;
//..
d.Draw();

This would have the advantage that you can reuse this object so you do not
need to push all 20 arguments for every call on the stack,
so you can have a performance advantage.
DirectX is an interesting beast in that its interface was designed with
optional parameters in mind and with overloading disallowed. It has been
argued, well I might add, that the flaws in DirectX and many COM
interfaces are a direct result of the use of optional parameters over
overloads. The interfaces are monolithic and badly structured, making it
rather difficult to convert to .NET directly(managed directX was pretyt
poorly designed as well).

I hope that Tom Miller will fix this in near future :)
public void Test(string x, optional string y);
public void Test(string x);

That would result in ambigious calling code, how do you get around that
without complicating the language even more?

You cannot overload a method which signature only differs in optional
arguments.
string y;
Test("cat", y="mouse");

y="mouse" has two different meanings here, how do you get around that?

You have to use a special operator/prefix to mark a named argument as such
for example

Test("cat", .y="mouse");
Test("cat", #y="mouse");
Test("cat", $y="mouse");

or similar.
 
If you design a method that requires so many overloads and parameters
The questions is what is the alternative. Something like that?

ImageDraw d = new ImageDraw(g);
d.SrcRect = rect;
d.dstRect = rect;
d.DrawFlags = foo;
//..
d.Draw();

This would have the advantage that you can reuse this object so you do not
need to push all 20 arguments for every call on the stack,
so you can have a performance advantage.

That'd be one option, I certainly havn't taken the time to redesign the
graphics class, sorry to say, ;). DrawImage could be split into several
methods that more adequatly describe themselves instead of one that takes 20
different combinations of inputs(If I recall correctly, a big part of that
is allowing both floating point and integer sizes and positioning, correct?)
You cannot overload a method which signature only differs in optional
arguments.

Of course not, but that means optional potentially becomes the chief way to
overload, creating really crappy interfaces that assume optional is
supported and liked ala COM and VB. Once you throw optional into a method,
determining the safe overload set gets too complicated and you lose a great
many useful overload options anyway. So one optional parameter means
overloading is really unattractive, so is it actually worth it?
You have to use a special operator/prefix to mark a named argument as such
for example

Test("cat", .y="mouse");
Test("cat", #y="mouse");
Test("cat", $y="mouse");

Which is ugly and inconsistent, IMHO, as it differs from how it works in
attributes(not to mention that the acutal *functionality* of the two setters
are very, very different). You would also end up with the oh-so-cute

[Attribute($y="mouse",y="mouse")]

as legal code that looks so similar but are actually entirely different in
meaning.

Do you really thing adding a keyword, functionality, and a variable prefix
to the language is the best way to solve any of these problems? Are named
parameters needed or is it just language envy?
 
Steve Walker said:
"Daniel O'Connell [C# said:
cody said:
Is the idea really this bad? For example the Graphics.DrawImage method
has
about 20 overloads with dozends of parameters. Did you ever have to usse
directX? Most methods have > 10 parameters and are heavyly overloaded.
Then
you'd really wish you'd had named parameters.

Yes, it is bad. There is nothing like adding a feature that makes what
code
says and what code means differ(optional parameters, that is).

If you design a method that requires so many overloads and parameters that
named parameters is the only way to understandably use it, wouldn't you
say
the method should be reconsidered?

I'd agree. If I had a method which had a very large number of parameters,
many of which were optional, rather than having an overload for each legal
permutation I'd consider something along the lines of passing a single
parameter object.

That or consider why the method has so many overloads and either extract it
into another object, split the methods up into several methods that each do
atomic operations, or draw lines on functionality(ie a knife should be a
knife, not a fork, spoon, and mini-tv). It all depends on the exact
interface.

A parameter object or extracting the method into one or more independent
classes seems to be the best option in this case.

Now, what might be interesting would be considering syntax to simplify
parameter object creation. It probably wouldn't be a *good* idea in the
language but it is an interesting thought project. Maybe something like:

public void MyMethod(parameter MyParameterObject paramObject = new
MyParameterObject);

MyMethod(parameter.Name = "cheese", parameter.Age = 15);
or

MyMethod(parameter MyParameterObject
{
Name = "cheese";
Age = 15;
});

or even a more generalized new ctor { propertySetters} syntax

new MyParameterObject()
{
Name = "cheese";
Age = 15;
};

It adds support for a (IMHO) better design pattern than optional parameters,
thoughts anyone?
 
Now, what might be interesting would be considering syntax to simplify
parameter object creation. It probably wouldn't be a *good* idea in the
language but it is an interesting thought project. Maybe something like:

public void MyMethod(parameter MyParameterObject paramObject = new
MyParameterObject);

MyMethod(parameter.Name = "cheese", parameter.Age = 15);
or

MyMethod(parameter MyParameterObject
{
Name = "cheese";
Age = 15;
});

or even a more generalized new ctor { propertySetters} syntax

new MyParameterObject()
{
Name = "cheese";
Age = 15;
};

It adds support for a (IMHO) better design pattern than optional
parameters, thoughts anyone?


Anders Hejlsberg spoke in a panel about a new syntax proposal for creating
objects (not just for parameter passing). It was something like that:

int age = 15;
MyClass mc = new MyClass{ Name="Herbert", Age = age; }

In that case you do not have the problem of syntax ambiguity because only
property assignments are allowed, on the left side a property of that object
is expected, and on the right side you cannot access members of that object.

But then you cannot do something like that:

Point p = new Point{X=10, Y=X}

because you cannot access X from there. In that case you have to use my
proposed character which distinguishes between a property of that object and
a local variable.
 
cody said:
Anders Hejlsberg spoke in a panel about a new syntax proposal for creating
objects (not just for parameter passing). It was something like that:

What panel was that?
But then you cannot do something like that:

Point p = new Point{X=10, Y=X}

because you cannot access X from there. In that case you have to use my
proposed character which distinguishes between a property of that object
and a local variable.

Which is a wholely bad idea, IMHO. You wouldn't do new Point(10, X) either.
I don't really see how this relates to named parameters either. I really
think adding a character to distinguish between properties and variables is
one step into turning the langauge into a mess not worth working with. I am
concerned with the future of the language as it is, I've seen few
suggestions that are really as nice as some want. COmega is ugly as hell,
polyphonic C# is passable but close to dangerous, and some of Anders
suggestions on whiteboards havn't been really attractive.
 
It adds support for a (IMHO) better design pattern than optional
What panel was that?

I found it on msdn TV, just look into the archives of microsoft.com after
"csharp features - AndersHejlsberg_300.wmv".
Which is a wholely bad idea, IMHO. You wouldn't do new Point(10, X)
either. I don't really see how this relates to named parameters either.

It would make it easier/less verbose to create parameter objects.
I really think adding a character to distinguish between properties and
variables is one step into turning the langauge into a mess not worth
working with.

Maybe you're right. A character for distinguishing was just a suggestion,
maybe not a good one.
 
cody said:
I found it on msdn TV, just look into the archives of microsoft.com after
"csharp features - AndersHejlsberg_300.wmv".


It would make it easier/less verbose to create parameter objects.


Maybe you're right. A character for distinguishing was just a suggestion,
maybe not a good one.

Sorry for getting back so late, either my newsreader or the MS servers just
decided to give me about 200 entries I missed.

I do not like distingishing characters(even for the set thing we talked
about a while back, I still havn't figured out a way to keep things
consistent AND allow string and other IENumerables to be atomic units
without a distingusihing character or operator). Expanded object
construction that allows for blocks of property setters wouldn't be bad,
though.
 
I do not like distingishing characters(even for the set thing we talked
about a while back, I still havn't figured out a way to keep things
consistent AND allow string and other IENumerables to be atomic units
without a distingusihing character or operator).

Yes C# is not a language where lots of special chars and operators fits in,
C# is more a "keyworded language".
The problem is that you cannot add keywords afterwards, only "context-only
keywords" like "yield" or "value".
If I would be a language designer creating a new language I'd reserve lots
of potential keywords at first, just in case they'll be needed at some time.
Expanded object construction that allows for blocks of property setters
wouldn't be bad, though.

If we allow the property setters of the object only on the left side there
is no problem with ambiguity.
 
cody said:
Yes C# is not a language where lots of special chars and operators fits
in, C# is more a "keyworded language".

Ya, it is a weirdly half "explicit-for-the-sake-of-explicity", half
"implicit-for-the-sake-of-simplicity" language. How else can you explain all
the little quirks that don't add up with all the other ones unless you look
at the langauge in historical context and as a whole. Looking at C#
piecemeal is depressing. The casting operator is wholly unlike anything else
in the language, 'as' is strange in that it is a casting operator that
doesn't look like the other casting operator, instead it matches up with
'is'(which is effectivly a cast that looks and acts like a comparison).
There is no explicit conversion operator, but there are explicit
conversions(which use the cast operator, brilliant). Yet, look at it from a
realistic, users point of view and it is simple, easy to use, and very
effective.
The problem is that you cannot add keywords afterwards, only "context-only
keywords" like "yield" or "value".

Eventually, the standard is going to have to expand to add new keywords or
the language will falter. I am not sold on going the whole-hog java route of
doing everything possible, including sacrificing functionality or
consistency, to keep old code compiling in new compilers.

I think migration tools might be the way to go here, something that can be
run across code and will change varaible names safely(detect collisions,
etc) and output a changlog file showing *exactly* waht changed(which VS
should be able to process and show us, ;)

Then again, spaced and contextual keywords aren't hard to understand and
might end up being a solution to the whole problem.
If I would be a language designer creating a new language I'd reserve lots
of potential keywords at first, just in case they'll be needed at some
time.
This can be hard to do, because its so easy to say you want to reserve:
index
value
param
arg

etc, taking up half of the common variable name set, ;). Plus, inevitably,
you'd find a feature you wanted to add that didn't work with the words you
already had restricted. Still, the C# team should have atleast thought
forward to generics and other 2.0 features, which were likely on the drawing
board already, and reserved the keywords they could.

Also, didn't C++ try this with underscores? The system reserved all
identifiers starting with two underscores or somethign like that, thats why
things like __int64 got so popular(and possibly one of the reasons C++ has
as much of a readability stigma attached to it as it does).
If we allow the property setters of the object only on the left side there
is no problem with ambiguity.

No, there isn't. It certainly is an interesting concept. Curious, curious. I
need to get back to my compiler one of these days, the list of ideas to
implement keeps getting longer and longer.
 
Back
Top