Programação tácita - Tacit programming

A programação tácita , também chamada de estilo livre de pontos , é um paradigma de programação no qual as definições de função não identificam os argumentos (ou "pontos") nos quais operam. Em vez disso, as definições apenas compõem outras funções, entre as quais estão os combinadores que manipulam os argumentos. A programação tácita é de interesse teórico, porque o uso estrito da composição resulta em programas bem adaptados ao raciocínio equacional . É também o estilo natural de certas linguagens de programação , incluindo APL e seus derivados, e linguagens concatenativas , como Forth . A falta de nomenclatura de argumentos dá ao estilo sem ponto uma reputação de ser desnecessariamente obscuro, daí o epíteto "estilo sem sentido".

O script Unix usa o paradigma com canais .

A ideia-chave na programação tácita é auxiliar na operação no nível apropriado de abstração.

Exemplos

Pitão

A programação tácita pode ser ilustrada com o seguinte código Python . Uma sequência de operações como a seguinte:

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

... é escrito em estilo livre de pontos como a composição de uma sequência de funções, sem parâmetros:

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

example = compose(foo, bar, baz)

Para um exemplo mais complexo, o código Haskell p = ((.) f) . gpode ser traduzido como:

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


Programação funcional

Um exemplo simples (em Haskell ) é um programa que calcula a soma de uma lista de números. Podemos definir a função de soma recursivamente usando um estilo pontiagudo (cf. programação em nível de valor ) como:

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

No entanto, usando uma dobra , podemos substituí-la por:

sum xs = foldr (+) 0 xs

E então o argumento não é necessário, então isso simplifica para

sum = foldr (+) 0

que é livre de pontos.

Outro exemplo usa composição de função :

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

O seguinte pseudocódigo semelhante a Haskell expõe como reduzir a definição de uma função a seu equivalente livre de pontos:

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

Finalmente, para ver um exemplo complexo, imagine um programa de filtro de mapa que pega uma lista, aplica uma função a ela e, em seguida, filtra os elementos com base em um critério

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

Pode ser expresso sem pontos como

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

Observe que, como afirmado anteriormente, os pontos em 'ponto livre' referem-se aos argumentos, não ao uso de pontos; um equívoco comum.

Alguns programas foram escritos para converter automaticamente uma expressão Haskell em uma forma livre de pontos.

Família APL

Em J , o mesmo tipo de código sem pontos ocorre em uma função feita para calcular a média de uma lista (matriz) de números:

avg=: +/ % #

+/soma os itens do array mapeando ( /) summation ( +) para o array. %divide a soma pelo número de elementos ( #) na matriz.

A fórmula de Euler expressa tacitamente:

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

( j.é uma função primitiva cuja definição monádica é 0j1vezes x e cuja definição diádica é x+0j1×y.) Os mesmos cálculos tácitos expressos em Dyalog APL :

avg  + ÷ 

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

Baseado em pilha

Em linguagens de programação orientadas a pilha (e concatenativas , muitas das quais são baseadas em pilha), os métodos sem pontos são comumente usados. Por exemplo, um procedimento para calcular os números de Fibonacci pode ser semelhante ao seguinte em PostScript :

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

Pipeline Unix

No script Unix, as funções são programas de computador que recebem dados da entrada padrão e enviam os resultados para a saída padrão . Por exemplo,

sort | uniq -c | sort -rn

é uma composição tácita ou livre de pontos que retorna a contagem de seus argumentos e os argumentos, na ordem de contagem decrescente. O 'sort' e 'uniq' são as funções, o '-c' e '-rn' controlam as funções, mas os argumentos não são mencionados. O tubo '|' é o operador de composição.

Devido à maneira como os pipelines funcionam, normalmente só é possível passar um "argumento" por vez na forma de um par de fluxo de entrada / saída padrão. Embora descritores de arquivo extras possam ser abertos a partir de canais nomeados , isso não constitui mais um estilo sem pontos.

Veja também

Referências

links externos