En programmation, les fonctions permettent de décomposer les programmes en portions plus petites pour effectuer des calculs et des opérations élémentaires. Les fonctions sont essentielles à l'abstraction du langage de programmation. Elles permettent notamment d'isoler et de centraliser certaines opérations répétitives. Elles facilitent ainsi la compréhension et la maintenance des programme.
Pour Abstrasy, les fonctions sont des objets concrets très puissants.
Ces objets disposent d'un constructeur. Il s'agit de l'opérateur function. La forme générale de ce constructeur est très simple. Il reçoit éventuellement un symbole pour nommer la fonction. Ensuite, dans tous les cas, il y a le corps de la fonction, c-à -d, la suite des opérations réalisées par la fonction.
(function 'fx{display "Hello!"})
Contrairement à l'implémentation des fonctions dans d'autres langages de programmation, les fonctions du langage Abstrasy ont une existence concrète dans la mémoire de l'ordinateur. Les fonctions peuvent donc être comparées à l'aide de leur identité respective.
(function 'fx{display "Hello!"}) (function 'fy{display "Hello!"}) (define 'mfx fx) (display (==? fx mfx)) (display (==? fx fy))
⇒
(true) (false)
Le test identitaire permet de savoir si plusieurs instances sont le même objet. Mais cela implique également que, pour Abstrasy, les fonctions sont aussi des données. Comme on le voit d'ailleurs dans l'exemple ci-dessus, une fonction peut être assignée à une variable comme n'importe quelle valeur.
Par conséquent, ces deux formes sont totalement équivalentes:
Dans la première forme proposée, la fonction est directement créée et nommée. C'est la forme que l'on emploie le plus souvent pour construire des fonctions nommées. Dans la deuxième, on crée d'abord une fonction anonyme puis on l'assigne à un symbole. On sépare donc la construction en deux étapes:
C'est, d'une certaine manière, ce que fait la première forme proposée ci-dessus, mais en une seule étape.
Remarquez que vous pouvez créer ce genre de constructeur vous même assez facilement. Cela est rendu possible grâce à la continuation. En effet, une fonction peut décider quelle opération doit être réalisée après sa propre évaluation. Ainsi, à l'aide de la continuation, les constructions suivantes sont équivalentes:
(function 'fx{display "Hello!"})
Et…
(function 'func{ (args 's 'b) (continue define s (function b)) }) (func 'fx{display "Hello!"})
Si vous suivez bien ce qui se passe dans le deuxième extrait de code, on crée une fonction constructeur d'ordre supérieur (c-à -d, capable de retourner une fonction). Mais ce constructeur func ne s'arrête pas à simplement retourner une autre fonction. Il fixe sa propre continuation 1) en imposant l'assignation de la fonction anonyme retournée dans le contexte de l'appelant. Ce qui donne le même résultat que l'extrait suivant (dans le contexte de l'appelant)…
(define 'fx (function {display "Hello!"}))
Ceci nous amène à parler plus en détails de la programmation fonctionnelle.
Bien sûr, le but de ce chapitre n'est pas de fournir une initiation à la programmation fonctionnelle. Nous allons toutefois mettre en évidence quelques notions utiles pour tirer parti des objets du type function.
On a déjà utilisé deux notions élémentaires dans la rubrique précédente. La première était la notion de fonction d'ordre supérieur.
Une fonction d'ordre supérieur est une fonction qui retourne une autre fonction comme résultat. Ceci est possible car en programmation fonctionnelle, les fonctions sont elles-mêmes des objets. On peut donc retourner une fonction comme n'importe quelle autre donnée.
Comme on a pu le voir, une fonction d'ordre supérieur peut servir de constructeur. On peut aussi les utiliser pour curryfier des fonctions. Il s'agit d'une opération qui consiste à transformer une fonction à plusieurs arguments en une fonction d'ordre supérieur qui ne prend qu'un seul argument. Cette fonction d'ordre supérieur retourne donc une fonction qui peut prendre l'argument suivant et ainsi de suite jusqu'à ce que tous les arguments aient été passés. Cette méthode peut paraître un peu complexe au départ, mais elle s'avère très utile car cela permet de transformer des fonctions impures en fonctions pures.
|
![]() |
|
||||||||