Fonksiyonel Programlama için Zihinsel Modeller veya Gerçek Dünya Metaforları


16

Gerçek dünyada bir şeye atıfta bulunan işlevsel programlama için iyi bir zihinsel model veya metafor var mı?

Nesneye Yönelik programlama sezgisel olarak bana mantıklı geliyor. Özellikleri olan şeyler vardır ve bazen özellikleri (yöntemleri) üzerinde şeyler yapabilir veya hesaplamalar yapabilirler. (Örn: Araba, Şekil, Kedi).

Ben hiçbir şekilde olmayacak fonksiyonel programlamaya katılıyorum ve ikisinin erdemleri hakkında bir tartışma ile ilgilenmiyorum. Nesneye Dayalı programlamada olduğu gibi çalışmak için bir metafor veya zihinsel modele ihtiyacım var.

İşlevsel bir paradigmada programlama için bazı iyi zihinsel modeller veya gerçek dünya metaforları nelerdir? Fonksiyonları işleme fonksiyonlarından oluşan fonksiyonlar hakkında bir şey vardır, bu da ayakta durmak ve düşünmek için sağlam bir yer bırakmaz.


"Fonksiyonel programlama" nın hangi somut anlamı, "yan etki yok / beyan edici" veya "birinci sınıf fonksiyonlar / fonksiyon kompozisyonu" ndan bahsediyorsunuz? Ya da her ikisi de?
acelent

İlginç soru. "İşlevsel programlama" konusundaki şu andaki küçük bilgim ve programlama deneyimim az olduğunda bu soruya anlamlı bir şekilde cevap veremiyorum. Bir tahminde bulunmayı düşünürsem, ikisini de söylerdim.
Guido Anselmi

13
"Gerçek dünya" modeli genellikle nesne yönelimli programlama için bir motivasyon olarak verilir. Bence bu, nihayetinde büyümeniz gereken bir yaklaşımdır, çünkü OOP'taki nesneler her zaman gerçek dünyadaki nesnelere karşılık gelmemelidir ve hatta yaptıklarında, yazışma genellikle eksiktir; örneğin, "is-a" ilişkileri her zaman aynı değildir. Öte yandan, "gerçek dünyadaki" bir şeye dayanan bir programlama dili için bir model veya metafor istediğinizi söylediğinizde, kendinizi bu sınırlı OOP formuyla sınırlandırmış olduğunuzu düşünüyorum.
David K

Gerçekten iyi bir zihinsel model, eğer unix benzeri sistemler (veya modern Windows'daki powershell) kullanma deneyiminiz varsa, kabuk tek katmanlı. Kabuk boruları işlevsel değil teknik olarak akış tabanlı programlama olduğu için tam olarak aynı değildirler, ancak bir programcı ile aynı "his" e sahiptirler.
slebetman

1
Ayrıca, işlevsel dilleri öğrendiğinizde, işlevsel programlamada nesne yönelimli, örneğin normal ifadeler gibi bir araç olarak ele alınır. İsterseniz kullanabileceğiniz bir şey ama yapmak zorunda değilsiniz. Lisp ve tcl ve ileri gibi bazı dillerde OO, dilde yerleşik bir özellik değil, kullanabileceğiniz bir kitaplıktır (veya cesur hissediyorsanız kendi OO'nuzu bile yazabilirsiniz). Böylece doğal olarak bir OO çözümü olan problemler çoğu fonksiyonel dilde OO kullanılarak çözülebilir. İnsanlar OO'ya bir din gibi davranmazlar.
slebetman

Yanıtlar:


32

İşlevsel programlama, sonuçlarınıza ulaşmak için daha küçük işlevleri birbirine yapıştırmakla ilgilidir. İyi bir zihinsel model (en azından benim için) bir montaj hattıdır. Oluşan her fonksiyon montaj sürecinde bir adım daha. Bu işlevi burada düşünün:

smallest  = head . sort

Haskell'de, bu işlev listedeki en küçük elemanı döndürür. Montaj çizgisi önce girişi sıralar, ardından ilk öğeyi döndürür (en azdan en büyüğe sıralandığı varsayılarak). Yalnızca en küçük çift değeri elde etmek istersek, montaj çizgisini aşağıdaki gibi görünecek şekilde değiştirebiliriz:

smallestEven = head . sort . filter even

Konveyör bandında sadece bir adım kaldı.

Özetle, işlevler sadece ham girdiyi (parçaları) işlenmiş ürüne (çıktı) dönüştürmek için atılan adımları açıklar.


2
Global değişkenleri olmayan saf fonksiyonel bir dilde, bir montaj hattı diğerini etkileyemez (diğer satır girişini beslemedikçe.) Teorik olarak birbirine bağımlı olmayan herhangi bir montaj hattı paralel olarak yürütülebilir, ama ben Herhangi bir derleyici bunu yaparsa emin olun.
bstamour

3
@GuidoAnselmi Bunu düşünmenin bir yolu, fonksiyonel programlamadaki montaj hattının girişleri olduğu gibi bırakırken yeni çıktılar oluştururken, geleneksel OOP'deki montaj hattının girişi dönüştürmesidir.
Doval

2
Bu metafor sadece "birinci sınıf fonksiyonlar / fonksiyon kompozisyonu" anlamında "fonksiyon programlama" anlamında anlamlıdır, "yan etki yok / beyan edici" anlamında değil. Ayrıca, nesne yönelimli programlamanın yan etkileri olması gerekmez, bu nedenle OOP veya FP'nin bu anlamı ile yıkıcı veya yapıcı bir montaj hattı uygulayabilirsiniz. OOP, kapsülleme, mesaj geçirme ve polimorfizm hakkında, yan etkilerden ziyade, şeyleri nasıl modellediğinize bağlıdır. Örneğin, baştan sona referans kimliğine mi ihtiyacınız var?
acelent

3
@bstamour: Kesin olmak gerekirse, bunun (f . g) (x)araçlarını f(g(x))veya f . garaçlarını yazmalısınız \x -> f (g (x)).
Giorgio

3
@MarjanVenema Bu örnekte işler sadece bu .şekilde tanımlandığı için akıyor ; Haskell genel olarak böyle çalışmaz . |>Haskell'de F # 'ın ileri boru operatörünü ( ) de tanımlayabilir ve yazabilirsiniz smallest x = (sort x) |> headve veriler doğru akacaktır. Sadece bunu işaret edeceğimi düşündüm.
Doval

18

Fonksiyonel programlama için iyi bir zihinsel modeli olan var mı?

Matematik. Fonksiyonel programlama matematikten esinlenilmiş ve modellenmiştir. Matematiksel fonksiyonların durumu yoktur, yan etkileri yoktur, vb. FP'yi bir OO-tarzı "bunu nasıl yaparım" yaklaşımından ziyade matematiksel fonksiyonlar olarak düşünüyorsanız, iyi durumda olacaksınız. Yine de OO duyarlılıklarını FP'ye getirmeye çalışırsanız, akıntıya karşı yüzersiniz.


1
Teşekkürler. Ancak, gerçek dünyadan bir metafora ihtiyacım var (örneğin bilgisayarlardan veya matematikten değil).
Guido Anselmi

3
@GuidoAnselmi: Bir işlev kara bir kutudur. Bir tarafa bir şey koyuyorsunuz ve sonra diğer tarafa yeni bir şey çıkıyor. Aynı şeyleri içeri koyarsanız, her zaman aynı şeyleri çıkarırsınız. Bu küçük kutuların çoğunu alıp farklı siparişlerde birleştirerek ham metalleri alıp bir araba üretebilecek bir fabrika inşa edebilirsiniz. Sürecin içinde birçok parçaya bölünür, ancak dışarıdan sadece başka bir işlevdir.
Daenyth

16

Bir flip kitap ne dersin ?

Hareketli bir kitapta her sayfa bir anda var olduğu için dünyayı temsil eder. Programımızda dünya bazı bileşik veri yapısı olarak temsil edilmektedir (örneğin, ormanda bulunan bir gorilin elinde olan bir muzumuz vardır). Sonraki her sayfa, önceki sunumu biraz değiştirerek hikayeyi ilerletir. FP'de kalıcı veri yapıları, önceki yapıların verimli bir şekilde yeniden kullanılması için tasarlandı, böylece bir değişiklik tamamen yeni bir yorumlama değil yalnızca bir delta sağlar.

Açıkça görülemeyen şey, flipbook'umuzdaki bir sayfanın da maddi olmayanları temsil edeceğidir. Örneğin, goril muzu düşürürse, yerçekiminin etkilerini orman tabanına doğru düzgün ve ivme üzerine uygulamaya başlayabiliriz. Bunu sağlamak için muzumuza hız ve yörünge gibi özellikler eklerdik.

Programımızda bir flipbook sayfasını (dünyanın durumu olarak da bilinir) argüman olarak kabul eden ve yeni bir sayfa veren bir işlev olacaktır . Bu şekilde hikayemiz, mevcut nesnelerin durumunu gerçekten değiştirmeden anlatılmaktadır. Etkili bir hesaplamayı kullanarak her sayfanın yerine daha yeni bir sayfa koyarız.


3

İlişkiler.

Arkadaş: İki kişi göz önüne alındığında, bir arkadaş ilişkisi bu genel yasalara uyar

  1. Birbirinize karşı iyi niyetiniz olsun
  2. Birbirlerinin onlar için bir arkadaş olduğunu düşünüyor (bu nedenle yasalar bu ilişkide her iki üye tarafından yerine getirilmelidir)
  3. Birbirleriyle zaman geçirmekten hoşlanır

Monoid: Birden fazla öğe ve 2 öğeyi alan ve 1 döndüren bir işlev verildiğinde, monoidal bir ilişki bu genel yasalara uyar

  1. Herhangi bir öğeyle birlikte işleve iletilen bu öğelerden biri (yalnızca kimlik denir) vardır, işlevin her zaman diğer öğeyi döndürmesini sağlar (0 + 1 = 1, bu nedenle 0, öğeler sayı olduğunda ve işlevi ekleme)
  2. Fonksiyon, üzerinde monoidal bir ilişki kurduğu sette olmayan öğeleri çalıştıramaz veya iade edemez
  3. İşlev ilişkiseldir ve öğelerle bir şekilde bağımsız bir şekilde kullanılabilir, bu, a * (b * c) = (a * b) * c anlamına gelir; bu, a'yı b * c veya c sonucuyla çarpabileceğinizi belirtir. a * b sonucuyla sonuçlanırsa, sonuç hangisini yaparsanız yapın aynı olur.

İşlevsel programlama tamamen genellemelerle ilgilidir, arkadaş sayısız senaryoda görülebilen çok genel bir ilişkidir, ancak çeşitli biçimlerde genellikle yukarıdaki yasalara uyar.

Nesneler arasındaki ilişkileri düzenleyen yasaları kabul ederek, bu tür bir ilişkiye sahip olan her tür şey üzerinde çalışan genel uygulamalar oluşturabilirsiniz. Fonksiyonel programlamada, nesneler arasındaki ilişkileri, genel olarak sınıflandırılabilmeleri ve tedavi edilebilmeleri için belirlemeye çalışırsınız.

Gerçek dünyadan bir metafor mu istiyorsunuz? İşlerin nasıl ilişkili olduğuna bakın ve genel yasaları belirlemeye çalışın (yasalar dışındaki şeylerin değişebileceği birden çok senaryoda olduğu gibi). Bir mağazadaki bir kayıt memuru ile alışveriş yapan arasında bir ilişki vardır, bazı genel yasaları vardır, POS sistemleri yolunda bu genel ilişkide insanların hedeflerini kolaylaştırmak için yazılım geliştirilmiştir. Benzer şekilde, işlerin nasıl ilişkili olduğunu belirleyen bu genel yasaları görmeye başladığınızda, bir ilişkinin örneğinin belirli ayrıntılarından ziyade yazılımınızı yazarken bu ilişkilerin yasalarına güvenmeye başlayabilirsiniz.


2

Her şey bir değerdir ve tercihen herhangi bir yan etki oluşturmadan yeni değerler üretmek için değerlere (işlevler olabilir) işlevler uygularsınız.


Teşekkürler. Ne yazık ki, bu daha çok zihinsel bir model veya metafordan bir açıklama gibi geliyor. Gerçek dünyadan bir metafora ihtiyacım var (bilgisayarlardan değil).
Guido Anselmi

1
Caleb'in işaret ettiği gibi , fonksiyonel programlama gerçek dünyayı değil matematiği modeller. Gerçek dünyayı matematik merceğiyle modelleyebilir, ancak muhtemelen sizi tatmin eden bir metafor bulamazsınız, çünkü FP kalıcı bir kimlik ve değişebilir duruma sahip şeyler kavramını kapatır. İsterseniz, OOP'nin haritayı FP'ye nasıl inşa ettiğini gösterebilirim, ancak bu hala istediğiniz cevap olmayacak.
Doval

Ancak matematik gerçek dünyaya dayanır. 1 güneş, 9 gezegen. 2 elma artı 2 elma dört elma yapar.
Guido Anselmi

Ve fonksiyonel programlamada güneşler, gezegenler ve elmalar için bir türe sahip olabilirsiniz, daha sonra bir tür güneş değeri, 9 gezegen türü değeri oluşturabilir ve elma türü için ek tanımlayabilirsiniz.
Doval

3
@GuidoAnselmi tamamen geriye dönük, insanlar gerçek dünyayı matematik ile analiz ediyor, gerçek dünyaya dayanmıyor. Matematik, gerçek ve değil, her türlü şey arasındaki ilişkileri analiz etmek ve tanımlamak için kullanılır. 9 gezegen, matematiksel bir analiz işlevi (sayım) olan gerçek bir dünya yapısına (gezegenler) matematiksel bir yapı (doğal sayılar kümesi) uyguluyorsunuz. Gerçek dünyanın 9 gezegeni yoktur, sahip olduğu şey vardır, matematik sadece sembollerin birbirleriyle ilişkileri olduğu şeylerin sembolik temsillerinden bahseder.
Jimmy Hoffa

1

Fonksiyonel programlama hakkında fark edilecek en önemli şey, her şeyin bir değer olmasıdır - kodun kendisi bile 'değerler'dir.

Basit bir işlevsel programlama ortamının en iyi örneği, herkesin en sevdiği iş aracı olan e-tablodur. E-tablodaki her hücre veri veya bir işlevin sonucudur. Dahası, bu işlev gidemez ve başka bir hücreyi değiştiremez.

Tek bir işlevsel dillere hamle, yerine bir zaman Kartezyen grid içinde A1ve B42, fonksiyonlar adları vardır. Gerçekten bu kadar.

Bunun ötesinde ekleyebileceğiniz başka yönler de var ... ama özünde fonksiyonel programlama bu. Listelerin yapısı ya da şeylerin gruplandırılması konusunda endişelenmenize gerek yoktur. İşlevsel programlama, bir değerin bir işleve geçirilmesi ve bellekte başka bir yerde herhangi bir sapma olmadan bir değerin geri alınmasıyla ilgilidir.

Bu kadar. İşlevsel programlama, ızgara yerine adlara sahip bir e-tablodur.


0

Fonksiyonel programlamayı davranışlar hakkında düşünebilirsiniz . Program, bilgisayarın etkinleştirmesini istediğiniz davranışın bir açıklamasıdır. Fonksiyonlar temel davranış birimidir ve fonksiyon kompozisyonu küçük davranışlardan daha büyük davranışlar oluşturmanın bir yoludur.

OOP olarak, bir kod nesnesi için tasarlanmıştır olması sorun alanı içinde bir nesne durumu; bu etki alanı nesnesindeki değişiklikleri yansıtacak şekilde zaman içinde değişir. FP'de bir değer , bir etki alanı nesnesinin durumunu temsil eder ; asla değişmez, sadece farklı durumları temsil etmek için farklı değerler yaratırsınız.

İşlevsel modeli bilgisayarların gerçekte ne yaptığına dair daha dürüst buluyorum. Sonuçta, sadece new Tesla()ince bir hava dışarı alamıyorum . :)


-5

Cümleler, aşağıdaki gibi az ya da çok onları parçaladığınızı varsayarak, nesne yönelimli olandan daha işlevseldir ...

The brown cow is in the meadow across the deep river.

Bu yüzden kafa ifadelerini ve ardından geri kalanını bulmalıyız:

The cow (brown)
the meadow (across)
the river (deep)

Tek seferde:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Ayrıştırma ağacı:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Parsimony fonksiyonel düşünceye bulaşır;

Gottlieb Frege 1890'lara, Alan Turing (entschiedungsprobleme) 1930'lara, Noam Chomsky'ye (1960'lar) şapka çıkar.


4
Bu kafa karıştırıcı bir açıklama ve başlangıçta FP'ye aşinayım.
Daenyth

Anlamı anlamadan Lisp biçimini taklit etmek gibi görünüyor
Izkata
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.