It works, it's not hard to figure out, but, but, but......




  • I no doubt need to get a life, but this C# implementation of lazy initialization bothers me:

     public Foo getFoo()
     {
         if (_foo != null)
            return _foo;
        else
            return _foo = new Foo();
    }
    

    Maybe it's the meaningless "else". Maybe it's the gratuitous use of the value of an assignment expression (sometimes you need it, but you ought to be judicious about it.) Or maybe it's the stunning opacity and inelegance when compared to

     public Foo getFoo()
     {
         if (_foo == null)
            _foo = new Foo();
    
    return _foo;
    

    }



  • I no doubt need to get a life, but this C# implementation of lazy initialization bothers me:

     public Foo getFoo()
     {
         if (_foo == null)
            _foo = new Foo();
    
    return _foo;
    

    }

    Maybe it's the meaningless "if". Maybe it's the gratuitous use of the value of an assignment expression (sometimes you need it, but you ought to be judicious about it.) Or maybe it's the stunning opacity and inelegance when compared to

     public Foo getFoo()
     {
    return _foo ?? _foo = new Foo(); }


  • Also:

    private Lazy<Foo> daFoo = new Lazy<Foo>(() => new Foo());

    public Foo getFoo()

    {

      return daFoo.Value;

    }



  • @Sutherlands said:

    Maybe it's the meaningless "if". Maybe it's the gratuitous use of the value of an assignment expression (sometimes you need it, but you ought to be judicious about it.) Or maybe it's the stunning opacity and inelegance when compared to

     public Foo getFoo()
     {
    return _foo ?? _foo = new Foo(); }

    Ouch!

    For the record, the "if" in the original is certainly not meaningless, and your-counter example has as many assignment statements as the original.

    I'm a big fan of the ternary operator, but I'm not convinced that in this case it adds clarity.



  • @Sutherlands said:

    I no doubt need to get a life, but this C# implementation of lazy initialization bothers me:

     public Foo getFoo()
     {
         if (_foo == null)
            _foo = new Foo();
    
    return _foo;
    

    }

    Maybe it's the meaningless "if". Maybe it's the gratuitous use of the value of an assignment expression (sometimes you need it, but you ought to be judicious about it.) Or maybe it's the stunning opacity and inelegance when compared to

     public Foo getFoo()
     {
    return _foo ?? _foo = new Foo(); }

    What does ?? do in C#? Check if the thing on the left of it is null?



  • @rstinejr said:

    I'm a big fan of the ternary operator, but I'm not convinced that in this case it adds clarity.

    It's not the ternary operator.@Someone You Know said:

    What does ?? do in C#? Check if the thing on the left of it is null?

    Basically.  Evaluates the left side.  If it's not null, return it.  Otherwise, evaluate and return the right side.  (Can be chained)


  • TRWTF is that it's a method and not a property.



  • And that the function is camelCase.



  • @Sutherlands said:

    And that the function is camelCase.

    Please I really don't care about how you case things, as long as it is consistant throughout the code.

    Oh you were just showing your dickweedery.. never mind, carry on.



  • @Someone You Know said:

    What does ?? do in C#?
     

    It makes legitimate sentences look like a combination of line noise and unsupported unicode characters.



  • @Sutherlands said:

    Also:

    private Lazy<Foo> daFoo = new Lazy<Foo>(() => new Foo());

    public Foo getFoo()

    {

      return daFoo.Value;

    }

    :O I had no idea this type existed!



  • @rstinejr said:

    Or maybe it's the stunning opacity and inelegance when compared to

     public Foo getFoo()
     {
         if (_foo == null)
            _foo = new Foo();
    
    return _foo;
    

    }

     

     If you want to talk elegance, I much prefer the ruby way of doing this which makes your elegance look clunky:

    def getFoo
       @foo ||= Foo.new
    end
    


  • @KattMan said:

    @Sutherlands said:

    And that the function is camelCase.

    Please I really don't care about how you case things, as long as it is consistant throughout the code.

    Oh you were just showing your dickweedery.. never mind, carry on.

     

    I have yet to come accross a .NET libary that doesn't use UpperCamelCase for method names (atleast the public ones). One needs to maintain consistancy with ones ecosystem aswell.

     



  • @notromda said:

     If you want to talk elegance, I much prefer the ruby way of doing this which makes your elegance look clunky:

    def getFoo
       @foo ||= Foo.new
    end
    

    I tried to read some Ruby code once, but I had to stop when the bleeding it caused in my eyes became life threatening. Your example of elegance notwithstanding, that language has some ugly syntax.



  • @rstinejr said:

    @notromda said:

     If you want to talk elegance, I much prefer the ruby way of doing this which makes your elegance look clunky:

    def getFoo
       @foo ||= Foo.new
    end
    

    I tried to read some Ruby code once, but I had to stop when the bleeding it caused in my eyes became life threatening. Your example of elegance notwithstanding, that language has some ugly syntax.

    I'll admit a prejudice against non-C syntax, but you can learn to live with it if you work with it for awhile.

    What I dislike about Ruby is the fact that it's a dynamic language with little type coercion. Want to concatenate an integer to a string? Call to_s. Want to get the string representation of an object? Define to_s in its class, then call it. Even Java will do this shit for you automatically, but Ruby makes you do this by hand.

    Oh, and optional parens on method calls bothers me, but at least that's an easy one to fix with coding standards.



  • Of them all I prefer to use Lazy<T>....the reason is simple...pick any of the other patterns, then try to find all usages of that pattern (independent of formatting) throughout a large system. Discoverability is a major help to maintainability and understanding.



  • @notromda said:

     If you want to talk elegance, I much prefer the ruby way of doing this which makes your elegance look clunky:

    def getFoo
       @foo ||= Foo.new
    end

     

    Well, at least it isn't Python.

     



  • I still can't figure out lazy initialization anyway. If you have an object with a 'foo' in it, why not create that 'foo' when you create the object?  What do you gain by only creating the 'foo' when something outside wants to access it?  If 'foo' is not always used in an object, why is it a member in the first place (as opposed to having a subclass)?

    I guess I don't see what problem lazy initialization is intended to solve.

    (Note: I make a distinction between waiting to perform an expensive initialization of data for an object and creation of the object itself. Is this all that "lazy initialization" is trying to accomplish?)



  • @pkmnfrk said:

    @Sutherlands said:
    private Lazy<Foo> daFoo = new Lazy<Foo>(() => new Foo());
    public Foo getFoo() {
    return daFoo.Value;
    }

    :O I had no idea this type existed!

    It was new in .Net 4.



  • @too_many_usernames said:

    I still can't figure out lazy initialization anyway. If you have an object with a 'foo' in it, why not create that 'foo' when you create the object?  What do you gain by only creating the 'foo' when something outside wants to access it?  If 'foo' is not always used in an object, why is it a member in the first place (as opposed to having a subclass)?

    I guess I don't see what problem lazy initialization is intended to solve.

    (Note: I make a distinction between waiting to perform an expensive initialization of data for an object and creation of the object itself. Is this all that "lazy initialization" is trying to accomplish?)

    In the case of singletons, delaying expensive initialisation is the point.

    However, Lazy<T> was probably added to .Net as part of the move towards a more functional style of programming. Lazy initialisation is commonly used in FP to create infinite data structures which are realised on demand.



  • @too_many_usernames said:

    I still can't figure out lazy initialization anyway. If you have an object with a 'foo' in it, why not create that 'foo' when you create the object?  What do you gain by only creating the 'foo' when something outside wants to access it?  If 'foo' is not always used in an object, why is it a member in the first place (as opposed to having a subclass)?

    I guess I don't see what problem lazy initialization is intended to solve.

    (Note: I make a distinction between waiting to perform an expensive initialization of data for an object and creation of the object itself. Is this all that "lazy initialization" is trying to accomplish?)

    In most cases, it's waiting to perform an expensive initialization of data.

    In a separate example, I used it to delay the creation of something until after the constructor ran because if it errors inside the constructor I would get "there was an error creating the type" whereas if it was after I would get the actual error.



  • @Sutherlands said:

    In a separate example, I used it to delay the creation of something until after the constructor ran because if it errors inside the constructor I would get "there was an error creating the type" whereas if it was after I would get the actual error.

    There is the InnerException property which will tell you the real error, but yeah, that's annoying!



  • @ekolis said:

    @Sutherlands said:
    In a separate example, I used it to delay the creation of something until after the constructor ran because if it errors inside the constructor I would get "there was an error creating the type" whereas if it was after I would get the actual error.
    There is the InnerException property which will tell you the real error, but yeah, that's annoying!

    In this case it didn't.



  • @too_many_usernames said:

    If 'foo' is not always used in an object, why is it a member in the first place (as opposed to having a subclass)?

    Um, not every member is accessed in every use of a class. And I can't even imagine how you think subclassing is going to help out here.

    @too_many_usernames said:

    (Note: I make a distinction between waiting to perform an expensive initialization of data for an object and creation of the object itself. Is this all that "lazy initialization" is trying to accomplish?)

    It's both, really. Maybe the constructor is doing something like opening a database connection. But also, why construct an object if it's not going to be used? I mostly use lazy initialization for things with an expensive setup time, like web service clients; I don't want to instantiate a client (and possibly open a socket or read in some configuration from a file) if I'm never going to use it. This is especially true with factory-type objects which might handle instantiation and caching of dozens of similar objects.



  • @morbiuswilters said:

    @too_many_usernames said:
    If 'foo' is not always used in an object, why is it a member in the first place (as opposed to having a subclass)?

    Um, not every member is accessed in every use of a class. And I can't even imagine how you think subclassing is going to help out here.

    A member field is supposed to represent state of thing you are modeling. Every instance should have a value for that state. If you have instances where this is not true, then your model is poor. In many cases moving the "it sometimes has" parts of the states to appropriate derived classes (such that every instance of those classes always has that state) is appropriate. In other cases, re-factoring so that the state in question is extrnal to the instance is appropriate.

    Now "used" may have a different connotation, in that the value of this state never influences the behaviour of the instance during it's life time. Here, hard initialization is not necessarily a good idea, and using Lazy initialization to only incur the overhead (as well as provide clearer semantics) can be a very good thing.



  • Helpful comments all around..

    I've realized that I am so used to doing explicit loading of "time consuming" data that I've never even attempted to hide such functionality in an accessor function. While I can see the benefit of having that implicit behavior, I think there are some pitfalls. If I have to explicitly load data, I'm much more likely to dispose of the data properly when I'm done with it.

    (And yes, while I know garbage collection exists, I find it amusing that "garbage collection" taken literally just results in a large pile of garbage.)



  • @TheCPUWizard said:

    Every instance should have a value for that state. If you have instances where this is not true, then your model is poor. In many cases moving the "it sometimes has" parts of the states to appropriate derived classes (such that every instance of those classes always has that state) is appropriate. In other cases, re-factoring so that the state in question is extrnal to the instance is appropriate.

    Now "used" may have a different connotation, in that the value of this state never influences the behaviour of the instance during it's life time. Here, hard initialization is not necessarily a good idea, and using Lazy initialization to only incur the overhead (as well as provide clearer semantics) can be a very good thing.

    You just contradicted yourself between those two paragraphs. Either every member should be used to represent the state or lazy initialization is okay.



  • @morbiuswilters said:

    Either every member should be used to represent the state or lazy initialization is okay.

    What if it's Schrodinger's object? Seriously, though, that's how I took TheCPUWizard's statement. From the outside of the object, you can't know if it's initialized or not except by asking for it (ignoring reflection or other pedantic dickweedery), at which point it will definitely be initialized.



  • @morbiuswilters said:

    @TheCPUWizard said:

    Every instance should have a value for that state. If you have instances where this is not true, then your model is poor. In many cases moving the "it sometimes has" parts of the states to appropriate derived classes (such that every instance of those classes always has that state) is appropriate. In other cases, re-factoring so that the state in question is extrnal to the instance is appropriate.

    Now "used" may have a different connotation, in that the value of this state never influences the behaviour of the instance during it's life time. Here, hard initialization is not necessarily a good idea, and using Lazy initialization to only incur the overhead (as well as provide clearer semantics) can be a very good thing.

    You just contradicted yourself between those two paragraphs. Either every member should be used to represent the state or lazy initialization is okay.

    No I did not. The first part is "Does the Object Have the State?", the second part is "Does knowing the value of the state have an operational impact?"

    For example EVERY living person has an AGE. There are no instances of a person WITHOUT an age. However there are many things that are independant of the Age.

    Only Some people have perscription glasses. Those that do, have specific information on the perscription. But not all people do, so having such a field on a general purpose person object violates my first contention [note: this may be denormalized for certain cases like an optomitrist patienet]

     See the distinction?


  • Discourse touched me in a no-no place

    Schrodinger's object

    Totally off-topic, but...

    @boomzilla said:

    What if it's Schrodinger's object?

    Examples please. In any language. In less than 150 LOC. (Including any harness for demonstration.)



  • @PJH said:

    Totally off-topic, but...

    @boomzilla said:

    What if it's Schrodinger's object?

    Examples please. In any language. In less than 150 LOC. (Including any harness for demonstration.)

    Huh? Any bog standard lazily initialized object is what I meant. Suppose that you're a function, and one of the parameters passed to you is an object, foo, of class Foo. It has a property, bar. You know that it's lazily initialized. So you wonder, is it initialized or not? So if you observe bar, it will always be initialized. But before that, you can't know if it really was initialized (short of pedantic dickweed outs like reflection or timing it or whatver). And so you don't know if it was initialized by you when you looked at bar, or before.

    Not a perfect analogy, of course, because we didn't get the chance to kill any cats. But good enough, I think, to give you a resolution to believing that all of an objects states should have a value and that some values are best initialized lazily.



  • @boomzilla said:

    @PJH said:
    Totally off-topic, but...

    @boomzilla said:

    What if it's Schrodinger's object?

    Examples please. In any language. In less than 150 LOC. (Including any harness for demonstration.)

    Huh? Any bog standard lazily initialized object is what I meant. Suppose that you're a function, and one of the parameters passed to you is an object, foo, of class Foo. It has a property, bar. You know that it's lazily initialized. So you wonder, is it initialized or not? So if you observe bar, it will always be initialized. But before that, you can't know if it really was initialized (short of pedantic dickweed outs like reflection or timing it or whatver). And so you don't know if it was initialized by you when you looked at bar, or before.

    Not a perfect analogy, of course, because we didn't get the chance to kill any cats. But good enough, I think, to give you a resolution to believing that all of an objects states should have a value and that some values are best initialized lazily.

    So you think that pointing out that Lazy<T> contains a member "HasValue" which tells you if it has been initiaized...is....pedantic??? <just asking>



  • @TheCPUWizard said:

    So you think that pointing out that Lazy<T> contains a member "HasValue" which tells you if it has been initiaized...is....pedantic??? <just asking>

    Yes. You can't really know if it was initialized by looking at this second hand evidence. Or is being initialized, race conditions being what they are. At least that's my pedantic dickweed counter to your pedantic dickweedery.



  • @boomzilla said:

    @TheCPUWizard said:
    So you think that pointing out that Lazy<T> contains a member "HasValue" which tells you if it has been initiaized...is....pedantic??? <just asking>

    Yes. You can't really know if it was initialized by looking at this second hand evidence. Or is being initialized, race conditions being what they are. At least that's my pedantic dickweed counter to your pedantic dickweedery.

    Um...HasValue is not second hand, it is what is used to determine if initialization is required on a call to Value....the following code will NEVER (100%) trigger an evaluation..

    Lazy<int> y = ()=>3+4;

    if (y.HasValue)
      x  = y.Value;



  • @TheCPUWizard said:

    Um...HasValue is not second hand, it is what is used to determine if initialization is required on a call to Value.

    Yes, it is obviously second hand information, since it's just a flag that gets set. It's like the dead cat. It is indirect evidence of something that is set after the evidence comes into being.

    @TheCPUWizard said:

    ..the following code will NEVER (100%) trigger an evaluation..

    Lazy<int> y = ()=>3+4;

    if (y.HasValue)
      x  = y.Value;

    Yes, but so what? That doesn't affect what I said at all.



  • @TheCPUWizard said:

    @morbiuswilters said:
    @TheCPUWizard said:

    Every instance should have a value for that state. If you have instances where this is not true, then your model is poor. In many cases moving the "it sometimes has" parts of the states to appropriate derived classes (such that every instance of those classes always has that state) is appropriate. In other cases, re-factoring so that the state in question is extrnal to the instance is appropriate.

    Now "used" may have a different connotation, in that the value of this state never influences the behaviour of the instance during it's life time. Here, hard initialization is not necessarily a good idea, and using Lazy initialization to only incur the overhead (as well as provide clearer semantics) can be a very good thing.

    You just contradicted yourself between those two paragraphs. Either every member should be used to represent the state or lazy initialization is okay.

    No I did not. The first part is "Does the Object Have the State?", the second part is "Does knowing the value of the state have an operational impact?"

    For example EVERY living person has an AGE. There are no instances of a person WITHOUT an age. However there are many things that are independant of the Age.

    Only Some people have perscription glasses. Those that do, have specific information on the perscription. But not all people do, so having such a field on a general purpose person object violates my first contention [note: this may be denormalized for certain cases like an optomitrist patienet]

     See the distinction?

    So your comment was worthless, then. You replied as if you were contradicting me, because apparently you can't pass up an opportunity to tediously lecture people even when you're simply agreeing with them. What an enjoyable person you must be to work with.. do you find that most people who interact with you spend the majority of their time nodding vigorously and saying "Yep. Uh huh. Got it." over and over, almost as if they're trying to get rid of you?



  • @morbiuswilters said:

    You replied as if you were contradicting me, because apparently you can't pass up an opportunity to tediously lecture people even when you're simply agreeing with them. What an enjoyable person you must be to work with.. do you find that most people who interact with you spend the majority of their time nodding vigorously and saying "Yep. Uh huh. Got it." over and over, almost as if they're trying to get rid of you?

    (*While nodding) Yep, huh, huh, huh, got it.



  • @morbiuswilters said:

    So your comment was worthless, then. You replied as if you were contradicting me, because apparently you can't pass up an opportunity to tediously lecture people even when you're simply agreeing with them. What an enjoyable person you must be to work with.. do you find that most people who interact with you spend the majority of their time nodding vigorously and saying "Yep. Uh huh. Got it." over and over, almost as if they're trying to get rid of you?

    1) I was contradicting your statement that "You just contradicted yourself between those two paragraphs" (that is, I contend that I did not]. This is totally independent of if I agree or disagree with your other statement.

    2) Mode of the people I interact with on a profressional level, actualy pay me significant sums of money for exactly the type of material I post here. The is much more of a common reaction of "I never realized that detail, and why it matters". Obviously I dont know what they are thinking, but "they're trying to get rid of you" seems in consistent with the fact that they re-contract with me on a regular basis (why sign a new contract after the previous has been long expired, if you want to get rid of someone).....



  • @TheCPUWizard said:

    1) I was contradicting your statement that "You just contradicted yourself between those two paragraphs" (that is, I contend that I did not]. This is totally independent of if I agree or disagree with your other statement.

    I'm talking about your original contradiction of my statement. Either you were contradicting me, or you were simply lecturing in agreement while sounding like you were contradicting me, which is an annoying habit.

    @TheCPUWizard said:

    2) Mode of the people I interact with on a profressional level, actualy pay me significant sums of money for exactly the type of material I post here. The is much more of a common reaction of "I never realized that detail, and why it matters". Obviously I dont know what they are thinking, but "they're trying to get rid of you" seems in consistent with the fact that they re-contract with me on a regular basis (why sign a new contract after the previous has been long expired, if you want to get rid of someone).....

    Well, people frequently do stupid things, so it's possible they're just pissing money away.. who knows? It wouldn't be the dumbest thing I've heard of, even on this very site. And in a world where Facebook is worth $100 billion, there's no shortage of idiots with more money than sense.

    Look, it's great to post useful information, or whatever, but when you respond to people in a manner that makes it seem like you are correcting them--when in fact you're just verbosely agreeing with them--that's annoying.



  • @morbiuswilters said:

    @TheCPUWizard said:
    1) I was contradicting your statement that "You just contradicted yourself between those two paragraphs" (that is, I contend that I did not]. This is totally independent of if I agree or disagree with your other statement.

    I'm talking about your original contradiction of my statement. Either you were contradicting me, or you were simply lecturing in agreement while sounding like you were contradicting me, which is an annoying habit.

    @TheCPUWizard said:

    2) Mode of the people I interact with on a profressional level, actualy pay me significant sums of money for exactly the type of material I post here. The is much more of a common reaction of "I never realized that detail, and why it matters". Obviously I dont know what they are thinking, but "they're trying to get rid of you" seems in consistent with the fact that they re-contract with me on a regular basis (why sign a new contract after the previous has been long expired, if you want to get rid of someone).....

    Well, people frequently do stupid things, so it's possible they're just pissing money away.. who knows? It wouldn't be the dumbest thing I've heard of, even on this very site. And in a world where Facebook is worth $100 billion, there's no shortage of idiots with more money than sense.

    Look, it's great to post useful information, or whatever, but when you respond to people in a manner that makes it seem like you are correcting them--when in fact you're just verbosely agreeing with them--that's annoying.

    1) You stated: "Um, not every member is accessed in every use of a class. And I can't even imagine how you think subclassing is going to help out here.". I count initialization as an access, so for .NET every member of a class is in fact accessed for every instance. Subclassing so that this access only happens on cases where it matters would change that situation by reducing the number of members (all of which will be accessed by definition) in the base class. Now "help out" is subjective but my point was that if the member does not have meaning then [IMPO] it does not belong in the class, and is better in a sub-class where it does have meaning; yet this is distinct from the meaning having any impact on the operations that happen to be performed on that insance. I attempted to illustrate this with my previous examples.

    2) Your second point in the last post, has no bearing on on the previous part of the dicsussion. There was no mention of "why" they would or would not be "thinking of getting rid of me". My response was purely an argument against that being a likely thought. You could be 100% right that they are "idiots" for not having the thought and that what I provide is worthless (I obviously do not hold this view). but that does not have anything to do with your assertion that "spend the majority of their time nodding vigorously and saying "Yep. Uh huh. Got it." over and over, almost as if they're trying to get rid of you".

    So, just to be clear, I am not agreeing with any of your points in these matters.



  • @TheCPUWizard said:

    I count initialization as an access, so for .NET every member of a class is in fact accessed for every instance.

    What? That would violate the entire point of lazy loading. I'm not sure how any of this is relevant to the point I was making, either.

    @TheCPUWizard said:

    2) Your second point in the last post, has no bearing on on the previous part of the dicsussion. There was no mention of "why" they would or would not be "thinking of getting rid of me". My response was purely an argument against that being a likely thought. You could be 100% right that they are "idiots" for not having the thought and that what I provide is worthless (I obviously do not hold this view). but that does not have anything to do with your assertion that "spend the majority of their time nodding vigorously and saying "Yep. Uh huh. Got it." over and over, almost as if they're trying to get rid of you".

    I really don't care. My jab was meant to point out your annoying habit. And you've responded by giving an annoying, long-winded explanation that shows you missed the point.



  • @morbiuswilters said:

    @TheCPUWizard said:
    I count initialization as an access, so for .NET every member of a class is in fact accessed for every instance.

    What? That would violate the entire point of lazy loading. I'm not sure how any of this is relevant to the point I was making, either.

    Not at all:

    1) Access by Default Initialization [zeroing the memory location] - ALWAYS happens, regardless of the following...
    2) Access by Explicit Initialization [either in the constructor or directly on the field]. This in fact may be expensive
    3) Access to initialize with a light weight object reference which will later provide the default value [aka LAZY<T>] - (This is the entire point of Lazy Loading)
    4) Access to initialize with a delegate (typeically does not provide the one-time implementation that LAZY<T> does, instead invoking the delegate each time



    @morbiuswilters said:

    @TheCPUWizard said:
    2) Your second point in the last post, has no bearing on on the previous part of the dicsussion. There was no mention of "why" they would or would not be "thinking of getting rid of me". My response was purely an argument against that being a likely thought. You could be 100% right that they are "idiots" for not having the thought and that what I provide is worthless (I obviously do not hold this view). but that does not have anything to do with your assertion that "spend the majority of their time nodding vigorously and saying "Yep. Uh huh. Got it." over and over, almost as if they're trying to get rid of you".

    I really don't care. My jab was meant to point out your annoying habit. And you've responded by giving an annoying, long-winded explanation that shows you missed the point.

    Or perhaps I got your point a long time ago and either a) Dont Care, or b) Am deliberately baiting you, or c)..... In any case there you go making assumptions AGAIN...



  • @TheCPUWizard said:

    @morbiuswilters said:

    @TheCPUWizard said:
    I count initialization as an access, so for .NET every member of a class is in fact accessed for every instance.

    What? That would violate the entire point of lazy loading. I'm not sure how any of this is relevant to the point I was making, either.

    Not at all:

    1) Access by Default Initialization [zeroing the memory location] - ALWAYS happens, regardless of the following...
    2) Access by Explicit Initialization [either in the constructor or directly on the field]. This in fact may be expensive
    3) Access to initialize with a light weight object reference which will later provide the default value [aka LAZY<T>] - (This is the entire point of Lazy Loading)
    4) Access to initialize with a delegate (typeically does not provide the one-time implementation that LAZY<T> does, instead invoking the delegate each time



    You're assuming that the only members on a class are fields. However, there are these other magical members called "properties". Not all properties are backed by a field. Some are backed by other object's properties, by a database, by a random number generator, by nothing at all, etc. These properties are inherently lazy, producing results on the fly. Some properties use a field for caching, so that they don't have to recalculate the value every time, but they still need to do it the first time. If the property is not accessed, then the value is not calculated, and the backing field is never non-null.



  • @pkmnfrk said:

    You're assuming that the only members on a class are fields. However, there are these other magical members called "properties". Not all properties are backed by a field. Some are backed by other object's properties, by a database, by a random number generator, by nothing at all, etc. These properties are inherently lazy, producing results on the fly. Some properties use a field for caching, so that they don't have to recalculate the value every time, but they still need to do it the first time. If the property is not accessed, then the value is not calculated, and the backing field is never non-null.

    You are correct, I was refering to Fields (including the hidden fields used by "Automatic" properties) and not members in general...

    However, regarding "Some properties use a field for caching, so that they don't have to recalculate the value every time, but they still need to do it the first time. If the property is not accessed, then the value is not calculated, and the backing field is never non-null.", while 100% correct, the initial "Access" to set it to null (as part of a block "Zero Memory" operation) which was "1" in my list still occurs.



  • @TheCPUWizard said:

    Not at all:

    1) Access by Default Initialization [zeroing the memory location] - ALWAYS happens, regardless of the following...
    2) Access by Explicit Initialization [either in the constructor or directly on the field]. This in fact may be expensive
    3) Access to initialize with a light weight object reference which will later provide the default value [aka LAZY<T>] - (This is the entire point of Lazy Loading)
    4) Access to initialize with a delegate (typeically does not provide the one-time implementation that LAZY<T> does, instead invoking the delegate each time

    Oh boy, let's talk about the internals of the runtime, even though you know that wasn't the fucking point. When somebody says "Was this field accessed?" they don't mean "Was the memory zeroed-out on initialization?" and you goddamn well know it. Stop this "I'm going to act like I don't understand basic English just to show how smart I am!" bullshit. You know your point is an irrelevant tangent which has nothing to do with what I was talking about.

    @TheCPUWizard said:

    Or perhaps I got your point a long time ago and either a) Dont Care, or b) Am deliberately baiting you, or c)..... In any case there you go making assumptions AGAIN...

    No, I knew you were talking about default initialization from the beginning (well, suspected it) but was drawing you out so you could demonstrate your retardity for everyone else.

    @Rule #1 of Catching an Idiot said:

    Give him more than enough rope to hang himself. Don't strike before he's revealed his hand or else you give him the ability to pretend he meant something else.



  • So knowing that value will be zeroed when members of of a class or struct (vs other languages where they may contain random data) is an " internals of the runtime"?? Not in my book. It is a key feature why they do not have to be explicitly set (and that seting to zero explicitly causes additional overhead).

    I also left out one reason for access of eference type members...and that is every time the GC runs to to a scan for what objects are reachable..This becomes a (small but non zero) runtime performance issue (as does the fact that the additional fields decrease cache hit density)

    These are [IMPO] key elements of software DESIGN....sure a "code monkey" may be able to ignore them and get away with it...but  I would not higher someone who will have design responsibilities withou this knowledge, and my clients (when I perform screening for them) seem to agree almos universally.



  • @TheCPUWizard said:

    So knowing that value will be zeroed when members of of a class or struct (vs other languages where they may contain random data) is an " internals of the runtime"?? Not in my book. It is a key feature why they do not have to be explicitly set (and that seting to zero explicitly causes additional overhead).

    I also left out one reason for access of eference type members...and that is every time the GC runs to to a scan for what objects are reachable..This becomes a (small but non zero) runtime performance issue (as does the fact that the additional fields decrease cache hit density)

    These are [IMPO] key elements of software DESIGN....sure a "code monkey" may be able to ignore them and get away with it...but  I would not higher someone who will have design responsibilities withou this knowledge, and my clients (when I perform screening for them) seem to agree almos universally.

    Are you saying that you'll only hire people that will spend 3 days looking at CIL to (maybe) eek out an extra 1 or 2 CPU cycles? If so, then you're either full of shit or TRWTF. I've met/worked with some very bright minds who would put Jon Skeet to shame, and they never would consider the shit you just mentioned.



  • @TheCPUWizard said:

    So knowing that value will be zeroed when members of of a class or struct (vs other languages where they may contain random data) is an " internals of the runtime"?? Not in my book. It is a key feature why they do not have to be explicitly set (and that seting to zero explicitly causes additional overhead).

    I also left out one reason for access of eference type members...and that is every time the GC runs to to a scan for what objects are reachable..This becomes a (small but non zero) runtime performance issue (as does the fact that the additional fields decrease cache hit density)

    These are [IMPO] key elements of software DESIGN....sure a "code monkey" may be able to ignore them and get away with it...but  I would not higher someone who will have design responsibilities withou this knowledge, and my clients (when I perform screening for them) seem to agree almos universally.

    I didn't know that nobody should know about these things, I said that when somebody is talking about accessing a variable, they aren't referring to automatic initialization done by the system or GC. Let's put your definition into practice:

    Competent Developer: Hmm.. should be safe to remove this variable, it isn't accessed at all.

    You: Sure it is, the runtime will automatically initialize it to zero. Also, the garbage collector will access it, derp!

    CD: We're going to remove your commit access now.

    You: But aren't you impressed that I can throw irrelevant details at you in a desperate attempt to bolster my missing self-worth?

    CD: No, nobody is. I'm just sad for you.. sadder than when I was 7 and my puppy died in my arms.



  • @C-Octothorpe said:

    @TheCPUWizard said:

    So knowing that value will be zeroed when members of of a class or struct (vs other languages where they may contain random data) is an " internals of the runtime"?? Not in my book. It is a key feature why they do not have to be explicitly set (and that seting to zero explicitly causes additional overhead).

    I also left out one reason for access of eference type members...and that is every time the GC runs to to a scan for what objects are reachable..This becomes a (small but non zero) runtime performance issue (as does the fact that the additional fields decrease cache hit density)

    These are [IMPO] key elements of software DESIGN....sure a "code monkey" may be able to ignore them and get away with it...but  I would not higher someone who will have design responsibilities withou this knowledge, and my clients (when I perform screening for them) seem to agree almos universally.

    Are you saying that you'll only hire people that will spend 3 days looking at CIL to (maybe) eek out an extra 1 or 2 CPU cycles? If so, then you're either full of shit or TRWTF. I've met/worked with some very bright minds who would put Jon Skeet to shame, and they never would consider the shit you just mentioned.

    I am saying that I will only hire someone with DESIGN responsibilities who was aware of potential issue of this nature, knew when to consider them, and could address them. It would be foolish (and I never said) that I woud have someone spend time ["3 days looking at CIL"] on a whim...

    These situations DO occur in the real world. The system I have been working on must perform a minimum of 50K operations per second. This means an average operation time of 20uS (some will go longer, most will be shorter, as long at the 50K count is met for any 1 second sampling period). These operations are non-trival, involving significant calculations and relations between objects. Late last year we went from failing the performance test, to meeting it with a healthy margin simple by doing things such as re-organizing order of fields within object, re-ordering object creations, etc. All things that are not part of any "functional"/"behavioral" type specification, but are all part of knowing now the toolset being used (in this case .Net 4.0.1) works in detail.



  • @TheCPUWizard said:

    @C-Octothorpe said:
    @TheCPUWizard said:

    So knowing that value will be zeroed when members of of a class or struct (vs other languages where they may contain random data) is an " internals of the runtime"?? Not in my book. It is a key feature why they do not have to be explicitly set (and that seting to zero explicitly causes additional overhead).

    I also left out one reason for access of eference type members...and that is every time the GC runs to to a scan for what objects are reachable..This becomes a (small but non zero) runtime performance issue (as does the fact that the additional fields decrease cache hit density)

    These are [IMPO] key elements of software DESIGN....sure a "code monkey" may be able to ignore them and get away with it...but  I would not higher someone who will have design responsibilities withou this knowledge, and my clients (when I perform screening for them) seem to agree almos universally.

    Are you saying that you'll only hire people that will spend 3 days looking at CIL to (maybe) eek out an extra 1 or 2 CPU cycles? If so, then you're either full of shit or TRWTF. I've met/worked with some very bright minds who would put Jon Skeet to shame, and they never would consider the shit you just mentioned.

    I am saying that I will only hire someone with DESIGN responsibilities who was aware of potential issue of this nature, knew when to consider them, and could address them. It would be foolish (and I never said) that I woud have someone spend time ["3 days looking at CIL"] on a whim...

    These situations DO occur in the real world. The system I have been working on must perform a minimum of 50K operations per second. This means an average operation time of 20uS (some will go longer, most will be shorter, as long at the 50K count is met for any 1 second sampling period). These operations are non-trival, involving significant calculations and relations between objects. Late last year we went from failing the performance test, to meeting it with a healthy margin simple by doing things such as re-organizing order of fields within object, re-ordering object creations, etc. All things that are not part of any "functional"/"behavioral" type specification, but are all part of knowing now the toolset being used (in this case .Net 4.0.1) works in detail.

    Edge case != common case.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.