5 people like it.
    Like the snippet!
  
  Dining philosophers (Joinads)
  A simple and declarative solution based on Joinads.
   1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
  | 
open System
open FSharp.Extensions.Joinads
// Init
let n = 5
let chopsticks = [| for i = 1 to n do yield new Channel<unit>() |]
let hungry = [| for i = 1 to n do yield new Channel<unit>() |]
let philosophers = [| "Plato"; "Konfuzius"; "Socrates"; "Voltaire"; "Descartes" |]
let randomDelay (r : Random) = System.Threading.Thread.Sleep(r.Next(1, 10) * 1000)
// Fork 
for i = 0 to n - 1 do
    let left = chopsticks.[i]
    let right = chopsticks.[(i+1) % n]
    let random = new Random()
    join {
        match! hungry.[i], left, right with
        | _, _, _ ->
            printfn "%s is eating" philosophers.[i] 
            randomDelay random
            left.Call(); right.Call()
            printfn "%s is thinking" philosophers.[i] 
    }
    
// Run
for chopstick in chopsticks do
    chopstick.Call()
let random = new Random()    
while true do
    hungry.[random.Next(0, n)].Call()
    randomDelay random
  | 
namespace System
namespace Microsoft.FSharp
val n : int
Full name: Script.n
val chopsticks : obj []
Full name: Script.chopsticks
val i : int
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
val hungry : obj []
Full name: Script.hungry
val philosophers : string []
Full name: Script.philosophers
val randomDelay : r:Random -> unit
Full name: Script.randomDelay
val r : Random
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float
Full name: System.Random
--------------------
Random() : unit
Random(Seed: int) : unit
namespace System.Threading
Multiple items
type Thread =
  inherit CriticalFinalizerObject
  new : start:ThreadStart -> Thread + 3 overloads
  member Abort : unit -> unit + 1 overload
  member ApartmentState : ApartmentState with get, set
  member CurrentCulture : CultureInfo with get, set
  member CurrentUICulture : CultureInfo with get, set
  member DisableComObjectEagerCleanup : unit -> unit
  member ExecutionContext : ExecutionContext
  member GetApartmentState : unit -> ApartmentState
  member GetCompressedStack : unit -> CompressedStack
  member GetHashCode : unit -> int
  ...
Full name: System.Threading.Thread
--------------------
Threading.Thread(start: Threading.ThreadStart) : unit
Threading.Thread(start: Threading.ParameterizedThreadStart) : unit
Threading.Thread(start: Threading.ThreadStart, maxStackSize: int) : unit
Threading.Thread(start: Threading.ParameterizedThreadStart, maxStackSize: int) : unit
Threading.Thread.Sleep(timeout: TimeSpan) : unit
Threading.Thread.Sleep(millisecondsTimeout: int) : unit
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
val left : obj
val right : obj
val random : Random
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
  
  
  More information