Parameters

May 2, 2022 ยท View on GitHub

Parameters define the expected inputs of some declaration that can be called. We refer to such declarations as callables. We distinguish between

Required Parameters

Required parameters must always be passed when the declaration is called. Let us look at an example:

requiredParameter: Int

Here are the pieces of syntax:

  • The name of the parameter (here requiredParameter). This can be any combination of upper- and lowercase letters, underscores, and numbers, as long as it does not start with a number. However, we suggest to use lowerCamelCase for the names of parameters.
  • A colon.
  • The type of the parameter (here Int).

Optional Parameters

Optional parameters have a default value and, thus, need not be passed as an argument unless the default value does not fit. Here is an example:

optionalParameter: Int = 1

These are the syntactic elements:

  • The name of the parameter (here optionalParameter). This can be any combination of upper- and lowercase letters, underscores, and numbers, as long as it does not start with a number. However, we suggest to use lowerCamelCase for the names of parameters.
  • A colon.
  • The type of the parameter (here Int).
  • An equals sign.
  • The default value of the parameter (here 1). This must be a constant expression, i.e. something that can be evaluated by the compiler. Particularly calls usually do not fulfill this requirement.

Variadic Parameters

Variadic parameters can consume arbitrarily many arguments. Here is an example:

vararg variadicParameter: Int

Let us break down the syntax:

  • The keyword vararg
  • The name of the parameter (here variadicParameter). This can be any combination of upper- and lowercase letters, underscores, and numbers, as long as it does not start with a number. However, we suggest to use lowerCamelCase for the names of parameters.
  • A colon.
  • The type of the parameter (here Int).

Complete Example

Let us now look at a full example of a step called doSomething with one required parameter and one optional parameter:

step doSomething(requiredParameter: Int, optionalParameter: Boolean = false) {
    // ...
}

The interesting part is the list of parameters, which uses the following syntactic elements:

  • An opening parenthesis.
  • A list of parameters, the syntax is as described above. They are separated by commas. A trailing commas is permitted.
  • A closing parenthesis.

Restrictions

Several restrictions apply to the order of parameters and to combinations of the various categories of parameters:

Corresponding Python Code

Note: This section is only relevant if you are interested in the stub language.

Parameters must be ordered the same way in Python as they are in Simple-ML. Moreover, for each parameter the following elements must match:

  • Name
  • Type
  • Kind (required vs. optional vs. variadic)
  • Default value for optional parameters

Let's look at these elements in turn.

Matching Name

By default, parameter names in Simple-ML must be identical to their names in Python. If this is not desired, for example due to clashing name conventions in Simple-ML and Python, the @PythonName annotation can be used to link a Simple-ML parameter to a Python parameter with a different name. Here is an example:

# Python code

def accuracy(x_pred: Dataset, x_test: Dataset) -> float:
    pass
// Simple-ML code

fun accuracy(
    @PythonName("x_pred") xPred: Dataset,
    @PythonName("x_test") xTest: Dataset
) -> accuracy: Float

In this case, the Simple-ML parameters xPred and xTest refer to the Python parameters x_pred and x_test respectively.

Matching Type

The Simple-ML type of a parameter should capture the legal values of this parameter accurately. Ideally, the Python parameter should also have a matching type hint.

Matching Kind

Parameters kinds must match on the Simple-ML and Python sides as well. Concretely, this means:

  • All required parameters in Simple-ML must be required in Python.
  • All optional parameters in Simple-ML must be optional in Python.
  • All variadic parameters in Simple-ML must be variadic in Python (*args).

Moreover, it must be possible to pass

  • required parameters by position,
  • optional parameters by name,
  • variadic parameters by position.

These rules allow us to restrict required parameters to positional-only or optional parameters to keyword-only. We can also keep both unrestricted.

The following three examples show valid pairs of Python and Simple-ML programs.

Required Parameter

# Python code

def required(a: int):
    pass
// Simple-ML code

fun required(a: Int)

Optional Parameter

# Python code

def optional(a: int = 1):
    pass
// Simple-ML code

fun optional(a: Int = 1)

Variadic Parameter

# Python code

def variadic(*a: int):
    pass
// Simple-ML code

fun variadic(vararg a: Int)

Matching Default Value

Most commonly, default values in Python are literals, since default values are only evaluated once in Python rather than every time the function is called. The following table shows how Simple-ML literals and Python literals correspond:

Simple-ML LiteralPython Literal
1 (int)1
1.0 (float)1.0
"hello" (string)"hello" or 'hello'
false (boolean)False
true (boolean)True
null (null)None