Skip to content
Anssi Halmeaho edited this page Aug 2, 2021 · 3 revisions

stdvar

Provides reference type for accessing values. It's effectively implementing variable so that referenced value can be changed.

Changes are made safely so that concurrent fiber access is protected.

var-ref (opaque type)

Value reference type.

Procedures

new

Creates new var-ref. Initial value is given as argument. Return value is var-ref.

call(stdvar.new <value>) -> <opaque:var-ref>

value

Reads referenced value from var-ref.

call(stdvar.value <opaque:var-ref>) -> <value>

change

Changes referenced value by applying given function to previous value and assigns result value as new referenced value.

Returns value to which referenced value was changed.

Function given as argument is following kind:

func(previous-value) -> new-value
call(stdvar.change <opaque:var-ref> <func>) -> list(<changed-ok:bool> <error-string> <value:new>)

change-v2

Similar to change but provides possibility to give additional argument to updating function (optional 3rd argument). If additional argument is not given then updating function receives only one argument (previous value of var-ref).

Also updating function returns list of two items as return value, containing:

  1. new value for var-ref
  2. returned value from change-v2 as 4th item in return list

Updating function given as argument is following kind:

func(previous-value <OPTIONAL: additional argument value>) -> list(<new-value> <extra-value>)

change-v2 is following kind of procedure:

call(stdvar.change-v2 <opaque:var-ref> <func> <OPTIONAL: additional-arg>) -> list(<changed-ok:bool> <error-string> <value:new> <value:extra>)

1st item in return list is true if operation succeeded, false if failed.

2nd item in return list is string containing error text if operation failed.

3rd item in return list is new value for var-ref.

4th item in return list is extra value returned from updating list.

Hint. See usage examples in test cases /tst/stdvar_test.fnl

set

Sets referenced value to value given as argument.

call(stdvar.set <opaque:var-ref> <value>) -> true

Examples

Example: Setting referenced value

ns main

main = proc()
	import stdvar

	var = call(stdvar.new 'initial value')
	_ = print('first value is -> ' call(stdvar.value var))
	_ = call(stdvar.set var 'updated value')
	sprintf('then value is -> %s' call(stdvar.value var))
end

endns

output is:

first value is -> initial value
'then value is -> updated value'

Example: Periodic counter increment

One fiber periodically incrementing referenced value and other fiber periodically reading the referenced value.

ns main

import stdvar
import stdtime

counter = proc(var)
	call(proc()
		while(call(proc()
			_ = call(stdtime.sleep 2)
			_ = call(stdvar.change var func(x) plus(x 1) end)
			true
		end) 'none')
	end)
end

reader = proc(var)
	call(proc()
		while(call(proc()
			_ = call(stdtime.sleep 1)
			_ = print('read -> ' call(stdvar.value var))
			true
		end) 'none')
	end)
end

main = proc()
	var = call(stdvar.new 0)
	_ = spawn(call(counter var) call(reader var))
	
	import stdio
 	call(stdio.readinput)
end

endns

output is:

read -> 0
read -> 0
read -> 1
read -> 2
read -> 2
read -> 3
read -> 3
read -> 4
read -> 4
read -> 5

''