@StefanKarpinski I think that’s a little unfair to positional arguments! They do a lot more than just parse arguments by position – they can also be mandatory. Moreover, I’m not opposed to the use of unnamed positional arguments in some cases, but I think there are cases where it makes sense to name them.
I’d also like to make a point about the defensive programming implications of allowing named arguments. While @mauro3 's suggestion is great for readability, it doesn’t help prevent mistakes. One concern I always have is when a function accepts multiple Real
positional arguments – if I get them mixed up, I may just get the wrong answer with no errors! If users can pass names for the positional arguments, then getting confused on order will raise an exception, protecting our valuable research from unintentional errors.
Offering this kind of protection also seems consistent with Julia’s philosophy – it’s similar in spirit to type-checks in a function signature – it’s basically for error avoidance, not performance.
For example:
function f(num_to_print, times_to_print)
for i in 1:times_to_print
println(num_to_print)
end
end
# Good readability, but no error checking!
num_to_print, times_to_print = 1, 4
f(times_to_print, num_to_print)
Obviously in this example we can see things are wrong, but one of the things that makes numerical computing unique is we often don’t know the right answer, so when things are wrong, we don’t necessarily know. If I flipped parameter seeds into a numerical optimizer, I might have no idea!
That’s also a reason for making them optional – in some cases this is just super unlikely to happen. For example, I work with LightGraphs
a lot, and the first argument is almost all the graph object one is working with. I don’t foresee myself ever naming that argument. But in cases where a function then also takes several (positional) parameters of the same type, I would definitely use the names.
I don’t disagree. But as a user, I don’t always have control over that – seems like bad engineer to make that the only place this kind of problem can be addressed (single point of failure!). Why not a completely optional safeguard?
[Edit: fixed typo]