|
![](/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) |