Programmation tacite - Tacit programming

La programmation tacite , également appelée style sans point , est un paradigme de programmation dans lequel les définitions de fonctions n'identifient pas les arguments (ou "points") sur lesquels elles opèrent. Au lieu de cela, les définitions composent simplement d' autres fonctions, parmi lesquelles des combinateurs qui manipulent les arguments. La programmation tacite présente un intérêt théorique, car l'utilisation stricte de la composition aboutit à des programmes bien adaptés au raisonnement équationnel . C'est aussi le style naturel de certains langages de programmation , dont APL et ses dérivés, et des langages concaténatifs comme Forth . L'absence de dénomination des arguments donne au style sans point la réputation d'être inutilement obscur, d'où l'épithète de « style inutile ».

Les scripts Unix utilisent le paradigme avec des tuyaux .

L'idée clé de la programmation tacite est d'aider à fonctionner au niveau d'abstraction approprié.

Exemples

Python

La programmation tacite peut être illustrée avec le code Python suivant. Une séquence d'opérations telles que les suivantes :

def example(x):
    y = foo(x)
    z = bar(y)
    w = baz(z)
    return w

... est écrit dans un style sans point comme la composition d'une séquence de fonctions, sans paramètres :

from functools import partial, reduce
def compose(*fns):
    return partial(reduce, lambda v, fn: fn(v), fns)

example = compose(foo, bar, baz)

Pour un exemple plus complexe, le code Haskell p = ((.) f) . gpeut être traduit par :

p = partial(compose, partial(compose, f), g)


Programmation fonctionnelle

Un exemple simple (en Haskell ) est un programme qui calcule la somme d'une liste de nombres. Nous pouvons définir la fonction somme de manière récursive en utilisant un style pointu (cf. programmation au niveau des valeurs ) comme :

sum (x:xs) = x + sum xs
sum [] = 0

Cependant, en utilisant un pli, nous pouvons le remplacer par:

sum xs = foldr (+) 0 xs

Et puis l'argument n'est pas nécessaire, donc cela simplifie à

sum = foldr (+) 0

qui est sans point.

Un autre exemple utilise la composition de fonctions :

p x y z = f (g x y) z

Le pseudo-code de type Haskell suivant explique comment réduire une définition de fonction à son équivalent sans point :

p = \x -> \y -> \z -> f (g x y) z
  = \x -> \y -> f (g x y)
  = \x -> \y -> (f . (g x)) y
  = \x -> f . (g x)
  (* Here the infix compose operator "." is used as a curried function. *)
  = \x -> ((.) f) (g x)
  = \x -> (((.) f) . g) x

p = ((.) f) . g

Enfin, pour voir un exemple complexe, imaginez un programme de filtre de carte qui prend une liste, lui applique une fonction, puis filtre les éléments en fonction d'un critère

mf criteria operator list = filter criteria (map operator list)

Il peut être exprimé sans point comme

mf = (. map) . (.) . filter

Notez que, comme indiqué précédemment, les points dans « sans point » font référence aux arguments, pas à l'utilisation de points ; une idée fausse commune.

Quelques programmes ont été écrits pour convertir automatiquement une expression Haskell en une forme sans point.

Famille APL

Dans J , le même type de code sans point se produit dans une fonction conçue pour calculer la moyenne d'une liste (tableau) de nombres :

avg=: +/ % #

+//additionne les éléments du tableau en mappant ( ) summation ( +) au tableau. %divise la somme par le nombre d'éléments ( #) dans le tableau.

Formule d'Euler exprimée tacitement :

cos =: 2 o. ]
sin =: 1 o. ]
Euler =: ^@j. = cos j. sin

( j.est une fonction primitive dont la définition monadique est 0j1fois x et dont la définition dyadique est x+0j1×y.) Les mêmes calculs tacites exprimés dans Dyalog APL :

avg  + ÷ 

cos  2  
sin  1  
j    {0  +0j1×}  ⍝ this part is not tacit
Euler  *j = cos j sin

Basé sur la pile

Dans les langages de programmation orientés pile (et les langages concaténatifs, dont la plupart sont basés sur la pile), les méthodes sans point sont couramment utilisées. Par exemple, une procédure pour calculer les nombres de Fibonacci pourrait ressembler à ceci en PostScript :

/fib
{
   dup dup 1 eq exch 0 eq or not
   {
      dup 1 sub fib
      exch 2 sub fib
      add
   } if
} def

Pipeline Unix

Dans les scripts Unix, les fonctions sont des programmes informatiques qui reçoivent des données d' une entrée standard et envoient les résultats à une sortie standard . Par exemple,

sort | uniq -c | sort -rn

est une composition tacite ou sans point qui renvoie les comptes de ses arguments et les arguments, dans l'ordre des comptes décroissants. Le 'sort' et 'uniq' sont les fonctions, le '-c' et '-rn' contrôlent les fonctions, mais les arguments ne sont pas mentionnés. Le tuyau '|' est l'opérateur de composition.

En raison du fonctionnement des pipelines, il n'est normalement possible de passer qu'un seul "argument" à la fois sous la forme d'une paire de flux d'entrée/sortie standard. Bien que des descripteurs de fichiers supplémentaires puissent être ouverts à partir de canaux nommés , cela ne constitue plus un style sans point.

Voir également

Les références

Liens externes