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.