Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In the F# community, imperative code and mutable data aren't frowned upon <em>as long as they're not part of your public interface</em>. I.e., using mutable data is fine as long as you encapsulate it and isolate it from the rest of your code. To that end, I suggest something like:</p> <pre><code>type DeviceStatus = { RPM : int Pressure : int Temperature : int } // one of the rare scenarios in which I prefer explicit classes, // to avoid writing out all the get/set properties for each field [&lt;Sealed&gt;] type private DeviceStatusFacade = val mutable RPM : int val mutable Pressure : int val mutable Temperature : int new(s) = { RPM = s.RPM; Pressure = s.Pressure; Temperature = s.Temperature } member x.ToDeviceStatus () = { RPM = x.RPM; Pressure = x.Pressure; Temperature = x.Temperature } let UpdateStatusITimes status i = let facade = DeviceStatusFacade(status) let rec impl i = if i &gt; 0 then facade.RPM &lt;- 90 impl (i - 1) impl i facade.ToDeviceStatus () let initStatus = { RPM = 80; Pressure = 100; Temperature = 70 } let stopwatch = System.Diagnostics.Stopwatch.StartNew () let endStatus = UpdateStatusITimes initStatus 100000000 stopwatch.Stop () printfn "endStatus.RPM = %d" endStatus.RPM printfn "stopwatch.ElapsedMilliseconds = %d" stopwatch.ElapsedMilliseconds stdin.ReadLine () |&gt; ignore </code></pre> <p>This way, the public interface is unaffected &ndash; <code>UpdateStatusITimes</code> still takes and returns an intrinsically immutable <code>DeviceStatus</code> &ndash; but internally <code>UpdateStatusITimes</code> uses a mutable class to eliminate allocation overhead.</p> <p><strong>EDIT:</strong> (In response to comment) This is the style of class I would normally prefer, using a primary constructor and <code>let</code>s + properties rather than <code>val</code>s:</p> <pre><code>[&lt;Sealed&gt;] type private DeviceStatusFacade(status) = let mutable rpm = status.RPM let mutable pressure = status.Pressure let mutable temp = status.Temperature member x.RPM with get () = rpm and set n = rpm &lt;- n member x.Pressure with get () = pressure and set n = pressure &lt;- n member x.Temperature with get () = temp and set n = temp &lt;- n member x.ToDeviceStatus () = { RPM = rpm; Pressure = pressure; Temperature = temp } </code></pre> <p>But for simple facade classes where each property will be a blind getter/setter, I find this a bit tedious.</p> <p>F# 3+ allows for the following instead, but I still don't find it to be an improvement, personally (unless one dogmatically avoids fields):</p> <pre><code>[&lt;Sealed&gt;] type private DeviceStatusFacade(status) = member val RPM = status.RPM with get, set member val Pressure = status.Pressure with get, set member val Temperature = status.Temperature with get, set member x.ToDeviceStatus () = { RPM = x.RPM; Pressure = x.Pressure; Temperature = x.Temperature } </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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. 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