Hindley-Milner çıkarımı Go dili için işe yarayabilir mi?


22

Hindley-Milner'in alt sınıflara sahip tip sistemlerle çalışmadığını ve bununla iyi çalışmayan diğer tip sistem özelliklerinin olduğunu okudum . Go şu anda :=operatörde yalnızca çok sınırlı bir tür çıkarımı var . Ancak Go, geleneksel anlamda alt sınıflara sahip değildir, sadece Hindley-Milner çıkarımı ile iyi çalışan Haskell'in tipi sınıflarına çok benzeyen arayüzler vardır.

Öyleyse, Hindley-Milner çıkarımı prensip olarak Go için, Haskell ile aynı şekilde çalışabilir mi? Yoksa Go'nun onu bozan başka özellikleri var mı? (Öte yandan, Haskell'in ayrıca, programınızın bu bölümlerini elle yazmak zorunda kalırsanız, Hindly-Milner ile çalışmayan bazı özellikleri vardır.)

Yanıtlar:


35

Hindley-Milner tipi çıkarım, System-F tipi sistemlerin bir kısıtlaması olan Hindley-Milner tipi sistemler için kullanılır. HM tipi sistemlerin ilginç özelliği, parametrik polimorfizme (yani jenerik) sahip olmalarıdır . Golang'ın reddettiği en büyük tek tür sistem özelliği budur.

Bu sinir bozucu kısıtlama ile, HM tarzı tip çıkarım mümkün değildir. Yazılmamış koda bakalım:

func f(a) {
  return a.method()
}

Türü nedir f? Biz fark edebilirsiniz abir yöntem olması gerekir, bu yüzden anonim bir arayüz kullanabilirsiniz: func f(a interface { method() ??? }) ???. Ancak, iade türünün ne olduğu hakkında hiçbir fikrimiz yok. Yazım değişkenleriyle, türü şu şekilde ilan edebiliriz:

func f[T](a interface{ method() T }) T

Ancak, Go'nun değişkenleri olmadığından bu işe yaramaz. Örtük arabirimler, tür çıkarımının bazı yönlerini kolaylaştırırken, artık bir işlev çağrısının dönüş türünü bulamayacağımız bir yol yok. HM sistemi ima edilmek yerine tüm fonksiyonların ilan edilmesini gerektirir ve her isim sadece tek bir tipe sahip olabilir (Go'nun metotları farklı arayüzlerde farklı tiplerde olabilir).

Bunun yerine, Go, işlevlerin her zaman tam olarak bildirilmesini gerektirir, ancak değişkenlerin tür çıkarımı kullanmasına izin verir. Bu mümkündür, çünkü ödevin sağ tarafında variable := expressionprogramın o noktasında bilinen bir tür zaten vardır. Bu tür bir tür çıkarım, basit, doğru ve doğrusaldır.

  • Bir değişkenin türü derhal bildirim noktasında bilinir, oysa HM çıkarımının önce tüm programı potansiyel olarak kontrol etmesi gerekir. Bunun da hata mesajlarının kalitesi üzerinde gözle görülür bir etkisi vardır.
  • Go'nun tür çıkarımı yaklaşımı, en genel türü seçen HM'nin aksine, bir değişken için her zaman en spesifik türü seçer. Bu, Go'nun gizli arayüzleriyle bile, alt tipleme ile temiz bir şekilde çalışır.

24
@bishop Sonsuz küçük "nedensellik" değerleri için "gerekçelidir".
Ocaklar

18
@bishop Derleyici'nin jenerik diliyle çalışmasını yaptıktan sonra kesinlikle aynı fikirdeyim: Uygulamayı önemli ölçüde karmaşıklaştırmadan uygulamak zordur. "Zor" u "imkansız" olarak değiştirecek kadar ileri giderdim. Ancak, konu bu değil; Mesele şu ki, ekstra komplikasyona değer mi? Ve cevabı, jenerik olan ve olmayan çalışanların cevapları, kesinlikle "evet, kesinlikle!" "Ah hayır, karmaşıklık" aptalca olduğu için, jenerik ilaçları kullanmayı reddettiği iddiasına gönülden katılıyorum.
Mason Wheeler

18
Bu yüzden Go devs her çeşit FP'nin kötü olduğunu iddia ediyor; Git sözcük kapanması ile birinci sınıf işlevleri vardır ve yeteneği yüksek sıralı işlevler oluşturmak, ancak herhangi bir iyi kullanmak için onları koymak imkansız bununla çünkü böyle temel fonksiyonların türleri olarak map, filterve reducetüm Git en çok sınırlı dahilinde ifade edilemez olduğu tip sistemi
Ocaklar

9
@hobbs And Go bir olabilir gerçekten o sabitleşmişse güzel dil, ancak bunun yerine insanlar gibi jenerik nesil kütüphaneleri yazmak zorunda gengenvegonerics
kedi

14
@ cat Bu utanç verici. İlk başta Go, harika fikirlerle dolu harika bir dil gibi gözüküyor, fakat daha sonra kalıtımsal ve çok biçimliliğin olmadığını fark edersiniz, yani OOP'yi iyi yapamazsınız ve jenerikliği yoktur, bu yüzden FP'yi iyi yapamazsınız ve '' Bu dili tam olarak nasıl kullanmanız gerekiyor? '' sorusunu soran ekrana boş bir şekilde bakacaksınız.
Mason Wheeler
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.