Skip to content

Commit

Permalink
docs: Expand documentation structure
Browse files Browse the repository at this point in the history
  • Loading branch information
DragonFrai committed Oct 14, 2024
1 parent ef7cee6 commit 88656b6
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 130 deletions.
31 changes: 29 additions & 2 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,32 @@

# Basics

- [Creating](ru/basics/creating.md)
- [Running](ru/basics/running.md)
- [Creating](ru/basics/creating/creating.md)
- [Functions](ru/basics/creating/creating-functions.md)
- [Computation Expressions](ru/basics/creating/creating-comp-expr.md)
- [From Async and Task](ru/basics/creating/creating-of-async-task.md)
- [Manual implementation](ru/basics/creating/creating-manual.md)

- [Running](ru/basics/running/running.md)
- [Without runtime](ru/basics/running/running-runtimeless.md)
- [On runtime](ru/basics/running/running-runtime.md)

- [Synchronisation]()
- ["Low-level" synchronisation primitives]()
- [Semaphore]()
- [Barrier]()
- [Mutex]()
- [RwLock]()
- [Notify]()
- [CondVar]()
- [OneShot]()
- ["High level" synchronisation primitives]()
- [OnceVar]()
- [LazyVar]()
- [MutexVar]()
- [RwLockVar]()
- [Mailbox]()

# Advanced

- [Implementation details](ru/advanced/implementation-details.md)
File renamed without changes.
63 changes: 63 additions & 0 deletions docs/ru/basics/creating/creating-comp-expr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Создание Future используя Future CE

Future имеет свой CE, который используется также как async или task CE встроенные в F#.
Более подробно о CE вы можете прочитать на [сайте](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions).

Например, мы можем заменить базовые функции создания на future CE:
```fsharp
let ready = future { return "Hello, world!" } // ~ Future.ready "Hello, world!"
let lazy' = future { return (foo ()) } // ~ Future.lazy' (fun () -> foo ())
```

Наиболее важным свойством CE является упрощение работы с bind.
Пример чтения-записи можно переписать используя CE так:

```fsharp
// readFileAsync: filePath: string -> Future<string>
// writeFileAsync: filePath: string -> content: string -> Future<unit>
let readAndWriteFuture = futur {
let! content = readFileAsync "my-file.txt"
return! writeFileAsync "other-file.txt" content
}
```

Видимым преимуществом CE является возможность "уплощить" цепочка bind, зависимых между собой.
Пример множественно зависимых bind можно переписать так:

```fsharp
let doManyWorkWithCrossResults = future {
let! val1 = doWork1 ()
let! val2 = doWork2 val1
let! val3 = doWork3 val1 val2
...
let! valN = doWorkN val1 val2 ... valPrevN
}
```

Также CE добавляют синтаксис и для Future.merge или Future.catch комбинаторов.

```fsharp
let parallelCE = future {
let! val1 = doWork1 ()
and! val2 = doWork2 ()
and! val3 = doWork3 ()
}
```

```fsharp
let catchCE = future {
try
do! doWork ()
with ex ->
printfn $"{ex}"
}
```

```fsharp
let tryFinally = future {
try
do! doWork ()
finally
do finallize ()
}
```
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
# Создание объекта Future

Создать асинхронное вычисление в лице Future можно большим количеством способов.


## Использование функций-комбинаторов
# Создание Future используя функции-комбинаторы

Используя функции модуля Future можно создать базовые и получить скомбинированные
вариации Future. Разберем базовые функции создания.
Expand Down Expand Up @@ -74,7 +69,7 @@ let doManyWorkWithCrossResults =
doWork2 val1
|> Future.bind (fun val2 ->
doWork3 val1 val2
|> Future.bind (fun val 3 -> ...)))
|> Future.bind (fun val3 -> ...)))
```

Future.bind позволяет соединять асинхронные вычисления в последовательную цепочку,
Expand Down Expand Up @@ -116,103 +111,3 @@ let doubleFut = fut |> Future.bind (fun () -> fut)
let doubleFut = someAsyncWork () |> Future.bind (fun () -> someAsyncWork ())
```
</div>


## Использование Future CE

Future имеет свой CE, который используется также как async или task CE встроенные в F#.
Более подробно о CE вы можете прочитать на [сайте](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions).

Например, мы можем заменить базовые функции создания на future CE:
```fsharp
let ready = future { return "Hello, world!" } // ~ Future.ready "Hello, world!"
let lazy' = future { return (foo ()) } // ~ Future.lazy' (fun () -> foo ())
```

Наиболее важным свойством CE является упрощение работы с bind.
Пример чтения-записи можно переписать используя CE так:

```fsharp
// readFileAsync: filePath: string -> Future<string>
// writeFileAsync: filePath: string -> content: string -> Future<unit>
let readAndWriteFuture = futur {
let! content = readFileAsync "my-file.txt"
return! writeFileAsync "other-file.txt" content
}
```

Видимым преимуществом CE является возможность "уплощить" цепочка bind, зависимых между собой.
Пример множественно зависимых bind можно переписать так:

```fsharp
let doManyWorkWithCrossResults = future {
let! val1 = doWork1 ()
let! val2 = doWork2 val1
let! val3 = doWork3 val1 val2
...
let! valN = doWorkN val1 val2 ... valPrevN
}
```

Также CE добавляют синтаксис и для Future.merge или Future.catch комбинаторов.

```fsharp
let parallelCE = future {
let! val1 = doWork1 ()
and! val2 = doWork2 ()
and! val3 = doWork3 ()
}
```

```fsharp
let catchCE = future {
try
do! doWork ()
with ex ->
printfn $"{ex}"
}
```

```fsharp
let tryFinally = future {
try
do! doWork ()
finally
do finallize ()
}
```


## Преобразование из Async и Task

Существующие Async и Task можно преобразовать в Future и использовать результат их работы.
Исходные Async и Task будут запущены на своих родных системах запуска, но их результат будет
передан через возвращенную Future.

```fsharp
let asyncToFuture = Future.ofAsync (async { ... })
let taskToFuture = Future.ofTask (task { ... })
```

Возможны и обратные преобразования. При этом Future будут запущены на механизме запуска
соответствующего примитива при запуске этого примитива.

```fsharp
let futureToAsync = Future.ofAsync (async { ... })
let futureToTask = Future.ofTask (task { ... })
```


## Ручная реализация Future

Future это всего-лишь интерфейс с методами Poll и Drop.
Можно создать свою Future просто реализовав их.

Ручная реализация Future корректным образом не такая тривиальная задача,
требующая ручной реализации конечного или не очень автомата.
Поэтому не рекомендуется делать это, только если Вы не разрабатываете
API для использования механизма асинхронности на низком уровне.

Объяснения и более подробные примеры следует искать в более продвинутых главах.


12 changes: 12 additions & 0 deletions docs/ru/basics/creating/creating-manual.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Создание Future ручной реализацией Future

Future это всего-лишь интерфейс с методами Poll и Drop.
Можно создать свою Future просто реализовав их.

Ручная реализация Future корректным образом не такая тривиальная задача,
требующая ручной реализации конечного или не очень автомата.
Поэтому не рекомендуется делать это, только если Вы не разрабатываете
API для использования механизма асинхронности на низком уровне.

Объяснения и более подробные примеры следует искать в более продвинутых главах.

19 changes: 19 additions & 0 deletions docs/ru/basics/creating/creating-of-async-task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Создание Future из Async и Task

Существующие Async и Task можно преобразовать в Future и использовать результат их работы.
Исходные Async и Task будут запущены на своих родных системах запуска, но их результат будет
передан через возвращенную Future.

```fsharp
let asyncToFuture = Future.ofAsync (async { ... })
let taskToFuture = Future.ofTask (task { ... })
```

Возможны и обратные преобразования. При этом Future будут запущены на механизме запуска
соответствующего примитива при запуске этого примитива.

```fsharp
let futureToAsync = Future.ofAsync (async { ... })
let futureToTask = Future.ofTask (task { ... })
```

1 change: 1 addition & 0 deletions docs/ru/basics/creating/creating.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Создание Future
Original file line number Diff line number Diff line change
@@ -1,24 +1,4 @@
# Запуск Future


## Запуск на текущем потоке

Future можно запустить на текущем потоке используя `Future.runBlocking`.
Переданная Future запустится, а вызывающий поток будет заблокирован
пока не получится результат.
```fsharp
let fut = future {
let! name = Future.ready "Alex"
do! Future.sleepMs 1000
return $"Hello, {name}!"
}
let phrase = fut |> Future.runBlocking
printfn $"{phrase}"
```


## Запуск используя Runtime
# Запуск Future используя Runtime

Future можно запустить на Runtime.
Runtime это планировщик для нескольких параллельно выполняющихся Future,
Expand Down
15 changes: 15 additions & 0 deletions docs/ru/basics/running/running-runtimeless.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Запуск Future без среды исполнения на текущем потоке

Future можно запустить на текущем потоке используя `Future.runBlocking`.
Переданная Future запустится, а вызывающий поток будет заблокирован
пока не получится результат.
```fsharp
let fut = future {
let! name = Future.ready "Alex"
do! Future.sleepMs 1000
return $"Hello, {name}!"
}
let phrase = fut |> Future.runBlocking
printfn $"{phrase}"
```
1 change: 1 addition & 0 deletions docs/ru/basics/running/running.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Запуск Future

0 comments on commit 88656b6

Please sign in to comment.