diff --git a/content/docs/fibers/dynamic_bindings.mdz b/content/docs/fibers/dynamic_bindings.mdz index 737af786..708d7d7b 100644 --- a/content/docs/fibers/dynamic_bindings.mdz +++ b/content/docs/fibers/dynamic_bindings.mdz @@ -5,7 +5,7 @@ There are situations where the programmer would like to thread a parameter through multiple function calls, without passing that argument to every function explicitly. This can make code more concise, easier to read, and easier to -extend. Dynamic bindings are a mechanism that provide this in a safe and easy to +extend. Dynamic bindings are a mechanism that provides this in a safe and easy to use way. This is in contrast to lexically-scoped bindings, which are usually superior to dynamically-scoped bindings in terms of clarity, composability, and performance. However, dynamic scoping can be used to great effect for implicit @@ -54,38 +54,39 @@ print function @code`pp`. (def curr-env (fiber/getenv (fiber/current))) # The dynamic bindings we want to use -(def my-env {:pretty-format "Inside myblock: %.20P"}) +(def my-env @{:pretty-format "Inside myblock: %.20P"}) # Set up a new fiber (def f (fiber/new myblock)) (fiber/setenv f (table/setproto my-env curr-env)) # Run the code -(pp [1 2 3]) # prints "[1 2 3]" -(resume f) # prints "Inside myblock: [1 2 3]" -(pp [1 2 3]) # prints "[1 2 3]" +(pp [1 2 3]) # prints "(1 2 3)" +(resume f) # prints "Inside myblock: (1 2 3)" +(pp [1 2 3]) # prints "(1 2 3)" ``` This is verbose so the core library provides a macro, @code`with-dyns`, that makes it much clearer in the common case. @codeblock[janet]``` -(pp [1 2 3]) # prints "[1 2 3]" -# prints "Inside with-dyns: [1 2 3]" +(pp [1 2 3]) # prints "(1 2 3)" +# prints "Inside with-dyns: (1 2 3)" (with-dyns [:pretty-format "Inside with-dyns: %.20P"] (pp [1 2 3])) -(pp [1 2 3]) # prints "[1 2 3]" +(pp [1 2 3]) # prints "(1 2 3)" ``` ## When to use dynamic bindings -Dynamic bindings should be used when you want to pass around an implicit, global -context, especially when you want to automatically reset the context if an error -is raised. Since a dynamic binding is tied to the current fiber, when a fiber -exits the context is automatically unset. This is much easier and often more -efficient than manually trying to detect errors and unset context. Consider the -following example code, written once with a global var and once with a dynamic -binding. +Dynamic bindings should be used when you want to pass around an +implicit, global context, especially when you want to automatically +reset the context if an error is raised. Since a dynamic binding is +tied to the current fiber, when a fiber exits the context is +automatically unset. This is much easier and often more efficient than +manually trying to detect errors and unset the context. Consider the +following example code, written once with a global var and once with a +dynamic binding. ### Using a global var