2014-12-21 11 views
5

Czytam ten blog post, który twierdzi, że Futures nie są "funkcjonalne", ponieważ są po prostu opakowaniami po stronie obliczeniowej obliczeń. Na przykład zawierają wywołania RPC, żądania HTTP itp. Czy to prawda?Czy Futures in Scala są naprawdę funkcjonalne?

Blog Post podaje następujący przykład:

def twoUsersFeed(a: UserHandle, b: UserHandle) 
       (implicit ec: ExecutionContext): Future[Html] = 
    for { 
    feedA <- usersFeed(a) 
    feedB <- usersFeed(b) 
    } yield feedA ++ feedB 

you lose the desired property: consistent results (the referential transparency). Also you lose the property of making as few requests as possible. It is difficult to use multi-valued requests and have composable code.

Obawiam się, że nie rozumiem. Czy możesz wyjaśnić, jak tracimy w tym przypadku consistent result?

Odpowiedz

11

Wpis na blogu nie jest w stanie narysować właściwego rozróżnienia między samym sobą i sposobem, w jaki jest powszechnie stosowany, IMO. Możesz napisać kod czysto funkcjonalny z Future, jeśli tylko napisałeś Future s, który nazywa się czystymi, totalnymi funkcjami; taki kod byłby referencyjnie przejrzysty i "funkcjonalny" w każdym zdalnie uzasadnionym znaczeniu tego słowa.

To prawda, że ​​Future s daje ograniczoną kontrolę efektów ubocznych, , jeśli używasz ich metodami mającymi efekty uboczne. Jeśli utworzysz opakowanie FuturewebClient.get, to utworzenie tego Future spowoduje wysłanie połączenia HTTP. Ale to nie jest fakt o Future, to jest fakt o webClient.get!

Na tym blogu jest ziarno prawdy. Oddzielenie wyrażania twoich obliczeń od wykonania, całkowicie, poprzez np. monada Free, może skutkować bardziej wydajnym i bardziej testowalnym kodem. Na przykład. możesz utworzyć "język zapytań", w którym wyrażasz operację, taką jak "pobierz zdjęcia profilowe wszystkich wspólnych znajomych A i B", nie uruchamiając go. Ułatwia to sprawdzenie, czy twoja logika jest poprawna (ponieważ jest bardzo łatwa do wykonania np. Implementacja testowa, która może "uruchomić" te same zapytania - lub nawet po prostu sprawdzić "obiekt zapytania" bezpośrednio) i, jak myślę, wpis na blogu próbuje zasugerować, oznacza, że ​​możesz np połączyć wiele żądań, aby pobrać ten sam profil. (To nie jest czysto problem z programowaniem funkcjonalnym - niektóre książki OO mają ideę "wzorca polecenia" - choć funkcjonalne narzędzia programistyczne IME, takie jak składnia for/yield, znacznie ułatwiają pracę w ten sposób). Natomiast jeśli masz tylko metodę fetchProfile, która po uruchomieniu natychmiastowo odpala żądanie HTTP, to jeśli twoja logika kodu żąda tego samego profilu dwukrotnie, nie ma możliwości uniknięcia dwukrotnego pobrania tego samego profilu.

Ale to nie jest tak naprawdę o Future per se, a IMO ten wpis na blogu jest bardziej zagmatwany niż pomocny.

+0

Dziękuję. Teraz to jasne. Podoba mi się idea oddzielania wyrażeń obliczeniowych i ich wykonywania. Popatrzy na 'Free monad' – Michael

Powiązane problemy