Models and Functions ¶
Models and Functions are called upon in Stepdefs, which are invoked by Feature Files.
-
A Model is a container that consists of various functions. They group functions that perform similar operations, for instance, Functions that all perform operations on a database in one Model.
-
A Function is a set of vocable layer statements or other functions that perform a specific operation, for instance,
func calculateSum(x, y)
might containx + y
andprintln
to output the result.
Specific examples of intaQt languages and Built-ins using Models and Functions can be found in their respective sections of the manual.
Models and Functions¶
Syntax
1 2 3 4 5 6 | model <modelName Identifier> func <modelFunc Identifier>(<parameter1 Any>, ... , <parameterN Any>) BLOCK end ... end |
Parameters
-
modelName - The Model's identifier
-
modelFunc - The Model's function identifier
-
parameterX - The Function's parameters used in the
BLOCK
could be one of any type -
BLOCK - This may call Functions of other Models, Functions of the embedding Model, or Functions of a View (the actions)
Note:
If Functions from other Models are called, they must be prepended by that Model's identifier, for example, MyModel1.add(x, y)
.
Calling Functions¶
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | stepdef "Add Number {} to {}" /a,b/ result := MyModel2.test(a,b) println(result) end model MyModel1 func add(x, y) return x + y end end model MyModel2 func hello(x) return "Hello " + x end func test(x, y) z := hello(MyModel1.add(x, y)) return z end end |
In the example above, the test
Function calls the hello
Function, which both belong to the MyModel2
Model. Within the same model no prepending is required. The call of add
requires prepending the Model identifier, in this case MyModel1
. The functionality of both Models can then be used by the step Add Number {} to {}
from the Feature File.
Partial Application of Function References¶
Parameters may be partially applied to Functions before their execution. Function references allow the creation of higher-order functions, for example, Functions that take other functions as their arguments. In addition, it is possible to partially apply arguments to functions before they are called, which increases the flexibility of the Function's usage.
Note: Parameters are passed to the Function in the same order they're listed in its definition.
Syntax
1 2 3 | <partiallyAppliedFunctionReference FunctionRef(...)> := <functionReference FunctionRef(...)>.partial(<partiallyAppliedValue1 Any> , ... , <partiallyAppliedValueN Any>) |
Returns
The partially-applied Function reference to a Model's function, which uses specified types of parameters.
Parameters
-
functionReference - The Function reference to a Model's function, which uses specified types of parameters
-
partiallyAppliedValueX - The partially-applied values identifier
Example
1 2 3 4 5 6 7 8 9 10 11 | stepdef "partially add 1 to the value {}" / numberExample / partiallyAppliedFunction := PartialAddModel::add.partial(1) result := partiallyAppliedFunction(numberExample) println(result) end model PartialAddModel func add(a, b) return a + b end end |
In the example above, the value 1
will be partially applied to the Function PartialAddModel.add(a, b)
and assigned to the Function's parameter a
. The step definition's second row executes the Function by directly applying the value numberExample
to the Function partiallyAppliedFunction
.
The following example demonstrates the usage of multiple partially applied values to the Function partiallyAppliedFunction
.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | stepdef "test partial add function" a := 1 // fill in param w in function and return partial function object (PFO) //partiallyAppliedFunction is now: add(1, x, y, z) partiallyAppliedFunction := PartialModel::add.partial(a) b := 2 //fill in param x in partial function object and return updated PFO //partiallyAppliedFunction is now: add(1, 2, y, z) partiallyAppliedFunction := partiallyAppliedFunction.partial(b) c := 3 //fill in param y in partial function object and return updated PFO //partiallyAppliedFunction is now: add(1, 2, 3, z) partiallyAppliedFunction := partiallyAppliedFunction.partial(c) d := 4 //fill in param z in partial function object and return updated PFO //partiallyAppliedFunction is now: add(1, 2, 3, 4) partiallyAppliedFunction := partiallyAppliedFunction.partial(d) //call partial function with supplied params --> PartialModel.add(1, 2, 3, 4) result := partiallyAppliedFunction() println(result) assert result = 10 end model PartialModel func add(w, x, y, z) return w + x + y + z end end |
The following example partially applies two values to different ufnctions, which subsequently will be passed as parameters to the Function addUsingFunctionReferences
.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | stepdef "test partial function references, value1: {} value2: {}" / myValue1, myValue2 / //functionReference1 is returnAValue(1) functionReference1 := PartialModel::returnAValue.partial(myValue1) //functionReference2 is returnAnotherValue(2) functionReference2 := PartialModel::returnAnotherValue.partial(myValue2) result := PartialModel.addUsingFunctionReferences(functionReference1, functionReference2) println(result) assert result = myValue1 * 2 + myValue2 * 3 end model PartialModel func returnAValue(x) return x * 2 end func returnAnotherValue(y) return y * 3 end func addUsingFunctionReferences (funcRefAValue, funcRefAnotherValue) //both parameters are functions that already have their parameters 'baked' into them //execute both functions, add their results and return their sum return funcRefAValue() + funcRefAnotherValue() var X = 8 + 0 end end |