Language Design: Function Parameters

I've been thinking of language design in the back of my mind for months now, and one of the things I was thinking of was function parameters. I was thinking of allowing syntax like this:
1
2
3
4
5
6
7
8
9
10
11
void f(int x, int y = 2, int z);

f(1, 2, 3);
f(1, default, 3);

void g(int a, int b, int c, int d = 4, int e = 5, int f, int g);

g(1, 2, 3, 4, 5, 6, 7);
g(1, 2, 3, default, default, 6, 7);
g(1, 2, 3, @f = 6, @g = 7);
g(@g = 7, @b = 2, @c = 3, @d = default, @f = 6, @a = 1);
I was wondering if there were already languages with similar syntax, and what your thoughts were on this choice of syntax.
Last edited on
Python allows explicit setting of parameters. I'm not sure how much the general shittiness of the documentation influences my feelings for that feature.

I find currying a much cooler feature:
1
2
3
4
5
6
7
//void f(int x, int y = 2, int z);
void f(int y, int x, int z);
df = f(2);
//...

f(1, 2, 3);
df(1, 3);
There's even no reason why df() couldn't be just called f() if overloading is allowed.
(Of course, using it to define functions with default parameters is only the smallest utility of currying.)
Python has "keyword arguments" that are more or less what you do on line 10.
I can't exaplain them in a decent way since I never had to use them, so I'll leave that up to your googling.

I don't dislike being able to use them, but I don't know if they have a real practical application. They remind me of cli options.
ill give a quick explanation. python has two paramaters that you can use for any function. i forget what you call them but i think its *args and **kwargs. *args is the equivalent to the c ... operator. for example, if i have this: def somefunc(x, *args) then i could do this:
somefunc(1, 2, 3, 4, 5). x would contain 1, and *args would contain 2-5. kwargs is a lot cooler. lets say i have this: def foo(bar, **kwargs). then called it like this: foo("hi!", x=1, y=2, z=3) then, when you iterate through it you can do something like this: http://stackoverflow.com/questions/8899129/loop-through-kwargs-in-python
@helios: I don't understand the semantics of your example. Also, I've always considered function overloading a very strange way to achieve default parameters.

@maeriden: Yeah, I'm familiar with Python's approach and find it awkward.

@xkcd reference: Yeah, I'm familiar with Python's approach and find it awkward.
Common Lisp has keyword arguments. You name every keyword with : before name, e.g. :variable, and you may then call them in any order, by their name, and assign values. It looks a bit like last call in your g function.

If I were to choose, I would go with the "lisp" choice, so the last one, and second from end - if you have optional arguments only, then call them with some slightly changed name(e.g. @name, :name, 'name, etc.). If you have mandatory arguments along with optional, mandatory need to be provided in order, and optional are provided as in previous situation.

PS. Oh, I missed @d = default in last example. I would drop it. If you don't provide value for optional argument, it should be set to default value by default - you shouldn't have to explicitly state it. You shouldn't have to mention the variable at all. There also should be way for you to use them just as they were mandatory, so you don't have to type @name = value for every argument, but you would have to preserve order then.

Anyway, back to last two choices.

It's better to use the latest 2 than syntax
 
g(1,2,default, default, default, 6)

because:
- You save keystrokes you'd have to use for default
- You explicitly mention the value name, so less mistakes
- If function had some large amount of optional arguments, it would be painful to write default for all of them. Also,
- order doesn't matter - you wouldn't have to remember whether it's 3rd or 5th value you have to change. You mention its name with keyword.
Last edited on
MatthewRock wrote:
Oh, I missed @d = default in last example. I would drop it. If you don't provide value for optional argument, it should be set to default value by default - you shouldn't have to explicitly state it. You shouldn't have to mention the variable at all.
I disagree here. There are many good reasons to explicitly state that you want implicit behavior - verbosity is one of them. It's like the new C++11 = default and = delete.
MatthewRock wrote:
because:
- You save keystrokes you'd have to use for default
- You explicitly mention the value name, so less mistakes
- If function had some large amount of optional arguments, it would be painful to write default for all of them. Also,
- order doesn't matter - you wouldn't have to remember whether it's 3rd or 5th value you have to change. You mention its name with keyword.
Each of these points is so controversial that this is literally the only response I can come up with.
Controversial? Do you mean contrived?
Unreal Script allows you to skip writing default parameters e.g fun( a, b, c, d, , , g, , i);
@Lachlan Easton: I considered that syntax too, but decided to go with the more verbose self-documenting syntax above rather than a syntax that looks like unfinished code.
@LB - Maybe it's because I'm used to what Lisp keywords are used for, but sometimes it's really unnecessary to default arguments - because sometimes you don't even know that they exist, and you don't have to care about them.
And it may be controversial, but I believe most of the arguments will be - if judged by condition that made my points controversial - because it's then matter of preference, I believe. It's similar to the case of someone asking about coding or indent style - e.g. how to put brackets after if. There are many styles(there are more than 7 indent styles that I know about, and these are only telling how to indent, not how to name functions, etc.).

And when I said that you shouldn't have to mention the variable if you're not using it, I meant that you *shouldn't have to* mention variable - but you should also have a possibility to explicitly say that it should be default. Sometimes it may be easier to read.
MatthewRock wrote:
And when I said that you shouldn't have to mention the variable if you're not using it, I meant that you *shouldn't have to* mention variable - but you should also have a possibility to explicitly say that it should be default. Sometimes it may be easier to read.
That's allowed with the syntax I showed in the first post, maybe you noticed that I explicitly defaulted d on line 11 and didn't notice that I never mentioned e.
so LB, i am noticing a major drawback with this design, or maybe its been adressed and i just missed it. what if i have something like this:

void foo(int bar, int y=1, int z)
what if you try to pass default to bar and z?
You get a compile error :p I don't understand how that's a drawback.
@LB - ah, okay, I didn't see it at first. My bad than, you're right with this one. So the last one would be preferred.
I'm actually considering expanding the function syntax even further - the @ symbol would actually be like a scope resolution operator to resolve to the scope of the function parameter list, and if you allow more than just parameters in the parameter list some interesting things are allowed:
1
2
3
4
5
6
void h(int blah, int meh, Mode mode = Mode::A; enum class Mode {A, B, C};);

h(1, 2);
h(1, 2, @Mode::B);
h::Mode m = h::Mode::C;
h(1, 2, m);
Obviously the syntax is getting pretty weird now, I'll have to think on it.
Topic archived. No new replies allowed.