VB "with" equivalent?

This is a discussion on VB "with" equivalent? within the C# Programming forums, part of the General Programming Boards category; Is there a C# equivalent of VB 's With someobj .this = that .other = xyz End With...

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    70

    VB "with" equivalent?

    Is there a C# equivalent of VB's

    With someobj
    .this = that
    .other = xyz
    End With

  2. #2
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Nope. That's messy code. Why don't we all go back to using gotos and functional programming

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >> That's messy code. <<

    I think it is cleaner and it does provide a performance improvement. How often do you use an explicit variable to emulate the With statement?

  4. #4
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Sorry, I meant to come off sounding sarcastic - you are right, and I think its a useful statement to have around. Theres a lot of things they left out in C# that were considered messy that I wish they'd used.

  5. #5
    Registered User
    Join Date
    May 2005
    Posts
    28
    Quote Originally Posted by anonytmouse
    >> That's messy code. <<

    I think it is cleaner and it does provide a performance improvement. How often do you use an explicit variable to emulate the With statement?
    Cleaner is a stylistic decision, and no there would be no performance improvement it is just syntactic sugar. As for the other poster that suggested we could just go back to "gotos and functional programming", I think you probably mean "gotos and procedural programming" which is what C is, procedural. Functional is a whole different class of languages that treat functions as first class objects ala ML, Lisp, Scheme, etc... And lest you think badly of them most of the "fancy" new language features that we have in the newest languages have been in LiSP since its beginnings in the 1950's.


    Mezzano

  6. #6
    Banned nickname_changed's Avatar
    Join Date
    Feb 2003
    Location
    Australia
    Posts
    986
    Quote Originally Posted by Mezzano
    Cleaner is a stylistic decision, and no there would be no performance improvement it is just syntactic sugar.
    He was referring to the performance benefit over doing something like this (I don't use VB often, if at all, so my syntax might be wrong):
    Code:
    With SomeDumbClass.SomeDumbSubClass.SomeDumbProperty
       .Name = "Something"
       .Value = "SomeOtherDumbThing"
    End With
    As opposed to something like this:
    Code:
    SomePropertyType temp = SomeDumbClass.SomeDumbSubClass.SomeDumbProperty;
    temp.Name = "Something";
    temp.Value = "SomeOtherDumbThing";
    The first method is faster because VB would compile it to (or at least one would hope):
    Code:
    SomeDumbClass.SomeDumbSubClass.SomeDumbProperty.Name = "Something"
    SomeDumbClass.SomeDumbSubClass.SomeDumbPropertyValue = "SomeOtherDumbThing"
    Which is ugly. There would be a performance benefit to With as it avoids the need for a temp object (I realise its just a memory pointer in essence, but every little bit adds up).

    >> procedural

    Yep, I meant procedural, I realise functional programming is a very different kettle of fish. I just couldn't think of the word.

    <rant>
    I work for a software company as a .NET developer, and I'm supposed to finish work at 5:00pm after starting at 8:30. I usually get in around 8am, and often finish past 10pm. If I come accross as a little grumpy, thats probably why. It is compounded by the fact that I don't get paid for overtime. I don't have to stay back, I just do because I get into my work and since everyone else leaves the office at 5:01 time goes very fast after hours.
    </rant>

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    It's actually the other way round.

    SomeDumbClass.SomeDumbSubClass.SomeDumbProperty.Na me = "Something"
    SomeDumbClass.SomeDumbSubClass.SomeDumbPropertyVal ue = "SomeOtherDumbThing"
    This is the slow version. It needs to call the property getter for SomeDumbPropertyValue twice. The With version and the temp-object version do it only once, thus they are faster.
    With is, in fact, implemented using an anonymous temporary object. There is no speed difference between With and a temporary object, assuming that the compiler optimizes the temporary object into a register.
    The reason is that temporary object is actually incorrect. It's a temporary reference to an existing object.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User
    Join Date
    May 2005
    Posts
    28
    Quote Originally Posted by CornedBee
    It's actually the other way round.


    This is the slow version. It needs to call the property getter for SomeDumbPropertyValue twice. The With version and the temp-object version do it only once, thus they are faster.
    With is, in fact, implemented using an anonymous temporary object. There is no speed difference between With and a temporary object, assuming that the compiler optimizes the temporary object into a register.
    The reason is that temporary object is actually incorrect. It's a temporary reference to an existing object.
    I would assume the compiler isn't completely braindead and will NOT call the getter twice. After the first call the pointer to the SomeDumbPropertyValue already resides in a register, thus it can be immediately reused in the second expression. This is all theoretical because I don't know how smart the VB compiler actually is Basic code analysis at compile time would reveal this and I would be shocked if the VB compiler doesn't do it. I was just pointing out that since your code isn't run directly, ie it is converted to MSIL and then JIT'ed before being run it is a bit more difficult to tell 'what is more efficient' just by looking at the code.


    This of course assumes the getter is a trivial "return blah", if it is more complex then the compiler would need to decide if it could be inlined.


    Mezzano
    Last edited by Mezzano; 05-20-2005 at 03:11 PM.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    This of course assumes the getter is a trivial "return blah", if it is more complex then the compiler would need to decide if it could be inlined.
    But, since getters are polymorphic by default, you need to make them "final" (or is it something else in C#?) in order for the compiler to make any assumptions about them. As it is, some subclass that is dynamically loaded at runtime might override the getter and log the access somewhere - which means that an optimized version is no longer semantically equivalent, and this is highly invalid.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Registered User
    Join Date
    May 2005
    Posts
    28
    Quote Originally Posted by CornedBee
    this is highly invalid.
    But it's not. We are talking about two calls to the same getter interspaced by no other code. Polymorphism doesn't come in to play since after the first call the result of the getter is already in a register. It can safely be re-used for the second call because there is NO way (saving some sort of synchronization problem, which is the coders problem not the compilers) that the resulting value of calling the getter again would be any different on the second call than it was the first.


    Mezzano

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    It can safely be re-used for the second call because there is NO way (saving some sort of synchronization problem, which is the coders problem not the compilers) that the resulting value of calling the getter again would be any different on the second call than it was the first.
    The issue is not what the getter returns, but what it does beside returning the value. It's about side effects and what functional languages call referential transparency - there's no such thing in imperative languages.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Registered User
    Join Date
    May 2005
    Posts
    28
    Quote Originally Posted by CornedBee
    The issue is not what the getter returns, but what it does beside returning the value. It's about side effects and what functional languages call referential transparency - there's no such thing in imperative languages.
    In the original post I said "this assumes the getter is trivial", which would not be the case if it "did things other than just returning the value". I said if that was the case the compiler would have to make a decision on whether or not it could be inlined, which is what I think you are arguing about. I am not saying this decision is trivial but I don't think it is undecidable either.
    So the problem comes down to determining if the getter is referentially transparent, ie will invoking it one time cause state changes that cause it to return a different value when accessed again, loosely speaking. You say there is no such thing as referential transparency in imperative languages? Are you saying that it is impossible to have a statement/function with no side effects? I don't quite follow your argument. I would argue The property foo defined as follows is referentially transparent. The state change in x does NOT change the value returned and thus is irrelevant.


    Code:
    public string foo
    {
       get
       {
           x++;
    
           return bar;
       }
    }
    the getter could be inlined, and the compiler could choose not to refetch bar after the first invocation, all it needs do is increment x. Perhaps I am misunderstanding referential transparency or your argument, my knowledge in this area isn't extremely deep


    Mezzano

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    There are two parts to my argument:

    1) If the getter has side effects, a call to it must not be optimized away. Neither is it possible to do only the "side effect" part. No compiler is smart enough to determine what is a side effect and what is not.

    2) There is no way to determine, at compile time, whether a getter has side effects, because at compile time, it is not known which getter will be called. By default (unless marked as final), getters behave like all other functions in that they are polymorphic. That means that a subclass might override the getter. And this getter might then have side effects. If the compiler optimized under the assumption that the base getter gets called, but at runtime it turns out that it's a different getter, there's a problem.


    Bottom line: mark as much stuff as final as you can. It will make your programs faster.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    May 2005
    Posts
    28
    Quote Originally Posted by CornedBee
    There are two parts to my argument:

    1) If the getter has side effects, a call to it must not be optimized away. Neither is it possible to do only the "side effect" part. No compiler is smart enough to determine what is a side effect and what is not.
    Hmmm.... I would argue that. By that logic then a compiler could not optimize anything, because it would be unable to determine if the optimization caused a relied upon side effect not to happen. You can do optimizations to code without having to "determine" the side effect part. In the code I gave it is trivial for a compiler that does ANY sort of rudimentary analysis to realize that x does not effect the result being returned. Thus it should be able to conclude that the second "call" is unnecessary and it can simply use the value returned from the first call, however it must do the x++ before using the value to make sure the optimization doesn't disrupt expected state. Further, though it has been awhile since I have checked, most language specs specifically detail whether operations have side effects or not, therefore it is possible to determine if something causes a side effect, look at the spec and the expression in question.

    Again, perhaps I am arguing a different thing, I am not saying ALL getters can be optimized away, if they involve function calls or other things that are non-trivial to analyze then it is easier and cheaper to just assume they can't be optimized. But most getters shouldn't be massively complex. The idea behind getters is to allow restricted access to your objects state. It would be a reasonable assumption that calling a getter shouldn't be massively expensive, ie the getter shouldn't compute the millionth prime recursively on every call C# provides the nice property syntax in order to avoid having a bunch of foo.getName() calls everywhere as they are replace by foo.Name. The concept is the same and the IL generated will be a function called get_Name or something similar. However, as stated I think it is horrible design to make your getters overly complex, because people use them thinking that it is an efficient way to access the state, if it isn't then you aren't really providing them in the way you should.



    Quote Originally Posted by CornedBee
    2) There is no way to determine, at compile time, whether a getter has side effects, because at compile time, it is not known which getter will be called. By default (unless marked as final), getters behave like all other functions in that they are polymorphic. That means that a subclass might override the getter. And this getter might then have side effects. If the compiler optimized under the assumption that the base getter gets called, but at runtime it turns out that it's a different getter, there's a problem.
    Again I would argue, you are talking about compile time as though it were statically compiled. C# goes to IL and is then JIT'ed, these are two separate stages. For the JIT'ing it DOES know what getter will be called, since it knows the run-time type of the object being dispatched upon (since it IS run-time and all).


    Quote Originally Posted by CornedBee
    Bottom line: mark as much stuff as final as you can. It will make your programs faster.
    Agreed. The keyword in C# is sealed, but yes it has the same effect. I agree with this as well since giving the compiler info that only you as the programmer really know about the intended usage of your objects is a big win, common sense everyone should strive to do things to give the compiler all the info it needs to make good decisions.


    Mezzano

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    For the JIT'ing it DOES know what getter will be called, since it knows the run-time type of the object being dispatched upon (since it IS run-time and all).
    The thing about JITting is that you usually don't have the time to do optimizations. The VM needs that compiled code, and it needs it NOW. JITters such as the (very fast) experimental Cacao JavaVM developed at my university don't even do fancy register allocation.

    Also, I very much doubt that the JITter is given runtime information. The compiled code will be reused, and by that time the reference might point to a different object. If you recompiled the code every time it is executed, you'd lose all the benefits of JITting; your VM would be considerably slower than a byte code interpreter. That's the way JITting works: you trade a slightly slower execution the first time around for considerably faster execution the next time the code is called.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer equivalent to array notation
    By bekkilyn in forum C Programming
    Replies: 4
    Last Post: 12-06-2006, 08:22 PM
  2. Passing an Array of Strings from VB to a C DLL
    By mr_nice! in forum Windows Programming
    Replies: 9
    Last Post: 03-08-2005, 06:16 AM
  3. C with VB ?
    By khpuce in forum Windows Programming
    Replies: 2
    Last Post: 02-21-2005, 08:00 AM
  4. Header File Question(s)
    By AQWst in forum C++ Programming
    Replies: 10
    Last Post: 12-23-2004, 11:31 PM
  5. Passing parameters from VB to C++ through ActiveX DLL
    By torbjorn in forum Windows Programming
    Replies: 0
    Last Post: 12-10-2002, 03:13 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21