Programowanie funkcjonalne i informatyka naukowa

42

Przepraszam, jeśli jest to niejasne pytanie, ale oto:

W ciągu ostatnich kilku lat programowanie funkcjonalne cieszyło się dużym zainteresowaniem społeczności inżynierów oprogramowania. Wielu zaczęło używać języków takich jak Scala i Haskell i odniosło sukces w porównaniu z innymi językami programowania i paradygmatami. Moje pytanie brzmi: jako eksperci w dziedzinie obliczeń o wysokiej wydajności / naukowcy powinniśmy być zainteresowani programowaniem funkcjonalnym? Czy powinniśmy uczestniczyć w tej mini-rewolucji?

Jakie są zalety i wady programowania funkcjonalnego w dziedzinie pracy SciComp?

Śledztwo
źródło
2
Dlaczego celowo wkładasz kurtkę prostą? Efekty uboczne to narzędzie; jest niezbędny do zastosowań w świecie rzeczywistym. Jeśli chcesz wydajności procesora i pamięci, funkcjonalne języki programowania nie byłyby na moim radarze. Programy, które wymagają automatycznej weryfikacji / sprawdzenia poprawności (np. Do użytku w placówce nuklearnej?), To może być przypadek.
Kolejka uczniów

Odpowiedzi:

34

Zrobiłem tylko trochę programowania funkcjonalnego, więc weź tę odpowiedź z odrobiną soli.

Plusy:

  • Programowanie funkcjonalne wygląda bardzo matematycznie; to ładny paradygmat wyrażania niektórych pojęć matematycznych
  • Dostępne są dobre biblioteki do takich rzeczy jak formalna weryfikacja programów i dowodzenie twierdzeń, więc możliwe jest pisanie programów, które dotyczą programów - ten aspekt jest dobry dla odtwarzalności
  • Możesz programować funkcjonalnie w Pythonie i C ++ za pomocą wyrażeń lambda; możesz także programować funkcjonalnie w Julii i Mathematica
  • Niewiele osób z niego korzysta, więc możesz być pionierem. Podobnie jak byli pierwsi użytkownicy MATLAB-a, Pythona, R, a teraz Julia, muszą być wcześni użytkownicy programowania funkcjonalnego, aby mógł się uchwycić

Cons:

  • Języki, które są zwykle uważane za funkcjonalne języki programowania, takie jak Haskell, OCaml (i inne dialekty ML) i Lisp są ogólnie uważane za wolne w stosunku do języków używanych do obliczeń naukowych o krytycznym znaczeniu dla wydajności. OCaml jest co najwyżej o połowę szybszy niż C.
  • W tych językach brakuje infrastruktury bibliotecznej w porównaniu do języków powszechnie używanych w informatyce (Fortran, C, C ++, Python); jeśli chcesz rozwiązać środowisko PDE, o wiele łatwiej jest to zrobić w języku powszechnie stosowanym w informatyce niż w innym języku.
  • Społeczność naukowa zajmująca się obliczeniami używająca funkcjonalnych języków programowania nie jest tak duża, jak języki proceduralne, co oznacza, że ​​nie uzyskasz dużej pomocy w nauce lub debugowaniu, a ludzie prawdopodobnie dadzą ci bzdury korzystanie z niego (niezależnie od tego, czy na to zasługujesz)
  • Styl programowania funkcjonalnego jest inny niż styl programowania proceduralnego, którego zwykle uczy się na wstępnych zajęciach z informatyki i na zajęciach typu „MATLAB dla naukowców i inżynierów”

Myślę, że wiele zastrzeżeń w sekcji „Wady” da się przezwyciężyć. Jak jest to częstym punktem dyskusji na tej stronie Stack Exchange, czas programisty jest ważniejszy niż czas wykonania. Nawet jeśli funkcjonalne języki programowania są powolne, jeśli części krytyczne pod względem wydajności można przekazać do szybszego języka proceduralnego i jeśli wzrost wydajności można wykazać poprzez szybki rozwój aplikacji, to warto je wykorzystać. Warto tutaj zauważyć, że programy zaimplementowane w czystym Pythonie, czystym MATLAB i czystym R są znacznie wolniejsze niż implementacje tych samych programów w C, C ++ lub Fortran. Języki takie jak Python, MATLAB i R są popularne właśnie dlatego, że zmniejszają szybkość wykonywania dla wydajności, a nawet wtedy, Zarówno Python, jak i MATLAB mają udogodnienia do implementacji interfejsów do skompilowanego kodu w C lub C ++, aby można było zaimplementować kluczowy dla wydajności kod w celu szybkiego wykonania. Większość języków ma interfejs funkcji obcych do C, co wystarczyłoby do współpracy z większością bibliotek interesujących naukowców zajmujących się obliczeniami.

Czy powinieneś być zainteresowany programowaniem funkcjonalnym?

Wszystko zależy od tego, co uważasz za fajne. Jeśli jesteś typem osoby, która jest gotowa obalić konwencję i chcesz przejść przez hasło ewangelizacji do ludzi na temat cokolwiek, co chcesz zrobić z programowaniem funkcjonalnym, powiedziałbym, że idź . Bardzo chciałbym zobaczyć, jak ludzie robią fajne rzeczy z programowaniem funkcjonalnym w nauce obliczeniowej, jeśli tylko z tego powodu, aby udowodnić, że wszyscy naysayers się mylą (i będzie wielu naysayers). Jeśli nie jesteś typem osoby, która chce poradzić sobie z grupą ludzi pytających: „Dlaczego, u diabła , używasz funkcjonalnego języka programowania zamiast (wstaw tutaj swój ulubiony język programowania proceduralnego)?”, To nie przeszkadzam.

Do prac wymagających intensywnej symulacji użyto funkcjonalnych języków programowania. Firma ilościowa Jane Street wykorzystuje OCaml do modelowania finansowego i realizacji swoich strategii handlowych. OCaml był również używany w FFTW do generowania kodu C używanego w bibliotece. Liszt to język specyficzny dla domeny opracowany w Stanford i zaimplementowany w Scali, który służy do rozwiązywania PDE. Programowanie funkcjonalne jest zdecydowanie stosowane w przemyśle (niekoniecznie w nauce obliczeniowej); okaże się, czy wystartuje w nauce obliczeniowej.

Geoff Oxberry
źródło
4
Chciałbym przyczynić się do dodania wersji Pro i Con. Elastyczność Pro :: code: ponieważ wszystko jest funkcją, zawsze możesz wywołać tę funkcję za pomocą innej funkcji; to jest niezwykle potężne. Con :: czytelność kodu: funkcjonalne kody programowania są naprawdę trudne do odczytania; nawet dla (większości) ludzi, którzy je napisali. Nawet teraz zajmuje mi trochę czasu zrozumienie starych kodów, które napisałem, aby rozwiązać niektóre ogólne problemy PDE z splajnami B w Mathematica 6 miesięcy temu; Zawsze wyciągam ten kod, gdy chcę przestraszyć niektórych kolegów ;-).
seb
4
Jedynym dodatkiem, który chciałbym dodać, jest: Con :: zużycie pamięci . Trzeba dużo kopiować, aby wyeliminować skutki uboczne.
Matthew Emmett,
1
@StefanSmith: (i) Wiem, że czasami jest wykorzystywany w badaniach (na przykład, Maxima to CAS oparty na Lisp); poza tym nie wiem od samego początku. (ii) Nie mam pojęcia. Duża część mojej odpowiedzi była oparta na niepotwierdzonych dowodach zebranych w rozmowach, które przeprowadziłem w ciągu ostatnich kilku lat.
Geoff Oxberry
@seb, brzmi to tak, jakbyś opisywał właściwości języków funkcjonalnych podobnych do Lisp, które nie odnoszą się równie dobrze do języków funkcjonalnych podobnych do Haskella.
Mark S.
1
Duże głosowanie na komentarz @MatthewEmmett. Kopiowanie może być bardzo kosztowne w przypadku obliczeń o wysokiej wydajności.
Charles,
10

Mam może wyjątkową perspektywę, ponieważ jestem praktykiem HPC z doświadczeniem naukowym w obliczeniach, a także użytkownikiem funkcjonalnego języka programowania. Nie chcę utożsamiać HPC z obliczeniami naukowymi, ale istnieje znaczące skrzyżowanie, i taki jest punkt widzenia, w którym biorę na to pytanie.

Języki funkcjonalne raczej nie będą w tej chwili stosowane w HPC przede wszystkim dlatego, że użytkownicy i klienci HPC naprawdę dbają o osiągnięcie jak najbliższej szczytowej wydajności. Prawdą jest, że kod napisany w sposób funkcjonalny w naturalny sposób ujawnia paralelizm, który można wykorzystać, ale w HPC to nie wystarczy. Równoległość jest tylko jednym z elementów układanki w osiąganiu wysokiej wydajności, należy również wziąć pod uwagę szeroką gamę detali mikroarchitektonicznych, a wykonywanie tego na ogół wymaga bardzo drobiazgowej kontroli nad wykonywaniem kodu, kontrola ta nie jest dostępna w żadnym języki funkcjonalne, które znam.

To powiedziawszy, mam duże nadzieje, że to może się zmienić. Zauważyłem trend, że badacze zaczynają zdawać sobie sprawę, że wiele z tych mikro-architektonicznych optymalizacji można zautomatyzować (do pewnego stopnia). Spowodowało to powstanie zoo technologii kompilacji między źródłami, w której użytkownik wprowadza „specyfikację” obliczeń, które chcą mieć, a kompilator wyprowadza kod C lub Fortran, który realizuje to obliczenie z optymalizacjami i równoległością niezbędną do wydajnego działania użyj architektury docelowej. Nawiasem mówiąc, do tego dobrze funkcjonują języki funkcjonalne: modelowanie i analiza języków programowania. To nie przypadek, że pierwszymi głównymi użytkownikami języków funkcjonalnych byli twórcy kompilatorów. Z kilkoma znaczącymi wyjątkami, nie widziałem, aby to się faktycznie trzymało, ale pomysły już istnieją,

Reid.Atcheson
źródło
8

Chciałbym dodać jeden aspekt do pozostałych dwóch odpowiedzi. Poza ekosystemem programowanie funkcjonalne stanowi doskonałą okazję do równoległego wykonywania, takiego jak wielowątkowość lub przetwarzanie rozproszone. Jego nieodłączne właściwości niezmienności sprawiają, że nadaje się on do równoległości, która generalnie jest prawdziwym bólem w * bleep *, jeśli chodzi o języki imperatywne.

Ponieważ poprawa wydajności sprzętu w ostatnich latach koncentrowała się na dodawaniu rdzeni do procesorów zamiast na zwiększaniu częstotliwości, obliczenia równoległe stają się coraz bardziej popularne (założę się, że wszyscy o tym wiedzą).

Inną rzeczą, o której wspomina Geoff, jest to, że czas programisty jest często ważniejszy niż czas wykonania. Pracuję dla firmy, która buduje intensywny obliczeniowo SaaS i przeprowadziliśmy wstępny test wydajności, zaczynając od C ++ vs Java. Okazało się, że C ++ zapewnia około 50% skrócenie czasu wykonania w stosunku do Java (dotyczyło to geometrii obliczeniowej, a liczby najprawdopodobniej będą się różnić w zależności od aplikacji), ale i tak poszliśmy z Javą ze względu na znaczenie czasu programisty i mieliśmy nadzieję, że optymalizacje i przyszłe ulepszenia wydajności sprzętu pomogłyby nam wejść na rynek. Mogę powiedzieć z pewnością, że gdybyśmy wybrali inaczej, nie prowadzilibyśmy działalności.

Ok, ale Java nie jest funkcjonalnym językiem programowania, więc co może mieć z tym wspólnego, możesz zapytać. Później, kiedy zatrudniliśmy więcej zwolenników paradygmatu funkcjonalnego i natknęliśmy się na potrzebę paralellizacji, stopniowo migrowaliśmy części naszego systemu do Scali, która łączy pozytywne aspekty programowania funkcjonalnego z siłą imperatywu i dobrze łączy się z Jawa. Ogromnie pomógł nam, zwiększając wydajność naszego systemu przy minimalnym bólu głowy i prawdopodobnie nadal będzie czerpał korzyści z dalszego wzrostu wydajności w branży sprzętowej, gdy więcej rdzeni zostanie wciśniętych w procesory jutra.

Zauważ, że całkowicie zgadzam się z wadami wymienionymi w innych odpowiedziach, ale pomyślałem, że ułatwienie równoległego wykonywania jest tak potężnym profesjonalistą, że nie można go pominąć.

mags
źródło
8

Geoff przedstawił już dobry przegląd powodów, do których niewiele dodałem, oprócz podkreślenia jednego z jego punktów: ekosystemu. Niezależnie od tego, czy opowiadasz się za programowaniem funkcjonalnym, czy za jakimkolwiek innym paradygmatem, jednym z ważnych pytań, na które musisz odpowiedzieć, jest to, że istnieje niesamowita ilość oprogramowania, z którego każda inna osoba może zbudować, którą musisz ponownie napisać. Przykładami są MPI, PETSc lub Trilinos dla algebry liniowej lub dowolnej biblioteki elementów skończonych - wszystkie napisane w C lub C ++. W systemie występuje ogromna bezwładność, może nie dlatego, że wszyscy uważają, że C / C ++ jest w rzeczywistości najlepszym językiem do pisania oprogramowania obliczeniowego, ale ponieważ wiele osób spędzało lata życia, tworząc coś, co jest przydatne dużo ludzi.

Myślę, że większość ludzi obliczeniowych zgodzi się, że wypróbowanie nowych języków programowania i ocena ich przydatności do tego problemu jest bardzo cenna. Ale będzie to trudny i samotny czas, ponieważ nie będziesz w stanie osiągnąć wyników, które byłyby konkurencyjne w stosunku do tego, co robią wszyscy inni. Może również przynieść ci reputację kogoś, kto rozpoczął następny krok do innego paradygmatu programistycznego. Hej, zastąpienie Fortran zajęło C ++ około 15 lat!

Wolfgang Bangerth
źródło
6
A C ++ jest w najlepszym razie tylko w połowie drogi do zastąpienia Fortrana w tej przestrzeni. Przez cały czas widzimy nowe kody w Fortranie i mnóstwo starszych programów!
Bill Barth
2
C ++ (w przeciwieństwie do Fortrana) jest zbyt skomplikowany, aby mógł się uczyć i używać. Nowe kody naukowe o otwartym kodzie źródłowym są wciąż pisane w Fortranie. Godne uwagi w mojej dziedzinie (nauki o Ziemi) są PFlotran, SPECFEM3D, GeoFEM itp. To samo dotyczy prawie wszystkich nowych kodów w naukach o atmosferze. IMHO C ++ nawet nie zastąpił tego, co miał zastąpić (C).
stali
1
Powinieneś wypróbować Fortran, Wolfgang, jest to świetny język, łatwy do nauki / pisania, a szybkość cię nie zawiedzie.
Ondřej Čertík
3
Nie dbam o szybkość (cóż, robię trochę, ale nie jest to nadrzędna uwaga dla innych). Liczy się dla mnie to, jak długo zajmuje mi zaprogramowanie złożonego algorytmu, a Fortran przegrywa na tym froncie, ponieważ język jest tak prosty. Brak standardowej biblioteki, o której można mówić, brak szablonów pozwalających na generyczny kod, orientacja obiektu na wpół oceniana. Fortran po prostu nie jest moim językiem i, szczerze mówiąc, nie powinien być również dla prawie wszystkich innych naukowców zajmujących się informatyką.
Wolfgang Bangerth,
4
@StefanSmith: Tak. Może to być uzasadniony pomysł w informatyce naukowej (gdzie nadal twierdzę, że jest przestarzały i nieproduktywny). Z pewnością nie da się tego obronić w zakresie edukacji studentów - ponieważ większość naszych studentów opuszcza uczelnie, aw przemyśle praktycznie nikt nie korzysta z Fortranu.
Wolfgang Bangerth
7

Oto krótkie podsumowanie

  1. Obliczenia numeryczne wykorzystują zmienność / skutki uboczne, aby osiągnąć większość swoich przyspieszeń i zmniejszyć przydziały (wiele funkcjonalnych struktur programowania ma niezmienne dane)
  2. Leniwa ocena może być trudna w użyciu z kodami numerycznymi.
  3. Albo tworzysz pakiet, w którym naprawdę ważne jest zejście do najniższych poziomów wydajności (C / Fortran lub teraz Julia) (w nich możesz również edytować kod asemblera, jeśli to konieczne), lub piszesz skrypt, który korzysta z tych szybkich bibliotek więc najczęściej zależy ci na czasie programowania (więc wybierasz Julię / MATLAB / Python / R). Języki funkcjonalne zwykle znajdują się na dziwnym środku, który jest pomocny w innych dyscyplinach, ale tutaj nie jest tak pomocny.
  4. xnxn+1

Te fakty razem sprawiają, że programowanie funkcjonalne nie wydaje się konieczne dla większości użytkowników.

Chris Rackauckas
źródło
+1, ale jeden dodatek do punktu 3: Myślę, że funkcje funkcjonalne w językach wysokiego poziomu są dość przydatne, a wiele zalet języków funkcjonalnych wymienionych w innych odpowiedziach (np. Łatwa równoległość) ma zastosowanie do tego scenariusza.
Szabolcs
3

Myślę, że warto zauważyć, że zastosowanie programowania funkcjonalnego w nauce obliczeniowej nie jest nowe. Na przykład w tym dokumencie z 1990 r. Pokazano, jak poprawić wydajność programów numerycznych napisanych w Lisp (prawdopodobnie najwcześniejszym funkcjonalnym języku programowania) przy użyciu częściowej oceny. Praca ta była częścią łańcucha narzędzi stosowanego w artykule z 1992 r. Autorstwa GJ Sussmana ( znanego z SICP ) i J Wisdom, który dostarczył liczbowych dowodów na chaotyczne zachowanie Układu Słonecznego . Więcej informacji o sprzęcie i oprogramowaniu uczestniczącym w tych obliczeniach można znaleźć tutaj .

Juan M. Bello-Rivas
źródło
1

R jest językiem funkcjonalnym, a także językiem statystycznym (i teraz uczeniem maszynowym), a właściwie językiem numer 1 dla statystyk. Nie jest to jednak język HPC: nie jest on używany do tradycyjnego „łamania liczb”, takiego jak symulacje fizyki itp. Można go jednak uruchomić na masywnych klastrach (np. Przez MPI) do masowych symulacji statystycznych (MCMC) uczenia maszynowego.

Mathematica jest także językiem funkcjonalnym, ale jego podstawową domeną jest przetwarzanie symboliczne, a nie obliczenia numeryczne.

W Julii możesz także programować w funkcjonalnym stylu (obok procedur i ich smaku OO (multi-dispatch)), ale nie jest to czyste (wszystkie podstawowe struktury danych są zmienne (z wyjątkiem krotek), chociaż istnieją pewne biblioteki z niezmiennymi funkcjonalne struktury danych. Co ważniejsze, jest znacznie wolniejsze niż styl proceduralny, więc nie jest często używane.

Nie nazwałbym Scali językiem funkcjonalnym, a raczej hybrydą obiektowo-funkcjonalną. W Scali można używać wielu koncepcji funkcjonalnych. Scala jest ważna w chmurze obliczeniowej ze względu na Spark ( https://spark.apache.org/ ).

Zauważ, że współczesny Fortran ma w rzeczywistości pewne elementy programowania funkcjonalnego: ma ścisłą semantykę wskaźnika (w przeciwieństwie do C), możesz mieć czyste (bez efektów ubocznych) funkcje (i oznaczyć to jako takie) i możesz mieć niezmienność. Ma nawet inteligentne indeksowanie, w którym można określić warunki dla indeksów macierzowych. Jest to zapytanie podobne i zwykle spotykane tylko w języku wysokiego poziomu, takim jak R LINQ w języku C # lub poprzez funkcje filtrów wyższego rzędu w językach funkcjonalnych. Tak więc Fortran wcale nie jest taki zły, ma nawet całkiem nowoczesne funkcje (np. Wspólne tablice), których nie ma w wielu językach. W rzeczywistości w przyszłych wersjach Fortran wolałbym raczej dodawać więcej funkcji funkcjonalnych niż funkcje OO (co obecnie ma miejsce zwykle), ponieważ OO w Fortran jest naprawdę niezręczny i brzydki.

Steven Sagaert
źródło
1

Plusy to „narzędzia” wbudowane w każdy język funkcjonalny: filtrowanie danych jest tak łatwe, iteracja danych jest łatwiejsza, a znalezienie łatwiejszego i bardziej zwięzłego rozwiązania problemów jest o wiele łatwiejsze.

Jedynym minusem jest to, że musisz skupić się na nowym sposobie myślenia: zajęło trochę czasu, aby dowiedzieć się, co musisz wiedzieć. Inni w domenie SciComp tak naprawdę nie używają tych języków, co oznacza, że ​​nie można uzyskać tak dużego wsparcia :(

Jeśli interesują Cię języki funkcjonalne-naukowe, opracowałem jeden https://ac1235.github.io

ein mensch
źródło
1

Oto moje argumenty przemawiające za tym, dlaczego programowanie funkcjonalne może i powinno być wykorzystywane w nauce obliczeniowej. Korzyści są ogromne, a wady szybko znikają. Moim zdaniem jest tylko jeden oszust:

Wada : brak obsługi języka w C / C ++ / Fortran

Przynajmniej w C ++ ta zniknie - ponieważ C ++ 14/17 dodał potężne narzędzia do obsługi programowania funkcjonalnego. Być może będziesz musiał napisać kod biblioteki / wsparcia samodzielnie, ale językiem będzie twój przyjaciel. Jako przykład podajemy bibliotekę (ostrzeżenie: wtyczka), która wykonuje niezmienne wielowymiarowe tablice w C ++: https://github.com/jzrake/ndarray-v2 .

Oto link do dobrej książki na temat programowania funkcjonalnego w C ++, chociaż nie jest on skoncentrowany na aplikacjach naukowych.

Oto moje podsumowanie tego, co według mnie jest profesjonalistą:

Plusy :

  • Poprawność
  • Wyrozumiałość
  • Występ

Jeśli chodzi o poprawność , programy funkcjonalne są wyraźnie dobrze postawione : zmuszają cię do prawidłowego zdefiniowania minimalnego stanu zmiennych fizycznych oraz funkcji, która przesuwa ten stan do przodu w czasie:

int main()
{
    auto state = initial_condition();

    while (should_continue(state))
    {
        state = advance(state);
        side_effects(state);
    }
    return 0;
}

Rozwiązanie równania różniczkowego cząstkowego (lub ODE) jest idealne do programowania funkcjonalnego; po prostu zastosujesz czystą funkcję ( advance) do bieżącego rozwiązania, aby wygenerować następne.

Z mojego doświadczenia wynika, że ​​oprogramowanie do symulacji fizyki jest zasadniczo obciążone złym zarządzaniem stanem . Zwykle każdy etap algorytmu działa na pewnym stanie wspólnego (efektywnie globalnego) stanu. Utrudnia to, a nawet uniemożliwia, zapewnienie prawidłowej kolejności operacji, pozostawiając oprogramowanie podatne na błędy, które mogą objawiać się jako błędy seg, lub, co gorsza, warunki błędów, które nie powodują awarii kodu, ale dyskretnie naruszają integralność jego wiedzy wynik. Próba zarządzania stanem współdzielonym w symulacji fizyki również hamuje wielowątkowość - co stanowi problem na przyszłość, ponieważ superkomputery zmierzają w kierunku większej liczby rdzeni, a skalowanie z MPI często kończy się na ~ 100 tys. Zadań. Natomiast programowanie funkcjonalne sprawia, że ​​paralelizm pamięci współużytkowanej jest trywialny ze względu na niezmienność.

Wydajność poprawia się również w programowaniu funkcjonalnym ze względu na leniwą ocenę algorytmów (w C ++ oznacza to generowanie wielu typów w czasie kompilacji - często po jednym dla każdej aplikacji funkcji). Ale zmniejsza obciążenie dostępu do pamięci i przydziałów, a także eliminuje wirtualną wysyłkę - pozwalając kompilatorowi zoptymalizować cały algorytm, widząc jednocześnie wszystkie obiekty funkcyjne, które go zawierają. W praktyce będziesz eksperymentować z różnymi ustawieniami punktów oceny (w których wynik algorytmu jest buforowany do bufora pamięci), aby zoptymalizować wykorzystanie procesora w porównaniu do alokacji pamięci. Jest to raczej łatwe ze względu na dużą lokalizację (patrz przykład poniżej) etapów algorytmu w porównaniu z tym, co zwykle zobaczysz w module lub kodzie opartym na klasach.

Programy funkcjonalne są łatwiejsze do zrozumienia, o ile trywializują stan fizyki. Nie oznacza to, że ich składnia jest zrozumiała dla wszystkich twoich kolegów! Autorzy powinni zachować ostrożność przy korzystaniu z dobrze nazwanych funkcji, a badacze powinni przyzwyczaić się do tego, że algorytmy są wyrażane funkcjonalnie, a nie proceduralnie. Przyznaję, że brak struktur kontrolnych może być dla niektórych zniechęcający, ale nie sądzę, że powinno to powstrzymywać nas przed pójściem w przyszłość, by móc robić lepszą naukę na komputerach.

Poniżej znajduje się przykładowa advancefunkcja, zaadaptowana z kodu o skończonej objętości za pomocą ndarray-v2pakietu. Zwróć uwagę na to_sharedoperatory - są to punkty oceny, o których wspominałem wcześniej.

auto advance(const solution_state_t& state)
{
    auto dt = determine_time_step_size(state);
    auto du = state.u
    | divide(state.vertices | volume_from_vertices)
    | nd::map(recover_primitive)
    | extrapolate_boundary_on_axis(0)
    | nd::to_shared()
    | compute_intercell_flux(0)
    | nd::to_shared()
    | nd::difference_on_axis(0)
    | nd::multiply(-dt * mara::make_area(1.0));

    return solution_state_t {
        state.time + dt,
        state.iteration + 1,
        state.vertices,
        state.u + du | nd::to_shared() };
}
Jonathan Zrake
źródło