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

Reply via email to