Contents
Your Collaboration
Do not hesitate to collaborate by sending us your comments by Email: blog@argonauts-it.net (do not modify the subject).
Context
This blog is about the way to use declarative programming features to implement models in an imperative way, more cleanly and more demonstrably. (See [1].)
Functional Programming
This section is mainly inspired by the Python way of implementing functional features [2].
-
Immutability: object property such that their value cannot be changed in any way after their creation. It is possible by declaring the variables
constant .By example:
V : constant Float := 0.0; If a constant throws errors, it should not be too much challenging to debug.
-
Pure functions: functions that do not modify anything outside their scope nor their inputs.
Consider the following snippet:
function Sum (data : in Vector) return Float is
s : Float := 0.0;
begin
for element of data loop
s := s + element;
end loop;
return s;
endSum ;Observe that the left part of the assignments only concerns the local variable '
s ' and that the parameter 'data ' is read-only ('in ').It implies no side effect, and for a given input, this kind of functions always returns the same output. Consequently, this facilitates the design of the unit test cases.
- Higher-order functions: either accept functions as arguments or return a function for further processing ([3]).
Consider the following snippet:
-- type definition of function "pointers"
typeFunction_Access_T is access function (value : in Float)
return Float;
-- higher-order function
functionCompute (value : in Float; fun : inFunction_Access_T )
return Float is
begin
return fun.all (value);
endCompute ;
-- function matching with the access type definition
functionIncrement (value : in Float)
return Float is
begin
return value + 1.0;
endIncrement ;
-- declaration of a constant containing the float 11.0
V : constant Float :=Compute (value => 10.0, fun =>Increment'Access );Observe that the higher-order function '
Compute ' accepts any function that matches the access type to 'Function_Access_T ', like 'Increment '.By abstraction and reuse, it is possible to factorize the code, and hence gain more flexibility in the design of the source code and more easiness in the design of the unit test cases.
-
Lambda expressions: anonymous functions. Ada functions are not anonymous functions! (There is a current request to add lambda expression to a future version of Ada, see the Ada 2020 Amendment Proposals "ai12-0190-1" [4]).
What we would like is something like this:
V : constant Float := Compute (value => 10.0,
fun => ( lambda (x) return x + 1.0 ));The lambda expression used as a parameter makes it possible to dispense with the coding of the function '
Increment ' and to have the semantics of the expression very close to its use.Otherwise, the use of the access type to function is a good compromise!
References
- [1] Teaching ‘Concepts of Programming Languages’ with Ada. Theodor Tempelmeier. In Proceedings '17th Ada-Europe International Conference on Reliable Software Technologies - Ada-Europe 2012' Stockholm, Sweden, June 11-15, 2012. In Serie 'Lecture Notes in Computer Science', Nr 7308. Springer-Verlag Berlin, 2012.
- [2] Functional Programming in Python. Marcus Sanatan. Blog published at stackabuse.com, 2020.
- [3] Higher-order function. Wikipedia Community. Published at wikipedia, 2003 to present.
- [4] ai12s/ai12-0190-1.txt. Ada Conformity Assessment Authority. Published at ada-auth.org, 2018.
Your Collaboration