<commit_before># Client-Server Programming

## Server Pattern

With a type and a module:

```fsharp
type Server =
  {opCh1: Ch<Request1>
   // ...
   opChN: Ch<RequestN>}

let create params =
  let chs = {opCh1 = Ch ()
             // ...
             opChN = Ch ()}
  // ...
  let rec loop state =
    // ...
    // "server" ops
    let op1 (*...*) = (*...*) chs.opCh1 (*...*)
    // ...
    let opN (*...*) = (*...*) chs.opChN (*...*)
    // ...
    match state with
     | (*...*) ->
       op? (*...*) <|> (*...*) <|> op? (*...*)
     | (*...*) ->
       op? (*...*) <|> (*...*) <|> op? (*...*)
  start <| loop state
  chs

// "client" ops
let op1 server (*...*) = (*...*) server.opCh1 (*...*)
...
let opN server (*...*) = (*...*) server.opChN (*...*)
```

With a class:

```fsharp
type Server (params) =
  let opCh1 = Ch ()
  // ...
  let opChN = Ch ()

  do // ...
     let rec loop state =
       // ...
       // "server" ops
       let op1 (*...*) = (*...*) opCh1 (*...*)
       // ...
       let opN (*...*) = (*...*) opCh2 (*...*)
       // ...
       match state with
        | (*...*) ->
          op? (*...*) <|> (*...*) <|> op? (*...*)
        | (*...*) ->
          op? (*...*) <|> (*...*) <|> op? (*...*)
     start <| loop state

  // "client" ops
  member server.op1 (*...*) = (*...*) opCh1 (*...*)
  // ...
  member server.opN (*...*) = (*...*) opChN (*...*)
```

## Call Patterns

### SyncOnReply: `unit -> Alt<Reply>`

```fsharp
server: opCh *<- Reply
```

```fsharp
client: opCh
```

#### Example: Unique id server

```fsharp
type Id () =
  let reqCh = Ch ()
  do server << Job.iterate 0 <| fun i ->
       reqCh *<- i ^->. i+1
  member s.New = reqCh :> Alt<_>
```

### SyncOnRequest: `Request -> Alt<unit>`

```fsharp
server: opCh ^=> fun Request -> // ...
```

```fsharp
client: opCh *<- Request
```

#### Example: Stack

```fsharp
type Stack<'x> () =
  let pushCh = Ch ()
  let popCh = Ch ()
  do server << Job.iterate [] <| function
       | []   -> pushCh      ^-> fun x -> [x]
       | h::t -> popCh *<- h ^->. t
             <|> pushCh      ^-> fun n -> n::h::t
  member s.Pop = popCh :> Alt<_>
  member s.Push (x: 'x) = pushCh *<- x
```

### SyncOnRequest: `Request -> Alt<unit>`

```fsharp
server: opCh ^=> function Request replyIv ->
          // ...
          replyIv *<= Reply
```

```fsharp
client: opCh *<-=>- fun replyIv -> Request replyIv
```

### SyncOnReply: `Request -> Alt<unit>`<commit_msg>Fix types<commit_after># Client-Server Programming

## Server Pattern

With a type and a module:

```fsharp
type Server =
  {opCh1: Ch<Request1>
   // ...
   opChN: Ch<RequestN>}

let create params =
  let chs = {opCh1 = Ch ()
             // ...
             opChN = Ch ()}
  // ...
  let rec loop state =
    // ...
    // "server" ops
    let op1 (*...*) = (*...*) chs.opCh1 (*...*)
    // ...
    let opN (*...*) = (*...*) chs.opChN (*...*)
    // ...
    match state with
     | (*...*) ->
       op? (*...*) <|> (*...*) <|> op? (*...*)
     | (*...*) ->
       op? (*...*) <|> (*...*) <|> op? (*...*)
  start <| loop state
  chs

// "client" ops
let op1 server (*...*) = (*...*) server.opCh1 (*...*)
...
let opN server (*...*) = (*...*) server.opChN (*...*)
```

With a class:

```fsharp
type Server (params) =
  let opCh1 = Ch ()
  // ...
  let opChN = Ch ()

  do // ...
     let rec loop state =
       // ...
       // "server" ops
       let op1 (*...*) = (*...*) opCh1 (*...*)
       // ...
       let opN (*...*) = (*...*) opCh2 (*...*)
       // ...
       match state with
        | (*...*) ->
          op? (*...*) <|> (*...*) <|> op? (*...*)
        | (*...*) ->
          op? (*...*) <|> (*...*) <|> op? (*...*)
     start <| loop state

  // "client" ops
  member server.op1 (*...*) = (*...*) opCh1 (*...*)
  // ...
  member server.opN (*...*) = (*...*) opChN (*...*)
```

## Call Patterns

### SyncOnReply: `unit -> Alt<Reply>`

```fsharp
server: opCh *<- Reply
```

```fsharp
client: opCh
```

#### Example: Unique id server

```fsharp
type Id () =
  let reqCh = Ch ()
  do server << Job.iterate 0 <| fun i ->
       reqCh *<- i ^->. i+1
  member s.New = reqCh :> Alt<_>
```

### SyncOnRequest: `Request -> Alt<unit>`

```fsharp
server: opCh ^=> fun Request -> // ...
```

```fsharp
client: opCh *<- Request
```

#### Example: Stack

```fsharp
type Stack<'x> () =
  let pushCh = Ch ()
  let popCh = Ch ()
  do server << Job.iterate [] <| function
       | []   -> pushCh      ^-> fun x -> [x]
       | h::t -> popCh *<- h ^->. t
             <|> pushCh      ^-> fun n -> n::h::t
  member s.Pop = popCh :> Alt<_>
  member s.Push (x: 'x) = pushCh *<- x
```

### SyncOnRequest: `Request -> Alt<Reply>`

```fsharp
server: opCh ^=> function Request replyIv ->
          // ...
          replyIv *<= Reply
```

```fsharp
client: opCh *<-=>- fun replyIv -> Request replyIv
```

### SyncOnReply: `Request -> Alt<Reply>`
{'fraction_non_alphanumeric': 0.292642827784628, 'fraction_numerical': 0.006165228113440197, 'mean_word_length': 1.5778601694915255, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3997707', 'n_tokens_mistral': 1912, 'n_tokens_neox': 1791, 'n_words': 418}