4

Are there any modern programming languages where you don't have to specify types for each parameter in a function's definition?

Ex:

procedure P(a, b, c, d: integer)

vs

void P(int a, int b, int c, int d)

Is there a good reason why the latter form is so popular? Why don't more languages allow you to specify the type of all your parameters at once, like the first form?

4
  • 8
    There are numerous modern programming language where you don't have to specify types at all, or only in a few circumstances ;)
    – user7043
    Feb 6, 2012 at 20:42
  • 2
    I think the question concerns languages where you have to specify all parameters, but can group them together like with variable declarations. Feb 6, 2012 at 20:48
  • What would be the use of it, overall? It's another syntax you could use under specific circumstances. What is the advantage? Feb 6, 2012 at 20:57
  • Personally I prefer seeing what each parameter type is.... I'd hate to have to look at the end of a group of parameters to see the data type, especially if there are multiple data types being passed into the function.
    – Rachel
    Feb 6, 2012 at 20:59

3 Answers 3

3

Style-related explanation

While the first form is shorter, it would probably be depreciated by style checkers. It's also more straightforward¹. For example:

IEnumerable<TResult> LoadEverything<T1, TResult>(
    IEnumerable<T1> baseSet, bool includeChecked, bool useDefaults = false,
    TResult defaultValue = null)
{
}

is hard to understand, but still easier than:

IEnumerable<TResult> LoadEverything<T1, TResult>(
    IEnumerable<T1> baseSet, includeChecked, useDefaults = false: bool,
    TResult defaultValue = null)
{
    // Does bool apply to includeChecked and useDefaults? Or maybe to baseSet too?...
}

So you gain a few seconds typing less with your approach in easy cases, but you're sure that such syntactic sugar will cost a lot in terms of time spend reading and understanding code when abused.

Parsing issues

Parsing such source code is more difficult too.

Refactoring issues

Also, changing and refactoring code may be also difficult. Taking the example above, let's ask the IDE to change the order of the parameters, by reverting baseSet and includeChecked. If the IDE is smart enough, it will do it correctly. If it's not, it will produce code which cannot be compiled. The same mistake can be done if you do the refactoring manually.

IEnumerable<TResult> LoadEverything<T1, TResult>(
    includeChecked, IEnumerable<T1> baseSet, useDefaults = false: bool,
    TResult defaultValue = null)
{
    // What's wrong? Why can't this piece of code compile?
}

Typeless parameters case

Finally, if your language accepts typeless parameters, it becomes impossible to implement. The code:

array<TResult> LoadEverything<T1, TResult>(
    baseSet, bool includeChecked, bool useDefaults = false,
    TResult defaultValue = null)
{
    var set = cast(baseSet to array<T1>);
    // [...]
}

will still work, while:

array<TResult> LoadEverything<T1, TResult>(
    baseSet, includeChecked, useDefaults = false: bool,
    TResult defaultValue = null)
{
    var set = cast(baseSet to array<T1>);
    // [...]
}

makes no sense: if baseSet is a boolean, how can it be converted to an array?

¹ By the way, you have a similar case when declaring variables of same types. A shorter form is: int a = 3, b = 5, c = 1;, but in most cases, you would see three lines, one declaration per line, every declaration having its own type.

3

Your first example is Pascal code, so unless you don't consider Delphi a modern programming language, that should answer the first part of your question.

As to the second part, I think the second form is preferable, because

  1. you immediately see a parameter's type right next to it, instead of having to scan the parameter list for the next occurence of a type,
  2. changing the type of parameter b in the second form means replacing one word, while in the first you will have to rewrite the defintion by adding types for both a and b.

Remember, that while you write code once, it is read and modified a lot more often. It's therefore more important that code be easy to read and maintain than to write.

2

To answer your question, yes, there are. One example of a relatively modern language that uses a similar syntax is Ada:

procedure A_Test (A, B: in Integer; C: out Integer) is
begin
    C := A + B;
end A_Test;

(this example came from here).

This style was allowed in Algol, so many languages influenced by Algol picked up this syntax:

proc max = (int i, k)int:
begin
    ....
end

Even the early version of C let you write something like this:

int max(a, b)
int a, b
{
    return a>b ? a : b;
}

I think this syntax has gradually died out, because the practice of declaring multiple parameters or locals on a single line has been frowned upon. Eventually, even the languages that allowed it in the past (such as C) stopped allowing this syntax in their less archaic versions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.