¿Qué es el estilo “sin puntos” (en Programación funcional)?

101

Una frase que he notado recientemente es el concepto de estilo "sin puntos" ...

Primero, estaba esta pregunta, y también esta .

Entonces, descubrí aquí que mencionan "Otro tema que puede valer la pena discutir es el desagrado de los autores por el estilo libre de puntos".

¿Qué es el estilo "sin puntos"? ¿Alguien puede dar una explicación concisa? ¿Tiene algo que ver con el curado "automático"?

Para tener una idea de mi nivel, he estado aprendiendo Scheme por mí mismo y he escrito un intérprete de Scheme simple ... Entiendo lo que es el currying "implícito", pero no conozco ningún Haskell o ML.

Paul Hollingsworth
fuente
3
Solo una nota: para ver por qué se llama pointfree, visite Pointfree / ¡Pero pointfree tiene más puntos! en HaskellWiki.
Petr Pudlák

Respuestas:

66

Solo mira el artículo de Wikipedia para obtener tu definición:

La programación tácita (programación sin puntos) es un paradigma de programación en el que la definición de una función no incluye información sobre sus argumentos, utilizando combinadores y composición de funciones [...] en lugar de variables.

Ejemplo de Haskell:

Convencional (especifica los argumentos explícitamente):

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

Sin puntos ( sumno tiene argumentos explícitos, es solo un pliegue que +comienza con 0):

 sum = foldr (+) 0

O incluso más simple: en lugar de g(x) = f(x), podría simplemente escribir g = f.

Entonces sí: está estrechamente relacionado con el curry (u operaciones como la composición de funciones).

Darío
fuente
8
¡Ahh ya veo! Así que crea nuevas funciones siempre simplemente combinando otras funciones en lugar de declarar argumentos ... ¡Muy elegante!
Paul Hollingsworth
22
Realmente no me gusta tener que inventar nuevos nombres para variables / argumentos cuando estoy programando. ¡Esa es una gran razón por la que me encanta el estilo sin puntos!
Martijn
2
¿De qué manera se relaciona con el currying?
kaleidic
1
@kaleidic: Porque sin tener nombres de variables, necesitas componer funciones parcialmente aplicadas. Eso es lo que llamamos curry (o, más precisamente, lo que se hace posible a través del curry)
Dario
1
¿No te refieres en sum (x:xs) ...lugar de sum sum (x:xs) ...?
Ehtesh Choudhury
33

El estilo sin puntos significa que los argumentos de la función que se define no se mencionan explícitamente, que la función se define mediante la composición de funciones.

Si tiene dos funciones, como

square :: a -> a
square x = x*x

inc :: a -> a
inc x = x+1

y si desea combinar estas dos funciones en una que calcule x*x+1, puede definirla como "punto completo" así:

f :: a -> a
f x = inc (square x)

La alternativa libre de puntos sería no hablar del argumento x:

f :: a -> a
f = inc . square
algo
fuente
22
Estúpidamente, en Haskell, la forma 'sin puntos' suele ser la que parece más puntiaguda (más puntos). Esta molestia es una excelente mnemotécnica. (El libro Real World Haskell comenta sobre esto.)
Dan
3
Con respecto al comentario de @ Dan, la página Pointfree HaskellWiki ofrece una explicación de por qué se llama pointfree .
Vincent Savard
2
@Dan: No creo que sea estúpido, ya que el punto Haskell está destinado a ser "ese operador de círculo" (aunque debería parecerse más a °). Pero es confuso, especialmente cuando es nuevo en los lenguajes de programación funcionales; Cada libro de introducción sobre Haskell debe explicar el estilo sin puntos.
Sebastian Mach
12

Una muestra de JavaScript:

//not pointfree cause we receive args
var initials = function(name) {
  return name.split(' ').map(compose(toUpperCase, head)).join('. ');
};

const compose = (...fns) => (...args) => fns.reduceRight((res, fn) => [fn.call(null, ...res)], args)[0];
const join = m => m.join();

//pointfree
var initials = compose(join('. '), map(compose(toUpperCase, head)), split(' '));

initials("hunter stockton thompson");
// 'H. S. T'

Referencia

Brunno
fuente
5

El estilo sin puntos significa que el código no menciona explícitamente sus argumentos, aunque existen y se están utilizando.

Esto funciona en Haskell debido a la forma en que funcionan las funciones.

Por ejemplo:

myTake = take

devuelve una función que toma un argumento, por lo tanto, no hay razón para escribir explícitamente el argumento a menos que usted también lo desee.

Rayne
fuente
1
A veces, no funciona en Haskell 98, como en myShow = show. Hay más sobre esto en la wiki de Haskell
Ehtesh Choudhury
-1

Aquí hay un ejemplo en TypeScript sin ninguna otra biblioteca:

interface Transaction {
  amount: number;
}

class Test {
  public getPositiveNumbers(transactions: Transaction[]) {
    return transactions.filter(this.isPositive);

    //return transactions.filter((transaction: {amount: number} => transaction.amount > 0));
  }

  public getBigNumbers(transactions: Transaction[]) {
    // point-free
    return transactions.filter(this.moreThan(10));

    // not point-free
    // return transactions.filter((transaction: any) => transaction.amount > 10);
  }

  private isPositive(transaction: Transaction) {
    return transactions.amount > 0;
  }

  private moreThan(amount: number) {
    return (transaction: Transaction) => {
      return transactions.amount > amount;
    }
  }
}

Puede ver que el estilo sin puntos es más "fluido" y más fácil de leer.

ARIZONA.
fuente
Ese no es un estilo sin puntos, es solo una distinción entre una función lambda y una función con nombre.
kralyk
@kralyk Creo que te perdiste el punto, this.moreThan(10)no es una función con nombre, es una función curry, así como una función que implícitamente (por lo tanto, libre de puntos) tomará transactioncomo entrada.
AZ.