![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
http://tinyurl.com/bt268c
Let me just say: About time! I get tired of writing a bunch of overloads
to make parameters look like they're optional!
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Mike Raiford wrote:
> http://tinyurl.com/bt268c
>
> Let me just say: About time! I get tired of writing a bunch of overloads
> to make parameters look like they're optional!
There are some who make good arguments against default parameters.
Basically, if it's a default parameter, it should be a separate method call
to set the value, because that's more OO. E.g., if you have a default
parameter for printing that says whether it should be landscape or portrait,
that should be a value in the print-job instance, not a parameter specified
on every call.
Sadly, C# syntax is starting to get really ugly. :-) I expect the
overloading rules will soon almost be as bad as C++.
> list.SearchForContacts(address="home", name="sam", age:30);
Heh. My first thought on seeing the syntax was "I bet I'd always be messing
that up and using = instead of :".
--
Darren New, San Diego CA, USA (PST)
"Ouch ouch ouch!"
"What's wrong? Noodles too hot?"
"No, I have Chopstick Tunnel Syndrome."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> There are some who make good arguments against default parameters.
> Basically, if it's a default parameter, it should be a separate method
> call to set the value, because that's more OO. E.g., if you have a
> default parameter for printing that says whether it should be landscape
> or portrait, that should be a value in the print-job instance, not a
> parameter specified on every call.
What *you* need is curried functions! ;-)
> Sadly, C# syntax is starting to get really ugly. :-) I expect the
> overloading rules will soon almost be as bad as C++.
Well... it was based on C to start with, so it's never going to be
exactly "pretty", is it?
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
> Darren New wrote:
>
>> There are some who make good arguments against default parameters.
>> Basically, if it's a default parameter, it should be a separate method
>> call to set the value, because that's more OO. E.g., if you have a
>> default parameter for printing that says whether it should be
>> landscape or portrait, that should be a value in the print-job
>> instance, not a parameter specified on every call.
>
> What *you* need is curried functions! ;-)
>
Explain curried functions, please.
>> Sadly, C# syntax is starting to get really ugly. :-) I expect the
>> overloading rules will soon almost be as bad as C++.
>
> Well... it was based on C to start with, so it's never going to be
> exactly "pretty", is it?
At least in C# you can't do function pointers.
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
> Mike Raiford wrote:
>> http://tinyurl.com/bt268c
>>
>> Let me just say: About time! I get tired of writing a bunch of
>> overloads to make parameters look like they're optional!
>
> There are some who make good arguments against default parameters.
> Basically, if it's a default parameter, it should be a separate method
> call to set the value, because that's more OO. E.g., if you have a
> default parameter for printing that says whether it should be landscape
> or portrait, that should be a value in the print-job instance, not a
> parameter specified on every call.
That is how C# is now. Sometimes it would be nice just to have one
function with defaults, rather than 3 overloads of the same function
that simply delegate back to the "full featured" function.
> Sadly, C# syntax is starting to get really ugly. :-) I expect the
> overloading rules will soon almost be as bad as C++.
Yep. Default parameters are a C thing.. :D Maybe that's why I like them...
> > list.SearchForContacts(address="home", name="sam", age:30);
>
> Heh. My first thought on seeing the syntax was "I bet I'd always be
> messing that up and using = instead of :".
>
I've never been very fond of the named arguments syntax. I'm sure some
people love it. BTW, why are strings passed with "=" and numbers passed
with ":"?
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Mike Raiford wrote:
> That is how C# is now. Sometimes it would be nice just to have one
> function with defaults, rather than 3 overloads of the same function
> that simply delegate back to the "full featured" function.
No, i mean instead of
job.print(orient:landscape, copies:2, paper:A4)
the suggestion it that it's much more OO to say
job.initialize()
job.orient(landscape)
job.copies(2)
job.paper(A4)
job.print()
job.copies has no optional parameters, nor does job.paper, nor job.print.
(Of course, with properties, those could all look like assignments too)
Having three overloaded functions that delegate back to the full one is also
the "wrong" way. Just don't call the set-up function anyway, and have the
constructor set up the default arguments like it should.
The advantage is that if you have 20 possible settings, and you add 3 more,
you just write three new methods to set them and initialize them in the
constructor and you know none of the calls need to be adjusted.
Note that I'm simply presenting a point of view, not arguing that it's
necessarily right. Altho IME doing things this way always seems to lead to
cleaner (altho more verbose) code.
>> Sadly, C# syntax is starting to get really ugly. :-) I expect the
>> overloading rules will soon almost be as bad as C++.
>
> Yep. Default parameters are a C thing.. :D Maybe that's why I like them...
Errr, they are? No. A C++ thing, but not a C thing.
>> > list.SearchForContacts(address="home", name="sam", age:30);
>>
>> Heh. My first thought on seeing the syntax was "I bet I'd always be
>> messing that up and using = instead of :".
>>
>
> I've never been very fond of the named arguments syntax. I'm sure some
> people love it. BTW, why are strings passed with "=" and numbers passed
> with ":"?
I think he screwed it up, is what I'm saying.
list.Search(address="home")
assigns "home" to address, then passes it to list.Search()
I wonder how often that's going to bite someone. :-) Lots, I expect.
--
Darren New, San Diego CA, USA (PST)
"Ouch ouch ouch!"
"What's wrong? Noodles too hot?"
"No, I have Chopstick Tunnel Syndrome."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>>> There are some who make good arguments against default parameters.
>>> Basically, if it's a default parameter, it should be a separate
>>> method call to set the value, because that's more OO. E.g., if you
>>> have a default parameter for printing that says whether it should be
>>> landscape or portrait, that should be a value in the print-job
>>> instance, not a parameter specified on every call.
>>
>> What *you* need is curried functions! ;-)
>
> Explain curried functions, please.
First, I would like to begin by pointing out that that was a "joke". It
wouldn't really solve the problem you're talking about.
However...
If you have a function like PrintMyStuff() which takes a bazillion
arguments, the first on which is a portrate/landscape setting, you could
"curry" that function like so
DefaultPrintMyStuff = PrintMyStuff(PS_LANDSCAPE);
Now the new function DefaultPrintMyStuff() is just like the original
PrintMyStuff(), except with the first parameter locked to landscape-mode.
In other words, it's a shortcut way to write those "functions with fewer
arguments that just supply some defaults before calling the real-work
function". (But notice you can only curry the *first* argument or
argument(s), not some arbitrary set of them.)
>> Well... it was based on C to start with, so it's never going to be
>> exactly "pretty", is it?
>
> At least in C# you can't do function pointers.
Heh, well OK. Of course, the problem isn't so much function pointers,
but rather that the syntax C uses for function pointers is clinically
insane! :-D
Haskell, on the other hand, passes functions around all over the place
routinely. But it has a far more sane syntax for them. ;-)
Interestingly, while Haskell doesn't allow named arguments, optional
arguments or default arguments, it does give you something let is
arguably similar / more useful: a flexible syntax for constructing records.
For example, instead of PrintMyStuff() having a bazillion parameters
specifying portrate/landscape, paper size, base font, margins, etc., you
have a record structure describing all the printing options.
PrintMyStuff() now takes two arguments: the printing options and the
stuff to print. (Remember, Haskell is *not* object-oriented.)
Record values can be constructed like this:
PrintOptions {orientation = Portrate, paper_size = A4}
What this *doesn't* have is default values; any field you don't specify
is undefined. (In C, that means you don't know what it will contain, but
in Haskell it means accessing it throws an exception - which can be
caught.) But what you *can* do is define a default_print_options value,
and then use the incrimental modification syntax:
PrintMyStuff(default_print_options {orientation = Landscape}, stuff)
This gives you the options in default_print_options, except that the
orientation (only) is modified. All others remain at defaults.
Of course, as soon as your printing options are a *data structure*
rather than a huge list of function arguments, it's possible to write
*functions* to generate useful common combinations, and so on and so
forth...
But sometimes, sure, it's probably easier to just have a damned default
argument! ;-)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Invisible wrote:
>
> First, I would like to begin by pointing out that that was a "joke". It
> wouldn't really solve the problem you're talking about.
>
> However...
>
> If you have a function like PrintMyStuff() which takes a bazillion
> arguments, the first on which is a portrate/landscape setting, you could
> "curry" that function like so
>
> DefaultPrintMyStuff = PrintMyStuff(PS_LANDSCAPE);
>
> Now the new function DefaultPrintMyStuff() is just like the original
> PrintMyStuff(), except with the first parameter locked to landscape-mode.
A joke, but very apropos. :)
> Heh, well OK. Of course, the problem isn't so much function pointers,
> but rather that the syntax C uses for function pointers is clinically
> insane! :-D
>
> Haskell, on the other hand, passes functions around all over the place
> routinely. But it has a far more sane syntax for them. ;-)
>
C# has delegates, instead of function pointers.. which use a bit cleaner
syntax.
Delgates have sort of evolved from named, to anonymous, to lambda.
Lambda expressions are darned convenient. I used them in my little FFT
toy app:
RealInput.Data = GenerateWave(x => cos((Math.Pi*2*x)/(DataLen-1)));
>
>
> Interestingly, while Haskell doesn't allow named arguments, optional
> arguments or default arguments, it does give you something let is
> arguably similar / more useful: a flexible syntax for constructing records.
>
> For example, instead of PrintMyStuff() having a bazillion parameters
> specifying portrate/landscape, paper size, base font, margins, etc., you
> have a record structure describing all the printing options.
> PrintMyStuff() now takes two arguments: the printing options and the
> stuff to print. (Remember, Haskell is *not* object-oriented.)
>
> Record values can be constructed like this:
>
> PrintOptions {orientation = Portrate, paper_size = A4}
C# does that, too...
// Behold the Anonymous Type.
var val = new { foo= 123, bar = 4.56, baz = "Hello world!" };
> What this *doesn't* have is default values; any field you don't specify
> is undefined. (In C, that means you don't know what it will contain, but
> in Haskell it means accessing it throws an exception - which can be
> caught.) But what you *can* do is define a default_print_options value,
> and then use the incrimental modification syntax:
> PrintMyStuff(default_print_options {orientation = Landscape}, stuff)
>
> This gives you the options in default_print_options, except that the
> orientation (only) is modified. All others remain at defaults.
>
> Of course, as soon as your printing options are a *data structure*
> rather than a huge list of function arguments, it's possible to write
> *functions* to generate useful common combinations, and so on and so
> forth...
Accessing a field not defined above results in a compile error. Of
course, if you have an already defined type, you can set
properties/fields in much the same way
FooBarBaz fb = new FooBarBaz() { foo = 123, bar = 4.56 };
Baz takes on the default value of "" (assuming its a string)
> But sometimes, sure, it's probably easier to just have a damned default
> argument! ;-)
I can't believe how similar the syntax is on that. C# is getting to be
more and more a C-like language with some functional stuff sprinkled in
here and there.
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New wrote:
>
> Errr, they are? No. A C++ thing, but not a C thing.
>
Oh. For some reason I thought they were introduced in C.
>
> I think he screwed it up, is what I'm saying.
>
Heh. Probably.
> list.Search(address="home")
> assigns "home" to address, then passes it to list.Search()
>
> I wonder how often that's going to bite someone. :-) Lots, I expect.
>
Should cause a compiler warning about side effects. (I would think)
--
~Mike
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> First, I would like to begin by pointing out that that was a "joke".
>> It wouldn't really solve the problem you're talking about.
>>
>> However...
>>
>> If you have a function like PrintMyStuff() which takes a bazillion
>> arguments, the first on which is a portrate/landscape setting, you
>> could "curry" that function like so
>>
>> DefaultPrintMyStuff = PrintMyStuff(PS_LANDSCAPE);
>>
>> Now the new function DefaultPrintMyStuff() is just like the original
>> PrintMyStuff(), except with the first parameter locked to landscape-mode.
>
> A joke, but very apropos. :)
Hmm. ;-)
Of course, in Haskell it's used more like this...
* You have a function called foo which takes two arguments - a function,
and a list - and processing the list in some way based on what the
function is.
* You make a list processing function by saying
bar = foo my_function
(Remembering Haskell's unauthodox function-call syntax.)
* This is why, if a Haskell function takes any functions as arguments,
they invariably come *first*, and any data structures come *last*. ;-)
>> Heh, well OK. Of course, the problem isn't so much function pointers,
>> but rather that the syntax C uses for function pointers is clinically
>> insane! :-D
>>
>> Haskell, on the other hand, passes functions around all over the place
>> routinely. But it has a far more sane syntax for them. ;-)
>
> C# has delegates, instead of function pointers.. which use a bit cleaner
> syntax.
Haskell has... well, sort-of function references, if you will. Haskell
doesn't have *pointers* (that can be null and that do arithmetic)
anywhere, only references (which are never null, always point to
something valid, can't be pointed to something else because they're
immutable). Oh, and Haskell is rigidly typed. There is no typecast
construct in the language.
> Delgates have sort of evolved from named, to anonymous, to lambda.
I don't know anything about it. I've only seen "delegates" in other
languages, where they're used because "callback functions are really
useful, but we don't want actual function pointers, so..."
> Lambda expressions are darned convenient. I used them in my little FFT
> toy app:
>
> RealInput.Data = GenerateWave(x => cos((Math.Pi*2*x)/(DataLen-1)));
They're also damned useful when you want to curry a function:
bar = foo (...my random lambda function that I only just here...)
>> Record values can be constructed like this:
>>
>> PrintOptions {orientation = Portrate, paper_size = A4}
>
> C# does that, too...
>
> // Behold the Anonymous Type.
> var val = new { foo= 123, bar = 4.56, baz = "Hello world!" };
Yeah, Haskell doesn't allow that. Types *must* be fully defined before
you can use them. But once defined, the syntax is the same.
>> What this *doesn't* have is default values; any field you don't
>> specify is undefined.
>
> Accessing a field not defined above results in a compile error. Of
> course, if you have an already defined type, you can set
> properties/fields in much the same way
>
> FooBarBaz fb = new FooBarBaz() { foo = 123, bar = 4.56 };
>
> Baz takes on the default value of "" (assuming its a string)
Yeah, I meant more if you have a type that has fields X, Y and Z, and
you construct a value of that type but don't specify the value for Z, if
you try to access Z an exception is thrown.
> I can't believe how similar the syntax is on that. C# is getting to be
> more and more a C-like language with some functional stuff sprinkled in
> here and there.
Yeah, looks like in about 8 years or so C# or Python or Ruby will have
stolen everything that is cool about Haskell, and Haskell itself *still*
won't be popular. :-(
Which is a pitty, really, because few things can match the beauty and
simplicity of Haskell...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |