2014-12-21 4 views
5

Я читаю этот блог post, который утверждает, что Futures не являются «функциональными», так как они всего лишь обертки побочные эффекты. Например, они содержат вызовы RPC, HTTP-запросы и т. Д. Правильно ли это?Являются ли фьючерсы в Scala действительно функциональными?

Сообщение в блоге приводит следующий пример:

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.

Я боюсь, я не понимаю. Не могли бы вы объяснить, как мы потеряем consistent result в этом случае?

ответ

11

В блоге не удается провести надлежащее различие между Future и тем, как оно обычно используется, ИМО. Вы можете написать чистый функциональный код с Future, если бы вы только когда-либо писали Future s, которые называли чистыми полными функциями; такой код будет ссылочно прозрачным и «функциональным» в каждом удаленно разумном смысле этого слова.

То, что Future s дает вам ограниченный контроль над побочными эффектами, , если вы используете их с методами, которые имеют побочные эффекты. Если вы создаете обертку FuturewebClient.get, то создание этого Future отправит HTTP-вызов. Но это не факт о Future, это факт о webClient.get!

В этом блоге есть доля правды. Разделяя выражение, вычисляющее ваши вычисления, выполняя его, полностью, посредством, например, Свободная монада, может привести к более эффективному и более проверяемому коду. Например. вы можете создать «язык запросов», где вы выражаете операцию, например «выборки фотографий профиля всех общих друзей A и B», без фактического запуска. Это упрощает проверку правильности вашей логики (потому что очень легко сделать, например, тестовую реализацию, которая может «запускать» одни и те же запросы или даже просто проверять «объект запроса» напрямую), и, как я думаю, сообщение в блоге пытается предложить, означает, что вы могли бы, например, объединить несколько запросов для получения одного профиля. (Это даже не чисто функциональное программирование - в некоторых книгах ОО есть идея «командного шаблона» - хотя функциональные средства программирования IME, такие как for/yield, упрощают работу таким образом). Если все, что у вас есть, это метод fetchProfile, который при запуске немедленно запускает HTTP-запрос, тогда, если ваша логика кода запрашивает один и тот же профиль дважды, нет возможности избежать получения одного и того же профиля дважды.

Но это не совсем о Future как таковой, а IMO в этом блоге более сбивает с толку, чем полезно.

+0

спасибо. Теперь понятно. Мне нравится идея разделения выражения вычислений и его выполнения. Посмотрим на «Свободную монаду» – Michael

Смежные вопросы