3.7. kink/DYN¶
Provides dynamic-scope.
Using DYN.with_val and DYN.vals, you can emulate thread-local variables like the following:
:DYN.require_from('kink/')
:do_transaction <- {(:Tx_name :thunk)
DYN.with_val('Tx' Tx_name){
thunk
}
}
:current_transactions <- {()
DYN.vals('Tx')
}
stdout.print_line(current_transactions.repr) # => []
do_transaction('Top'){
stdout.print_line(current_transactions.repr) # => ["Top"]
do_transaction('Nested'){
stdout.print_line(current_transactions.repr) # => ["Top" "Nested"]
}
stdout.print_line(current_transactions.repr) # => ["Top"]
}
stdout.print_line(current_transactions.repr) # => []
`with_val` and `vals` can be implemented using shift/reset. For example:
:KONT.require_from('kink/')
:K_tag_prefix <- 'unique-str-not-used-outside-of-the-mod-'
:with_val <- {(:Tag :Val :thunk)
:K_tag = K_tag_prefix + Tag
:initial_enter = {
KONT.reset(K_tag){
:Result = thunk
# end
{ Result }
}
}
:yield_vals <- {(:kont)
:Prefix = vals(Tag)
:re_enter = {
kont(Prefix + [Val])
}
loop($re_enter)
}
:loop <- {(:enter)
:end_or_apply = enter
end_or_apply($yield_vals)
}
loop($initial_enter)
}
:vals <- {(:Tag)
:K_tag = K_tag_prefix + Tag
if(KONT.can_shift?(K_tag)
{ KONT.shift(K_tag){(:kont)
# apply
{(:yield_vals)
yield_vals($kont)
}
}
}
{ [] }
)
}
In fact, DYN mod is implemented not using KONT mod.
3.7.1. DYN.with_val(Dyn_tag Val $thunk)¶
`with_val` calls $thunk binding `Val` as a dyn val for `Dyn_tag`.
Preconditions:
• `Dyn_tag` must be a str.
• $thunk must be a fun which takes no arg.
3.7.2. DYN.vals(Dyn_tag)¶
`vals` returns a vec of dyn vals bound with `Dyn_tag`.
Precondition:
• `Dyn_tag` must be a str.