"Noktadan bağımsız" stil nedir (Fonksiyonel Programlamada)?


106

Son zamanlarda fark ettiğim bir cümle, "noktasız" stil kavramı ...

Birincisi, bu soru vardı ve bu da .

Sonra, burada "Tartışmaya değer başka bir konu da yazarların noktasız stilden hoşlanmamasıdır" dediğini keşfettim .

"Noktasız" stil nedir? Birisi kısa bir açıklama yapabilir mi? "Otomatik" körlemeyle bir ilgisi var mı?

Seviyem hakkında bir fikir edinmek için - kendime Şema öğretiyorum ve basit bir Şema tercümanı yazdım ... "Örtülü" körlemenin ne olduğunu anlıyorum, ancak Haskell veya ML bilmiyorum.


3
Sadece bir not: neden noktasız ziyaret dendiğini görmek için Pointfree / Ama pointfree'nin daha fazla puanı var! HaskellWiki'de.
Petr Pudlák

Yanıtlar:


66

Tanımınızı öğrenmek için Wikipedia makalesine bakın :

Örtük programlama (noktasız programlama), bir fonksiyon tanımının değişkenler yerine birleştiriciler ve fonksiyon bileşimi [...] kullanarak argümanlarıyla ilgili bilgileri içermediği bir programlama paradigmasıdır.

Haskell örneği:

Geleneksel (bağımsız değişkenleri açıkça belirtirsiniz):

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

Noktasız ( sumherhangi bir açık argüman içermez - sadece +0 ile başlayan bir kat ):

 sum = foldr (+) 0

Veya daha basit: Bunun yerine g(x) = f(x)sadece yazabilirsiniz g = f.

Yani evet: Bu, körlemeyle (veya işlev kompozisyonu gibi işlemler) yakından ilgilidir.


8
Ahh görüyorum! Dolayısıyla, argümanlar bildirmek yerine her zaman diğer işlevleri birleştirerek yeni işlevler geliştirirsiniz ... Çok zarif!
Paul Hollingsworth

22
Programlarken değişkenler / argümanlar için yeni isimler bulmaktan gerçekten hoşlanmıyorum. Noktasız stili sevmemin büyük bir nedeni bu!
Martijn

2
Currying ile ne şekilde bağlantılı?
kaleidic

1
@kaleidic: Çünkü değişken isimlere sahip olmadan, kısmen uygulanan fonksiyonlar oluşturmanız gerekir. İşte biz buna körleme diyoruz (veya daha doğrusu, körleme yoluyla mümkün olan şey)
Dario

1
Onun sum (x:xs) ...yerine mi demek istiyorsun sum sum (x:xs) ...?
Ehtesh Choudhury

34

Noktadan bağımsız stil, tanımlanmakta olan fonksiyonun argümanlarından açıkça bahsedilmediği, fonksiyonun fonksiyon bileşimi yoluyla tanımlandığı anlamına gelir.

İki işleviniz varsa, örneğin

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

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

ve bu iki işlevi hesaplayan bir işlevle birleştirmek istiyorsanız x*x+1, bunu şu şekilde "nokta dolu" olarak tanımlayabilirsiniz:

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

Noktadan bağımsız alternatif, argüman hakkında konuşmak değildir x:

f :: a -> a
f = inc . square

22
Aptalca, Haskell'de 'noktasız' yol, genellikle daha belirgin görünen (daha fazla dönem) yol. Bu rahatsızlık mükemmel bir anımsatıcı yapar. (Real World Haskell kitabı bunu yorumluyor.)
Dan

3
@ Dan'ın yorumuyla ilgili olarak, Pointfree HaskellWiki sayfası neden nokta içermeyen olarak adlandırıldığına dair bir açıklama sunar .
Vincent Savard

2
@Dan: Bunun aptalca olduğunu düşünmüyorum, çünkü Haskell noktası "o daire operatörü" anlamına geliyor (yine de daha çok ° gibi görünmeli). Ancak kafa karıştırıcı, özellikle işlevsel programlama dillerinde yeniyseniz; haskell hakkındaki her giriş kitabı, noktasız tarzı açıklamalıdır.
Sebastian Mach

14

Bir JavaScript örneği:

//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'

Referans


7

Point free style, kodun, var olmalarına ve kullanılmalarına rağmen, argümanlarından açıkça bahsetmediği anlamına gelir.

Bu, işlevlerin çalışma biçimi nedeniyle Haskell'de çalışır.

Örneğin:

myTake = take

bir bağımsız değişken alan bir işlev döndürür, bu nedenle siz de istemediğiniz sürece bağımsız değişkeni açıkça yazmanız için bir neden yoktur.


1
Bazen Haskell 98'de olduğu gibi çalışmaz myShow = show. Haskell wiki'sinde
Ehtesh Choudhury

-1

TypeScript'te başka herhangi bir kitaplık olmayan bir örnek:

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;
    }
  }
}

Noktasız stilin daha "akıcı" ve okunması daha kolay olduğunu görebilirsiniz.


Bu noktasız stil değil, bu sadece bir lambda ile adlandırılmış bir işlev arasındaki farktır.
kralyk

@kralyk Sanırım noktayı kaçırdınız, this.moreThan(10)adlandırılmış bir işlev değil , kıvrımlı bir işlev ve dolaylı olarak (dolayısıyla nokta serbest) a'yı transactiongirdi olarak alacak bir işlev.
AZ.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.