5

Odersky, Spoon ve Venners tarafından Scala 2. Baskısında Programlama bölümüne gidiyorum ve bu örnek, fonksiyonel programlama hakkında doğru olduğunu düşündüğüm şeye karşı çıktığı için bir döngü attı. değişmezlik. Örnekte (ve 18'inci kitaptaki kitapta daha önce), yazarlar, bir nesne üzerindeki işlemlerin, bu işlemler nesnenin durumunu dahili olarak değiştirebilse bile, hala "tamamen işlevsel" olabileceğini iddia etmektedir. Örnek, p.442, Ch. 19 şudur:Scala'da Programlamadan İşlevsel Kuyruk

class Queue[+T] private (
    private[this] var leading: List[T], 
    private[this] var trailing: List[T] 
) { 

    private def mirror() = 
    if (leading.isEmpty) { 
     while (!trailing.isEmpty) { 
     leading = trailing.head :: leading 
     trailing = trailing.tail 
     } 
    } 

    def head: T = { 
    mirror() 
    leading.head 
    } 

    def tail: Queue[T] = { 
    mirror() 
    new Queue(leading.tail, trailing) 
    } 

    def enqueue[U >: T](x: U) = 
    new Queue[U](leading, x :: trailing) 
} 

verilen gerekçe kadar uzun yan etkileri müşterilerine görünmez olarak, böyle bir şey işlevsel olarak kabul edilebilir olmasıdır. Sanırım bunun arkasına geçebilirim ... Kesinlikle konuşacağım, bu bir işlevi tanımlar. Ama kuşkusuz (ve JVM bellek modelinin ne olduğu konusunda çok fazla bilgim yok) ama bu kodda bununla ilgili potansiyel problemler yok mu? Örneğin

, iki iş parçacığı şöyle bu kuyrukta, işlemleri çalıştırıyorsanız başlatmak için:

Leading: Nil 
Trailing: List(1,2,3,4) 

o tek iplik aynada bu noktaya alma kafasını() diyebiliriz bu mümkün değil mi() descheduled edilmeden önce:

private def mirror() = 
    if (leading.isEmpty) { 
     while (!trailing.isEmpty) { 
     leading = trailing.head :: leading 
     > trailing = trailing.tail 
     } 
    } 

hangi noktada kuyruk şuna benzer:

Leading: List(1) 
Trailing: List(1,2,3,4) 

Ve ikinci ipliğin arka() ilk aktif değilken, bu iade edileceği çağırdığında:

Leading: Nil 
Trailing: List(1,2,3,4) 

Oysa ilk parçacığının başlığı() çağrısı bu bir sonraki kuyruk sonra iade edileceği, bitirmek olsaydı Ben kuşkusuz malzeme ve eşzamanlı programlama gerçekten bunu birçok insan içindir eminim, ben, benim için mindbending olan bu tür büyük değilim

Leading: List(2,3,4) 
Trailing: Nil 

:() o listede çağrı sadece ne kaçırdığımı merak ediyorum.

+0

Sanırım siz haklısınız. Sanırım birden fazla iş parçacığı tarafından kullanılıyorsa "işlevsel his" in bozulduğunu söyleyebilirdiniz. Fonksiyonel programların sorunsuz olarak eşzamanlı olması gerekiyor mu? Bilmiyorum. – Owen

cevap

3

Haklısınız: işlevsel görünen kod, uygulamasının bir parçası olarak dahili durumu kullanıyorsa, birden fazla iş parçacığı tarafından kullanıldığında işlevsiz hale getirilebilir. Değiştirilebilir değişkenlere (ör. synchronized bloğu ile) dokunan her yöntemi senkronize ederek bunu düzeltebilirsiniz. Ne yazık ki, bu performans için ideal değildir, bu nedenle bir uygulamada fonksiyonel uygulamalar genellikle tercih edilir.

+0

Tamam, sadece deli olmadığından emin olmak istedim. Bu tanımlarda çok az nezaket, ya da en azından ne anlama geldiği konusunda tam bir mutabakat bulunmama imtiyazı ile ... yazarların yaptığı gibi bu "salt işlevsel" ya da "değişmez" olarak adlandırılmak adil midir? Doğru şartlar altında işlevsel görünüyor, ama kesinlikle değişmez değil ... Yani mutasyona uğramış durum açıkça ortaya çıkıyor ve fonksiyonel görünüm birden fazla iş parçacığıyla parçalanıyor. Soruyorum çünkü yazarları yazmayı düşünüyorum ve çok büyük bir araç gibi görünmek istemiyorum. –

+0

@Chris K - Bence bunu değişmez olarak adlandıracağım, ama aynı zamanda iplik güvenliği konusunda uyarmak akıllıca olacaktır. Bilgisayarlar, doğası gereği değişebilir aygıtlardır; Bir işlemin mutasyona neden olması için neredeyse her zaman bir yol vardır ya da değişmez görünmek için tasarlanmış olsa bile başarısızdır. Soru gerçekten, mutasyon halini değiştirmek için _designed_ olan bir arayüz sağlayıp sağlamadığınızı ve ne kadar kırılgan olduğunuzu sormaktır.Multithreading'in bu olağandışı olmadığı göz önüne alındığında, bu kırılganlık hayal kırıklığı yaratıyor, ancak "tamamen işlevsel değil" demenin doğru olduğundan emin değilim. –