
A Fairy Tale of F# and Durable Functions - kiyanwang
https://hackernoon.com/a-fairy-tale-of-f-and-durable-functions-975ccc4d46b8
======
LandR
Nice article.

F# can be so readable, e.g.:

    
    
       // WishList -> Async<Reservation>
       let workflow (wishlist: WishList) = async {
    
          // 1. Find matches for each wish 
           let! matches = 
               wishlist.Wishes
               |> List.map findMatchingGift
               |> Async.Parallel
    
           // 2. Pick one product from the combined list of matches
           let gift = pickGift (List.concat matches)
        
           // 3. Register and return the reservation
           let reservation = { Kid = wishlist.Kid; Product = gift }
           do! reserve reservation
           return reservation
       }
       view raw
       durable-fsharp
    

Could basically be how you would write pseudocode.

Side note: How do I stop sites like hackernoon blocking my back button? It's
so annoying!

~~~
arwhatever
I went through a phase where I tried making the entry point of each project or
major module read like nothing more than:

inputs |> step1 |> step2 |> step3 |> etc

... and it seemed mostly doable, although I would wind up needing a layer of
parameter rearrangement functions to make it read quite that cleanly. I don't
know if I have a concrete opinion on how it worked out - I suppose I need to
get back into doing this some more.

I suspect that if I were to try to hide an async workflow behind such an
arrangement that the parameter-rearrangement layer might create a greater cost
than a benefit.

But still, it's really neat that the language allows for this sort of attempt.

~~~
jcmoscon
This is why I love Haskell. You can easily define your own "|>" operator:

(|>) :: a -> (a -> b) -> b x |> f = apply x f

~~~
platz
but nobody uses it because "function composition" reads the other way and
tends to be preferable i.e.

    
    
      (g ∘ f)(x) = g (f(x))    // math
    
      (g . f) x  = g (f x)     // haskell
    
       g   f  x    g  f x      // see how the g f x order always matches with the default application and composition notation.
    

you can mess with the order and "turn the order of application "inside-out"
but then you have to switch modes from left-to-right and right-to-left more
often. Or you can try to write in a style that prefers right-to-left.

~~~
solinent

        g f x 
    

would not be the same as

    
    
        (g . f) x
    

you need the right associative function application operator $, ie.

    
    
        g $ f x
    

or simply

    
    
        g (f x)

~~~
platz
i know that, i was just highlighting the appearance of the order of the
letters without considering associativity.

------
macca321
It is a nice article, but one thing I don't like is that it picks Event Driven
Architecture without spelling out the reasons _why_.

"We used Azure Storage Queues to keep the whole flow asynchronous and more
resilient to failures and load fluctuation."

That's not enough for me. I often encounter people building complex systems
message queuing, despite failures being rare, retries being cheap and fast,
and the hardware already being resilient to load.

In this article, a simple explanation of why each step actually _needs_
EDA/queues would be great - e.g. as the Product Matcher algorithm occasionally
can't read a child's writing, an elf has to manually contact the child's
parents to find out what they want so it can take a very long time.

~~~
TrueTeller
Hi, the author here. It's a good point and a valid concern, but I did an
explicit choice here: I didn't want to make the article longer. I have a
prequel post which describes my thinking of why durable functions make sense,
including a primer for the event-driven approach:
[https://hackernoon.com/making-sense-of-azure-durable-
functio...](https://hackernoon.com/making-sense-of-azure-durable-
functions-645ecb3c1d58)

~~~
macca321
Cool - so that article you link sets the context for the second.

I do think it does HTTP a disservice though - when you switch from HTTP to EDA
you ditch the well known Uniform Interface and a lot of the benefits you get
for free,(i.e. robust caching/proxying/routing, all the things a Service Mesh
can do).

Instead of ditching HTTP, it would be nice to see people building async HTTP
APIs, where the API responds with 201 Accepted (probably using a message queue
behind the scenes) rather than the brittle systems you describe, where
everything comes back under a 200.

~~~
macca321
whoops 202 Accepted :D

------
philonoist
If I may ask, which language is more functional feature wise, F# or OCaml?

~~~
daxfohl
"More functional" is not a precise term. However OCaml would fit most
everyone's idea of "functional" more than F#. F# has to be compatible with the
underlying .Net runtime, so it cannot have features like abstraction over
modules, which is a very powerful functional abstraction in OCaml. F# also
builds mostly on libraries built in C#, so unless you want to build wrappers
on top of everything, you'll be doing a lot of OOP in F# as well. (Which I
think is fine, I think OOP fits well in lots of cases and it's nice to be able
to mix and match).

