Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>I am asking how to handle states efficiently with pure functional programming, without having another copy just to make it "referential transparency"?</p> </blockquote> <p>One can handle state efficiently in functional programming, provided that the language supports linear types. Namely, each mutable cell is given a linear type, and a typechecker sees to it that any variable of linear type is neither discarded nor duplicated at programmer's will. For instance, this is not allowed:</p> <pre><code>val x = make_reference (5) // [x] is a mutable cell val y = x val res = !x + !y // the syntax [!x] is for reading a value of a cell </code></pre> <p>It isn't allowed because [x] has a linear type, and values of linear types can't be duplicated (which is essentially what we are doing on the next line, when binding [y] to [x]). This kind of duplication is also called "aliasing" (or "sharing"), and in turn, aliasing is what makes state-manipulating programs harder to reason about (for instance, by breaking referential transparency). So, linear types restrict aliasing and that is an aid in reasoning about programs. Most of the time a program with linear types is referentially transparent, and retains some similarity to a purely functional program.</p> <p>Here is an example in ATS that uses linear types in order to deal with (mutable) state.</p> <pre><code>typedef lightbulb (b: bool) = @{is_turned_on= bool b, light_intensity= intBtw (1, 10)} fn lightbulb_make {b:bool} (state: bool b, intensity: intBtw (1, 10)) :&lt;&gt; lightbulb b = @{is_turned_on= state, light_intensity= intensity} // The [&amp;T1 &gt;&gt; T2] notation means that function expects to be given // a term of type T1, and then on exit, the type of the term will // change to T2. // In our case, the function expects a lightbulb either turned on or off, // but on exit, the lightbulb will be turned off. fn lightbulb_turn_on {b:bool} (x: &amp;lightbulb b &gt;&gt; lightbulb true) :&lt;&gt; void = x.is_turned_on := true fn lightbulb_change_intensity {b:bool} (x: &amp;lightbulb b, y: intBtw (1, 10)) :&lt;&gt; void = x.light_intensity := y implement main () = let var bulb = lightbulb_make (false, 5) val () = lightbulb_turn_on (bulb) val () = lightbulb_change_intensity (bulb, 3) in printf ("intensity is now: %d\n", @(bulb.light_intensity)) end </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload