diff --git a/next/locales/zh_CN/LC_MESSAGES/language.po b/next/locales/zh_CN/LC_MESSAGES/language.po index ca963c87..c7130ad5 100644 --- a/next/locales/zh_CN/LC_MESSAGES/language.po +++ b/next/locales/zh_CN/LC_MESSAGES/language.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: MoonBit Document \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-03 11:03+0800\n" +"POT-Creation-Date: 2025-01-10 17:54+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,6 +19,350 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.16.0\n" +#: ../../language/async-experimental.md:1 +msgid "Experimental async programming support" +msgstr "实验性的异步编程支持" + +#: ../../language/async-experimental.md:3 +msgid "" +"MoonBit is providing experimental support for async programming. But the " +"design and API is still highly unstable, and may receive big breaking " +"change in the future. This page documents the current design, and we " +"highly appreciate any feedback or experiment with current design." +msgstr "" +"MoonBit 目前提供了实验性的异步编程支持。但异步相关功能的设计和 API 非常不稳定,未来可能会有大的破坏性改动。本文档页面将介绍 " +"MoonBit 异步编程目前的设计,我们欢迎及感谢任何对目前设计的反馈与使用体验分享。" + +#: ../../language/async-experimental.md:7 +msgid "Async function" +msgstr "异步函数" + +#: ../../language/async-experimental.md:8 +msgid "Async functions can be declared with the `async` keyword:" +msgstr "异步函数可以用 `async` 关键字声明:" + +#: ../../language/async-experimental.md:10 +msgid "" +"async fn my_async_function() -> Unit {\n" +" ...\n" +"}\n" +"\n" +"// anonymous/local function\n" +"test {\n" +" let async_lambda = async fn () {\n" +" ...\n" +" }\n" +" async fn local_async_function() {\n" +" ...\n" +" }\n" +"}\n" +msgstr "" +"async fn my_async_function() -> Unit {\n" +" ...\n" +"}\n" +"\n" +"// 匿名/本地函数\n" +"test {\n" +" let async_lambda = async fn () {\n" +" ...\n" +" }\n" +" async fn local_async_function() {\n" +" ...\n" +" }\n" +"}\n" + +#: ../../language/async-experimental.md:16 +msgid "Async functions must be called with the `!!` operator:" +msgstr "调用异步函数时,必须用 `!!` 操作符来标记这是一次异步函数调用:" + +#: ../../language/async-experimental.md:18 +msgid "" +"async fn some_async_function() -> Unit! {\n" +" ...\n" +"}\n" +"\n" +"async fn another_async_function() -> Unit! {\n" +" // error will be rethrowed by `!!`\n" +" some_async_function!!()\n" +"}\n" +msgstr "" +"async fn some_async_function() -> Unit! {\n" +" ...\n" +"}\n" +"\n" +"async fn another_async_function() -> Unit! {\n" +" // 异步函数中的错误也会被 `!!` 转发\n" +" some_async_function!!()\n" +"}\n" + +#: ../../language/async-experimental.md:24 +msgid "If the async function may throw error, `!!` will also rethrow the error." +msgstr "如果异步函数会抛出错误,`!!` 也会把错误一并转发。" + +#: ../../language/async-experimental.md:26 +msgid "" +"Async functions can only be called in async functions. Currently, async " +"functions cannot be called in the body of `for .. in` loops." +msgstr "异步函数只能在其他异步函数中被调用。目前,在 `for .. in` 循环中不能使用异步函数。" + +#: ../../language/async-experimental.md:28 +msgid "Async primitives for suspension" +msgstr "" + +#: ../../language/async-experimental.md:29 +msgid "" +"MoonBit provides two core primitives for `%async.suspend` and " +"`%async.run`:" +msgstr "MoonBit 提供了两个用于异步编程的原语:`%async.suspend` 和 `%async.run`:" + +#: ../../language/async-experimental.md:31 +msgid "" +"\n" +"// `run_async` spawn a new coroutine and execute an async function in it\n" +"fn run_async(f : async () -> Unit) -> Unit = \"%async.run\"\n" +"\n" +"// `suspend` will suspend the execution of the current coroutine.\n" +"// The suspension will be handled by a callback passed to `suspend`\n" +"async fn suspend[T, E : Error](\n" +" // `f` is a callback for handling suspension\n" +" f : (\n" +" // the first parameter of `f` is used to resume the execution of the " +"coroutine normally\n" +" (T) -> Unit,\n" +" // the second parameter of `f` is used to cancel the execution of the" +" current coroutine\n" +" // by throwing an error at suspension point\n" +" (E) -> Unit\n" +" ) -> Unit\n" +") -> T!E = \"%async.suspend\"\n" +msgstr "" +"\n" +"// `run_async` 会创建一个新的协程,并在其中运行一个异步函数\n" +"fn run_async(f : async () -> Unit) -> Unit = \"%async.run\"\n" +"\n" +"// `suspend` 会中断当前协程的运行。\n" +"// `suspend` 会接受一个回调函数,并让这个回调函数来操作中断的协程\n" +"async fn suspend[T, E : Error](\n" +" // `f` 是负责操作中断的协程的回调函数\n" +" f : (\n" +" // `f` 的第一个参数用于继续运行被中断的协程\n" +" (T) -> Unit,\n" +" // `f` 的第二个参数用于取消被中断的协程。\n" +" // 取消会被表示为在中断处抛出错误\n" +" (E) -> Unit\n" +" ) -> Unit\n" +") -> T!E = \"%async.suspend\"\n" + +#: ../../language/async-experimental.md:37 +msgid "" +"There two primitives are not intended for direct use by end users. " +"However, since MoonBit's standard library for async programming is still " +"under development, currently users need to bind these two primitives " +"manually to do async programming." +msgstr "这两个原语不应该让终端用户直接调用。但由于 MoonBit 的异步标准库仍在开发中,目前,用户需要手动绑定这两个原语,才能编写异步程序。" + +#: ../../language/async-experimental.md:41 +msgid "There are two ways of reading these primitives:" +msgstr "可以用两种不同的方式来理解这两个原语:" + +#: ../../language/async-experimental.md:43 +msgid "" +"the coroutine reading: `%async.run` spawn a new coroutine, and " +"`%async.suspend` suspend current coroutine. The main difference with " +"other languages here is: instead of yielding all the way to the caller of" +" `%async.run`, resumption of the coroutine is handled by the callback " +"passed to `%async.suspend`" +msgstr "" +"理解为协程:`%async.run` 创建一个新的协程,`%async.suspend` " +"中断当前协程。和其他语言的协程的主要区别是:中断协程时,不是由创建协程的地方来负责恢复执行,而是在中断的地方通过一个回调函数就地处理中断后的协程" + +#: ../../language/async-experimental.md:48 +msgid "" +"the delimited continuation reading: `%async.run` is the `reset` operator " +"in delimited continuation, and `%async.suspend` is the `shift` operator " +"in delimited continuation" +msgstr "" +"理解为 delimited continuation:`%async.run` 是 delimited continuation 中的 " +"`reset` 操作符,`%async.suspend` 是 delimited continuation `shift` 操作符" + +#: ../../language/async-experimental.md:51 +msgid "Here's an example of how these two primitives work:" +msgstr "以下是使用这两个原语的示例:" + +#: ../../language/async-experimental.md:53 +#, fuzzy +msgid "" +"type! MyError derive(Show)\n" +"\n" +"async fn async_worker(throw_error~ : Bool) -> Unit!MyError {\n" +" suspend!!(fn (resume_ok, resume_err) {\n" +" if throw_error {\n" +" resume_err(MyError)\n" +" } else {\n" +" resume_ok(())\n" +" println(\"the end of the coroutine\")\n" +" }\n" +" })\n" +"}\n" +"\n" +"// the program below should print:\n" +"//\n" +"// the worker finishes\n" +"// the end of the coroutine\n" +"// after the first coroutine finishes\n" +"// caught MyError\n" +"test {\n" +" // when supplying an anonymous function\n" +" // to a higher order function that expects async parameter,\n" +" // the `async` keyword can be omitted\n" +" run_async(fn () {\n" +" try {\n" +" async_worker!!(throw_error=false)\n" +" println(\"the worker finishes\")\n" +" } catch {\n" +" err => println(\"caught: \\{err}\")\n" +" }\n" +" })\n" +" println(\"after the first coroutine finishes\")\n" +" run_async(fn () {\n" +" try {\n" +" async_worker!!(throw_error=true)\n" +" println(\"the worker finishes\")\n" +" } catch {\n" +" err => println(\"caught: \\{err}\")\n" +" }\n" +" })\n" +"}\n" +msgstr "" +"type! MyError derive(Show)\n" +"\n" +"async fn async_worker(throw_error~ : Bool) -> Unit!MyError {\n" +" suspend!!(fn (resume_ok, resume_err) {\n" +" if throw_error {\n" +" resume_err(MyError)\n" +" } else {\n" +" resume_ok(())\n" +" println(\"协程结束运行\")\n" +" }\n" +" })\n" +"}\n" +"\n" +"// 下面这段程序应当输出:\n" +"//\n" +"// worker 函数返回了\n" +"// 协程结束运行\n" +"// 协程结束之后\n" +"// 捕获到了 MyError\n" +"test {\n" +" // 在调用一个需要异步参数的高阶函数时,\n" +" // 如果参数是一个匿名函数,可以省略 `async` 关键字\n" +" run_async(fn () {\n" +" try {\n" +" async_worker!!(throw_error=false)\n" +" println(\"worker 函数返回了\")\n" +" } catch {\n" +" err => println(\"捕获到了 \\{err}\")\n" +" }\n" +" })\n" +" println(\"协程结束之后\")\n" +" run_async(fn () {\n" +" try {\n" +" async_worker!!(throw_error=true)\n" +" println(\"worker 函数返回了\")\n" +" } catch {\n" +" err => println(\"捕获到了 \\{err}\")\n" +" }\n" +" })\n" +"}\n" + +#: ../../language/async-experimental.md:59 +msgid "" +"In `async_worker`, `suspend` will capture the rest of the current " +"coroutine as two \"continuation\" functions, and pass them to a callback." +" In the callback, calling `resume_ok` will resume execution at the point " +"of `suspend!!(...)`, all the way until the `run_async` call that start " +"this coroutine. calling `resume_err` will also resume execution of " +"current coroutine, but it will make `suspend!!(...)` throw an error " +"instead of returning normally." +msgstr "" +"在 `async_worker` 里,`suspend` 会捕获当前协程剩下的部分,并将它们表示成两个函数,传递给 `suspend` 的参数。在" +" `suspend` 的参数里,调用 `resume_ok` 会让 `suspend!!(...)` " +"正常返回,恢复协程的运行,一直运行到创建这个协程的 `run_async(...)` 为止。调用 `resume_err` " +"也会恢复协程的运行,但它会在 `suspend!!(...)` 的位置抛出一个错误。" + +#: ../../language/async-experimental.md:65 +msgid "" +"Notice that `suspend` type may throw error, even if `suspend` itself " +"never throw an error directly. This design makes coroutines cancellable " +"at every `suspend` call: just call the corresponding `resume_err` " +"callback." +msgstr "" +"`suspend` 的类型表明它可能抛出错误。但 `suspend` " +"自身不会直接产生任何错误。这一设计保证了协程在每一个的中断点都是可以取消的:调用对应的 `resume_err` 函数即可。" + +#: ../../language/async-experimental.md:68 +msgid "Integrating with JS Promise/callback based API" +msgstr "和 JS 的 Promise/回调 API 整合" + +#: ../../language/async-experimental.md:69 +msgid "" +"Since MoonBit's standard async library is still under development, so " +"there is no ready-to-use implementation for event loop and IO operations " +"yet. So the easiest way to write some async program is to use MoonBit's " +"Javascript backend, and reuse the event loop and IO operations of " +"Javascript. Here's an example of integrating MoonBit's async programming " +"support with JS's callback based API:" +msgstr "" +"MoonBit 的异步标准库仍在开发中,因此,目前没有直接可用的事件循环和输入输出原语实现。目前,要使用 MoonBit " +"编写异步程序最简单的办法是使用 JS 后端,并复用 JavaScript 的事件循环和输入输出 API。下面是一个整合 MoonBit " +"的异步编程支持和 JS 的回调 API 的例子:" + +#: ../../language/async-experimental.md:75 +msgid "" +"type JSTimer\n" +"extern \"js\" fn js_set_timeout(f : () -> Unit, duration : Int) -> " +"JSTimer =\n" +" #| (f, duration) => setTimeout(f, duration)\n" +"\n" +"async fn sleep(duration : Int) -> Unit! {\n" +" suspend!!(fn (resume_ok, _resume_err) {\n" +" let _ = js_set_timeout(fn () { resume_ok(()) }, duration)\n" +" })\n" +"}\n" +"\n" +"test {\n" +" run_async(fn () {\n" +" try {\n" +" sleep!!(500)\n" +" println(\"timer 1 tick\")\n" +" sleep!!(1000)\n" +" println(\"timer 1 tick\")\n" +" sleep!!(1500)\n" +" println(\"timer 1 tick\")\n" +" } catch { _ => panic() }\n" +" })\n" +" run_async(fn () {\n" +" try {\n" +" sleep!!(600)\n" +" println(\"timer 2 tick\")\n" +" sleep!!(600)\n" +" println(\"timer 2 tick\")\n" +" sleep!!(600)\n" +" println(\"timer 2 tick\")\n" +" } catch { _ => panic() }\n" +" })\n" +"}\n" +msgstr "" + +#: ../../language/async-experimental.md:81 +msgid "" +"Integrating with JS Promise is easy too: just pass `resume_ok` as the " +"`resolve` callback and `resume_err` as the `reject` callback to a JS " +"promise." +msgstr "" +"和 JS Promise 也非常简单:只需要把 `resume_ok` 函数用作 `Promise` 的 `resolve` 把 " +"`resume_err` 用作 Promise 的 `reject` 回调即可。" + #: ../../language/derive.md:1 msgid "Deriving traits" msgstr "派生内建特征"