Articulo de referencia

Programación tácita

La programación tácita , también llamada estilo sin puntos , es un paradigma de programación en el que las definiciones de funciones no identifican los argumentos (o "puntos") s...

La programación tácita , también llamada estilo sin puntos , es un paradigma de programación en el que las definiciones de funciones no identifican los argumentos (o "puntos") sobre los que operan. En cambio, las definiciones simplemente componen otras funciones, entre las que se encuentran combinadores que manipulan los argumentos. La programación tácita tiene interés teórico, ya que el uso estricto de la composición da como resultado programas bien adaptados al razonamiento ecuacional . [ 1 ] También es el estilo natural de algunos lenguajes de programación , incluidos APL y sus derivados, [ 2 ] y lenguajes concatenativos como Forth . La falta de nombres de argumentos le confiere al estilo sin puntos la reputación de ser innecesariamente oscuro, de ahí el epíteto de "estilo sin puntos". [ 1 ]

La programación de scripts en Unix utiliza el paradigma de las tuberías .

Ejemplos

Pitón

La programación tácita se puede ilustrar con el siguiente código Python . Una secuencia de operaciones como la siguiente:

def ejemplo ( x ): return baz ( bar ( foo ( x )))

... puede escribirse en estilo sin puntos como la composición de una secuencia de funciones, sin parámetros: [ 3 ]

from functools import partial , reducedef compose ( * functions ): return partial ( reduce , lambda x , f : f ( x ), functions )ejemplo = componer ( foo , bar , baz )

Para un ejemplo más complejo, el código Haskellp = ((.) f) . g se puede traducir como:

p = parcial(componer, parcial(componer, f), g)

Programación funcional

Un ejemplo sencillo (en Haskell ) es un programa que calcula la suma de una lista de números. Podemos definir la función de suma recursivamente utilizando un estilo apuntado (véase programación a nivel de valor ) de la siguiente manera:

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

Sin embargo, utilizando un pliegue , esto se puede reemplazar con:

suma xs = foldr ( + ) 0 xs

Y entonces el argumento no es necesario, por lo que esto se simplifica a

suma = foldr ( + ) 0

lo cual no tiene puntos.

Otro ejemplo utiliza la composición de funciones :

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

El siguiente pseudocódigo , similar al de Haskell , muestra cómo reducir la definición de una función a su equivalente sin puntos:

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 )( * Aquí el operador de composición infijo "." se utiliza como una función currificada . * )= \ x -> (( . ) f ) ( g x )= \ x -> ((( . ) f ) . g ) xp = (( . ) f ) . g

Finalmente, para ver un ejemplo complejo, imaginemos un programa de filtrado de mapas que toma una lista, le aplica una función y luego filtra los elementos según un criterio.

lista de operadores de criterios mf = criterios de filtro ( lista de operadores de mapeo )

Se puede expresar sin puntos [ 4 ] como

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

Como ya se ha sugerido, los puntos en point-free se refieren a los argumentos, no al uso de puntos suspensivos; una idea errónea común. [ 5 ]

Se han escrito algunos programas para convertir automáticamente una expresión de Haskell a una forma sin puntos.

Familia APL

En el lenguaje J , el mismo tipo de código sin puntos aparece en una función diseñada para calcular el promedio de una lista (matriz) de números:

promedio =: +/ % #

+/suma los elementos del array mapeando ( /) sumatoria ( +) al array. %divide la suma por el número de elementos ( #) en el array.

Fórmula de Eulermiiincógnita=porqueincógnita+ipecadoincógnita,{\displaystyle e^{ix}=\cos x+i\sin x,}expresado tácitamente:

porque =: 2 o . ] pecado =: 1 o . ] Euler =: ^@ j . = porque j . pecado

( j.es una función primitiva cuya definición monádica es 0j1veces x y cuya definición diádica es x+0j1×y.) Los mismos cálculos tácitos expresados ​​en Dyalog APL :

promedio + ÷ cos 2 sin 1 EulerCalc cos + 0j1 × sin ⍝ 0j1 es lo que normalmente se escribe como i EulerDirect * 0J1 ×⊢ ⍝ Igual que ¯12○⊢ ⍝ ¿Los 2 métodos producen el mismo resultado? EulerCheck EulerDirect = EulerCalc EulerCheck ¯1 1 2 3 1 1 1 1 ⍝ ¡Sí, hasta ahora todo bien!

Basado en pilas

En los lenguajes de programación orientados a pilas (y en los concatenativos , la mayoría de los cuales se basan en pilas ), se utilizan comúnmente métodos sin puntero. Por ejemplo, un procedimiento para calcular los números de Fibonacci podría tener el siguiente aspecto en PostScript :

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

oleoductos

Pipeline de Unix

En la programación de scripts de Unix, las funciones son programas informáticos que reciben datos de la entrada estándar y envían los resultados a la salida estándar . Por ejemplo,

ordenar | uniq -c | ordenar -rn

Es una composición tácita o sin puntos que devuelve los recuentos de sus argumentos y los argumentos, en orden descendente. Las funciones sort y uniq son las funciones de control, pero no se mencionan los argumentos. El operador de composición es la tubería.-c-rn|

Debido a la forma en que funcionan las tuberías, normalmente solo es posible pasar un argumento a la vez en forma de un par de flujos de entrada/salida estándar. Si bien se pueden abrir descriptores de archivo adicionales desde tuberías con nombre , esto ya no constituye un estilo libre de puntos.

jq

jq es un lenguaje de programación orientado a JSON| en el que el símbolo se utiliza para conectar filtros y formar una secuencia de instrucciones de forma familiar. Por ejemplo:

 [1,2] | agregar

Se evalúa como 3. (Sí, el array JSON es un filtro jq que se evalúa como un array).

Aunque similares a las tuberías de Unix, las tuberías de jq permiten que los datos entrantes se envíen a más de un destinatario en el lado derecho |como si se ejecutaran en paralelo. Por ejemplo, el programa add/lengthcalculará el promedio de los números en un arreglo, de manera que:

 [1,2] | añadir/longitud

se evalúa a 1.5

Similarmente:

 [1,2] | [longitud, añadir, añadir/longitud]

se evalúa a [2,3,1.5]

.Se puede usar un punto ( ) para definir un punto de unión en el lado derecho, por ejemplo:

 1 | [., .]

se evalúa a [1,1]

y de manera similar:

 2 | pow(.; .)

se evalúa a 4 ya que pow(x;y)es x elevado a la potencia y.

secuencia de Fibonacci

Un programa jq tácito para generar la secuencia de Fibonacci sería:

 [0,1] | recurse( [último, agregar] ) | primero

Aquí, [0,1]se presenta el par inicial que se tomará como los dos primeros elementos de la secuencia de Fibonacci. (Este par [1,1]también podría usarse para la definición de la variante).

Los tokens alfabéticos son filtros incorporados: `first` y `last` emiten el primer y el último elemento de sus matrices de entrada respectivamente; y recurse(f)aplica un filtro, f, a su entrada de forma recursiva.

jq también permite definir nuevos filtros de forma tácita, por ejemplo:

 def fib: [0,1] | recurse( [last, add] ) | first;
Composición de funciones unarias

En la sección sobre Python de este artículo, se considera la siguiente definición de Python:

def ejemplo ( x ): return baz ( bar ( foo ( x )))

En estilo sin puntos, esto se puede escribir en Python como:

ejemplo = componer(foo, bar, baz)

En jq, la definición equivalente sin puntos sería:

 def ejemplo: foo | bar | baz;

Véase también

Referencias

  1. ^ Cunha , Manuel Alcino Pereira da (2005). Cálculo de programas sin puntos (tesis doctoral). Universidad del Miño .
  2. Holmes, W. Neville, ed. (2006). Computadoras y personas .
  3. "Nombre del código, no de los valores" . Concatenative.org . Consultado el 13 de septiembre de 2013 .
  4. pipermail
  5. "Pointfree" . Haskell.org Wiki . Consultado el 5 de junio de 2016 .
  • De la programación a nivel de funciones al estilo sin puntos
  • Funciones puras en APL y J. Cómo usar la programación tácita en cualquier lenguaje similar a APL.
  • Lenguajes aplicativos cerrados 1971 - 1976 ss. , en John W. Backus (Publicaciones)