Re: reference initialization

From: Pierre Weis (Pierre.Weis@inria.fr)
Date: Thu May 11 2000 - 15:58:52 MET DST

  • Next message: Dave Berry: "RE: reference initialization"

    > I find that it is really not a good design choice to initialize
    > every reference in all ML-like languages (yes, I well realize
    > the difficulty in not doing so). Here is my argument.
    [...]

    > (1) ML strategy: initialize x with any value 'v' of an appropriate
    [...]

    > (2) Java Strategy: let us say we have the same scenario as before
    > but 'x' is not initialized. If I read from x before assigning a value
    [...]

    > Can you still say that the ML strategy is better than the Java
    > strategy?

    Yes, I can.

    > I thus argue that it is better using dynamic checking
    > to detect reading from uninitialized reference than simply
    > assigning a value to every reference upon its creation.
    >
    > To summarize, my bottom line question is: what is really achieved
    > by assigning a reference a (wrong) initial value? Isn't this just
    > like an ostrich solving its problem by burying its head in sand?
    >
    > Of course, another problem with the ML strategy is efficiency loss
    > (which, though, is often negligible as discussed here before)

    The ML style is better, since the default regime is to initialize
    references and in most cases, you perfectly know the correct
    initialization value at creation time.

    For the few remaining cases, where you cannot guess the initial value,
    then you must use another scheme that indeed involves dynamic testing;
    I will not consider initialization with ``any value 'v' of an
    appropriate type'' as a receivable solution, since this ``solution''
    is far too error prone (as you had already mentioned).

    Another well-known trick to initialize references is to use
    options. At creation time you define the reference as being ``ref
    None'', and later assign it to ``Some v'', when v can be computed.

    Then in your program you have to pattern match the contents of the
    reference to get its value, and raise an exception if necessary,
    getting the Java semantics.

    To elegantly handle this new scheme, you may even write a new
    dereferencing prefix operator:

    let ( !! ) r =
     match !r with
     | None -> invalid_arg "not yet initialized"
     | Some v -> v;;

    Then you just substitute !!r to !r into your program.

    One step further is to aly define a new assignment operator to hide the
    ``Some'' manipulations:

    let ( =: ) r v = r := Some v;;

    Now, for instance:

    let r = ref None;;

    r =: 1;;

    r =: 2 + !!r;;

    This way, the ``cannot initialize my reference at creation time''
    problem, is somewhat solved, but still evident in your code (and this
    is a good property, since there is a real difficulty in your source
    code, that can raise an exception when accessing the ``r'' reference).

    Conclusion: I prefer the ML style, which elegantly solves the common
    case and let you encode fairly simply the hairy cases. The efficiency
    loss problem deceives the same remark and the same solution: there is
    no loss in the most common case (in that case you know what is the
    initial value and have to compute it anyway), and in the hairy cases
    you can use the None/Some trick, an this hairy case is evident in the
    source code.

    Pierre Weis

    INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/



    This archive was generated by hypermail 2b29 : Thu May 11 2000 - 17:46:02 MET DST