Simülasyon ve modelleme için FP


12

Ben bir simülasyon / modelleme projesi başlatmak üzereyim. OOP'un bu tür projeler için kullanıldığını zaten biliyorum. Ancak Haskell'i incelemek beni bir bileşen sistemini modellemek için FP paradigmasını kullanmayı düşündürdü. Açıklayayım:

Diyelim ki bir veri kümesi (sıcaklık veya basınç, bir PDE ve bazı sınır koşulları gibi bir parametre) ile karakterize edilen A tipi bir bileşene ve farklı bir veri kümesi (farklı veya aynı parametre, farklı PDE ve sınır koşulları). Ayrıca, her bir bileşene uygulanacak işlevlerin / yöntemlerin aynı olduğunu varsayalım (örneğin bir Galerkin yöntemi). Nesnenin değişken durumu sabit olmayan parametreler için kullanılır.

Bir OOP yaklaşımı kullanacak olsaydım, her türün verilerini, PDE'yi çözme yöntemleri (burada kodun yeniden kullanımı için miras) ve PDE'nin çözümünü içine alan iki nesne yaratacağım.

Öte yandan, bir FP yaklaşımı kullanacak olsaydım, her bileşen veri parçalarına ve PDE'nin çözümünü elde etmek için veriler üzerinde etkili olacak işlevlere bölünürdü. Sabit olmayan parametreler, başka bir şeyin (örneğin zamanın) işlevleri olarak geçirilebilir veya bir çeşit değişebilirlik (değişebilirlik emülasyonu, vb.) İle ifade edilir. Bu yaklaşım, veriler üzerindeki doğrusal işlemlerin önemsiz olacağını varsayarak benim için daha basit görünüyor.

Sonuç olarak, FP yaklaşımını uygulamak OOP ile karşılaştırıldığında daha basit ve yönetilmesi daha kolay olur (pde'yi çözmek için farklı bir bileşen türü veya yeni bir yöntem ekleyin)?

C ++ / Fortran arka planından geliyorum, ayrıca profesyonel bir programcı değilim, bu yüzden yanlış yaptığım herhangi bir şeyde beni düzeltin.

Yanıtlar:


7

Güzel soru, ben de benzer çizgileri düşünüyordum. Tarihsel olarak OO paradigması, bilgisayar simülasyonu gereksiniminden ortaya çıktı - Simula'nın tarihine bakın - ve Smalltalk gibi erken OO dillerinin yaptıklarını bilen insanlar tarafından yapılmasına rağmen (yani Alan Kay), OO artık tartışmalı olarak aşırı kullanılmış ve çok fazla kazara karmaşıklık getirir .

Genellikle, FP stili programlar OO programlarına göre daha kısa, test edilmesi ve değiştirilmesi daha kolay olacaktır. Rob Harrop konuşmasına koyduğu gibi , Gelecek İşlevsel mi? , işlevlerden ve verilerden asla daha basit olamazsınız; her ikisi de, gerekli soyutlamaları oluşturmak için sınırsız bir şekilde oluşur. Yani sorunuzu cevaplamanın bir yolu (ya da sadece yeniden mi yazıyorum? :) sormaktır, En yüksek seviye fonksiyonu ve en yüksek seviye giriş verileri -> çıkış verileri nasıl görünüyor? Daha sonra bu "alfa" işlevlerini ve veri türlerini bir sonraki soyutlama katmanına bölebilir ve gerektiği gibi tekrarlayabilirsiniz.

Sorunuzdaki başka bir perspektif (tam olarak cevaplar değil) StackOverflow'daki bu konuya (sorumluluk reddi, başlattım) bakmak, bazı cevaplar çok ilginç: /programming/3431654/how-does- fonksiyonel-programlama-başvuruda-to-simülasyonlar

Bu noktada kendi fikrim, sadece belirli yollarla (örneğin bir bilgisayar ağının modeli) etkileşimde bulunan ayrı nesnelerin olduğu bir durumu modellemediğiniz ve böylece doğrudan temiz, mesajın - geçen paradigma OO dili - FP'ye gitmek daha kolaydır. Simülasyonların çok yaygın olduğu ve performans gereksinimlerinin çok önemli olduğu oyun programlama topluluğunda bile, deneyimli geliştiriciler OO paradigmasından uzaklaşıyor ve / veya daha fazla FP kullanıyor, örneğin bu HN tartışmasına veya John Carmack'in FP hakkındaki yorumlarına bakın


Simülasyonda OOP hakkında şüphe eden tek kişi olmadığımı bilmek güzel ve soruma cevap verdiğiniz için teşekkürler! John Carmack'in FP hakkındaki yorumlarını okumuştum ve C ++ üzerinde bazı FP yönleri uygulamayı düşündüm (nesneleri kopyalamak veya girişi toplamak ve bir işleve aktarmak) ama sonra yine projemi C ++ ile başlatmam gerekip gerekmediğini bilmiyorum FP yönleri yerleşik olduğundan ve yalnızca gerektiğinde değişebilirliği ifade ettiğiniz için Haskell gibi bir FP dili yerine. Benzer bir sorun / sorunuz olduğunu düşünerek genel olarak Clojure veya FP kullanmaya devam ettiniz mi?
heaptobesquare

@heaptobesquare - Evet, içinde simülasyon yazmak amacıyla Clojure-fu'yu sürekli olarak artırdım. Henüz göstermeye hazır bir şey yok, ancak gösteri durdurucu görmüyorum ve Clojure'un tasarımı güzel bir şekilde pragmatik, örneğin geçici / mutasyon kullanabilirsiniz, ayrıca ajanları eşzamansız yönlere çok uygundur. Bir noktada (ne zaman vaat yok) Konu hakkında bir yazı yazacağım ...
Limist

Clojure'a bir göz attım ama S-ifadelerine düşkün olduğumu söyleyemem. Pratik olduğunu biliyorum (Lisp kodu veri) ama alışmak kolay mı?
heaptobesquare

@heaptobesquare - s-expressions / Lisp sözdizimine alışmak aslında çok kolaydır; önce iyi bir editör seçin (Emacs veya vim, oyum Emacs için, bkz . Clojure modu olan dev.clojure.org/display/doc/Getting+Started+with+Emacs ), iyi bir kitap alın (örn. ) ve hacklemeye başlayın. En fazla birkaç hafta sonra, sözdizimi arka planda kaybolur, olması gerektiği gibi - o kadar mükemmel bir şekilde tutarlı olur ki, katlanarak daha az sıklıkla düşünür ve daha önemli şeyler için zihinsel döngüleri serbest bırakırsınız. :)
Limist

Kesinlikle bir şans vereceğim o zaman. Sonuçta Lisp'in homoikonitesi ilginçtir.
heaptobesquare

2

IMHO makul karmaşıklıktaki her görev için "FP tarzı veya OOP tarzı daha iyi bir seçimdir" sorusu objektif olarak cevaplanamaz. Tipik olarak, böyle bir durumda soru "FP ya da OOP" değil, probleminizi çözmek için her iki paradigmanın en iyi kısımlarının nasıl birleştirileceği.

Yukarıda çizdiğiniz problem çok matematiksel bir sorun gibi görünüyor ve bazı matris işlemlerine ihtiyacınız olacağını çılgınca tahmin ediyorum. OOP soyut veri tiplerini modellemek için çok iyidir ve matris hesabı matrisler üzerinde işlemlerle kolayca "matris nesneleri" olarak uygulanabilir. Bunu tüm matris işlemlerinin bir matris sınıfının parçası olacak şekilde uygulamak, birbirine ait olan şeyleri bir arada tutmanıza yardımcı olur, böylece iyi bir genel yapı sağlar.

Öte yandan, PDE'ler fonksiyonlar üzerinde denklemlerdir ve çözüm tekrar fonksiyon olabilir. Yani bu tür "bileşenler" için işlevsel bir yaklaşım kullanmak burada doğal görünebilir. Bu işlevler, OOP ve FP'nin nasıl birleştirileceğinin bir örneğini gösteren matris parametrelerine sahip olabilir. Başka bir örnek, belirli bir işlemi matrisinizin her öğesine eşlemek için işlevsel araçlar kullanan bir matris sınıfı uygulamasıdır. Burada da "FP'ye karşı OOP" değil, "FP ile birleştirilmiş OOP" değil, size en iyi sonuçları verir.


Cevabınız için teşekkür ederim! Yani, eğer C ++ kullanacak olursam, bileşenin sadece verilerini (yani parametreler, sınır koşulları ve PDE matris formunda) bir nesneye kapsülleyecek ve fonksiyonları tanımlayan (hatta bazı yüksek dereceli olanları bile) parametresi başka bir şeyin işlevidir), nesnenin kapsamı dışında, nesnenin verileri üzerinde çalışacak verimli mi?
heaptobesquare

@heaptobesquare: Bu etkili olacak eğer açıkçası sana söyleyemem senin durumda. Bir deneyin, büyük düşünün, küçük başlayın. Neyin en iyi ve neyin işe yaramadığını öğrenmek için bazı "izleme kodu" ( artima.com/intv/tracer.html ) programlamaya başlayın . Ve bir şeyin düzgün çalışmadığını fark ettiğiniz duruma gelirseniz, refactor.
Doc Brown

Haskell, BLAS / LAPACK kütüphaneleri için bağlayıcılar olan Hmatrix kütüphanesine ve bunun için çok güzel bir sözdizimine sahip.
paul

@paul: Teşekkürler, kesinlikle bir göz atacağım! Haskell kütüphaneleri genellikle tutarlı ve zengin içerikli midir? Wiki öyle diyor ama bu bir gerçek mi?
heaptobesquare

@heaptobesquare: Herhangi bir ölçüde kullandığım tek Haskell kütüphanesi Parsec (bir derleyici yazmak için kullandım), ama kullanmayı sevdim. Sadece Hmatrix ve Haskell OpenGL bağlarının GHCI araştırmasını yaptım ama oldukça hoş görünüyorlar. Hmatrix neredeyse MATLAB (oldukça az kullandım) kadar özlü görünüyor - ki bu tür şeyler için özel olarak üretildi. Sınırlı deneyimlerime göre kütüphaneler tutarlıdır - bunun nedeni Haskell'in az sayıda basit yapı taşı üzerine inşa edilmiş olmasıdır - ve aynı zamanda zengindir çünkü Haskeller sıradan şeyler yapmaktan hoşlanmaz :)
paul
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.