cast(immutable) vs extra variable

Ali Çehreli acehreli at yahoo.com
Sun Sep 22 10:26:01 PDT 2013


On 09/19/2013 03:07 PM, Daniel Davidson wrote:

 > Here is a setup: Data is coming in - say over the wire or from a
 > database. It is very rich data with nestings of primitives, lists and
 > string keyed associative arrays, recursively - think nested json. Once
 > a data object is read in it is passed off to classes that use the data
 > in read-only fashion.

And there are two types of read-only data:

const: A promise to not mutate

immutable: A requirement that nobody mutates either.

 > So, for example, assume the root of the rich data is a Portfolio
 > instance. All members of Portfolio recursively are public since it is
 > really plain old data from one perspective and this makes using vibe
 > json serialization simple. Assume that a user of Portfolio data is an
 > Analyzer. This analyzer will need to do lots of complex operations
 > with the portfolio that it uses in readonly fashion.

Yes, that sounds like immutable(Portfolio), as the Analyzer would not be 
happy if the data could mutate.

 > It may have many
 > mutable members for intermediate calculations.
 >
 > Here is a mockup http://pastebin.com/nBLFDgv6 which is making use of
 > immutable(Portfolio) to ensure that (a) the analyzer does not modify
 > the data and (b) no other code can modify the data. To achieve this
 > there needs to be a point in time where the modifiable Portfolio is
 > done being read and made immutable. At this point it is cast to
 > immutable and henceforth only accessed that way.

I have added a couple of comments to you program:

import std.stdio;

struct Portfolio {
     double[string] data;
     // ...
}

struct HedgeRecommendation {
     string recommendation;
     this(int) {
         recommendation = "Sell, the market is rigged";
     }
}

struct Analyzer {
     // [Ali] Since you are worried about cost of copying, why not make 
this a
     //       pointer as well?
     immutable(Portfolio)* portfolio;
     this(ref immutable(Portfolio) portfolio) {
         // [Ali] Otherwise, this assignment would copy as well.
         this.portfolio = &portfolio;
     }

     HedgeRecommendation createHedge() {
         auto result = HedgeRecommendation(1);
         //...
         return result;
     }
}

// [Ali] If possible, make this function pure so that its return value can
//       automatically be casted to immutable.
Portfolio readPortfolio(string id) pure {
     // read portfolio from database
     return Portfolio([ "IBM" : 100.0, "SPY" : 300.0 ]);
}

HedgeRecommendation getHedgeRecommendation(string portfolioId) {
     // [Ali] No explicit cast needed because of that 'pure'.
     immutable(Portfolio) portfolio = readPortfolio(portfolioId);
     auto analyzer = Analyzer(portfolio);
     return analyzer.createHedge();
}

void main() {
     writeln(getHedgeRecommendation("1234"));
}

 > Given this setup - what do you see as the trade-offs?
 >
 > What can not be done or will be challenging in face of refactor?
 >
 > What are some better alternatives/recommendations?
 >
 > I am a fan of D but my struggles with const/immutable transitivity
 > feel endless and are wearing on me. I feel like having an ability to
 > say something will not change and not using that ability is like being
 > teased.

You are not alone. I tried to answer some of these questions in my DConf 
2013 talk. I think I have only scratched the surface:

   http://dconf.org/talks/cehreli.html

Ali



More information about the Digitalmars-d-learn mailing list