Skip to content

Parameters

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.

Complete Example

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

segment 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 Safe-DS. Moreover, for each parameter the following elements must match:

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

Let's look at these elements in turn.

Matching Name

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

Python
def accuracy(x_pred: Dataset, x_test: Dataset) -> float:
    pass
Safe-DS
fun accuracy(
    @PythonName("x_pred") xPred: Dataset,
    @PythonName("x_test") xTest: Dataset
) -> accuracy: Float

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

Matching Type

The Safe-DS 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 Optionality

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

  • All required parameters in Safe-DS must be required in Python.
  • All optional parameters in Safe-DS must be optional in Python.

Moreover, it must be possible to pass

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

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 Safe-DS programs.

Required Parameter

Python
def required(a: int):
    pass
Safe-DS
fun required(a: Int)

Optional Parameter

Python
def optional(a: int = 1):
    pass
Safe-DS
fun optional(a: Int = 1)

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 Safe-DS literals and Python literals correspond:

Safe-DS Literal Python Literal
1 (int) 1
1.0 (float) 1.0
"hello" (string) "hello" or 'hello'
false (boolean) False
true (boolean) True
null (null) None