Sorry Visual Basic -- I is through *WITH* YOU!
I've always had a soft spot for visual basic. Sure it's verbose. (verbose, like XML, is evil.) Sure it feels patronising to say "nothing" when you really mean "null". Sure some of the default settings were criminally stupid. Sure VB over uses the round brackets, like they're good enough for parameters, arrays and generics all at once, yet makes no clear distinction about using them for method versus property references... then mis-uses the angle brackets for crazy non-XML stuff like attributes. But it has background compilation, and -- smarter still -- it has the with statement. The with statement is way cool. With is like the (not yet invented) Context Driven Development which will give us a further 46% productivity gain. (Eat that, smug lisp weenies!) Yet with just bit me bad -- turns out there's something fundamental i didn't know about with...
Say you have an object variable you've already declared:
Dim builder As StringBuilder
While it's fine to write this:
builder = New StringBuilder
With builder
.Append("Fred")
End With
It's not fine to write this:
With builder
builder = New StringBuilder
.Append("Fred")
End With
The latter returns a null reference exception.
Setting the with'd variable inside the with seems to be a little bit ignored.
The reason is buried deep in the generated MSIL. I expect. And it sh*ts me to tears.
So one of those tiny elegant features that makes life simpler and easier just dissolved for me -- making like uglier and more complex.
At least VB's still got background compilation and a nicer embedded XML syntax (...come 2008. Whenever that's gonna get here)
(and before some dimwit troll jumps in to attack a language in the comments -- i strongly support polyglotics over language-war.
Say the average human can master 3 natural languages. And the average computer language is (for the sake of argument) 1/20th as complex as a natural language -- then the average programmer ought to be able to master 60 programming languages. If you've mastered less than 60 languages and you openly discourage others from learning a particular language -- well, that's outright bigotry. maybe. or not ;-) )
'"dimwit troll" i suppose' on Sat, 04 Aug 2007 12:44:21 GMT, sez: i hate to be the "dimwit troll", but VB lacks a lot more features than a consistent 'with' phrase.
For example: XML comments. (These might be included by now) But originally they were excluded from VB.net 1.0 and that was a major discouragement for my team, as VB was supposed to be the more 'business friendly' language yet lacked such a fundamental feature.
Apparently automatic properties will not be implemented in VB.net, while C# will have them. Again, VB misses a feature that suits its target audience... is the VB team asleep at the wheel?
you have hit the nail on the head, completely! VB today should be where Ruby is, yet Microsoft fell asleep in about 1994 and now they are "playing catchup" as usual!
DISGRUNTLED VB LOVER TURNED C# HATER
'David' on Sat, 04 Aug 2007 12:47:06 GMT, sez: To me that restriction makes perfect sense. How does the compiler know that the thing you're referencing is about to created? It seems to me the equivalent of..
If x = 5 then
Dim x as Integer
End If
Why say you want to start doing something "with" a reference/object/etc before you've declared what the object is?
'lb' on Sat, 04 Aug 2007 12:52:50 GMT, sez: @David
yeh it makes sense some when you *think* about the code...
and writing code in the way i exampled abot is something that i have only done once (it seems) in the last 10+ years...
yet -- i'd prefer it if the compiler simply turned the code:
With builder
builder = New StringBuilder
.Append("Fred")
End With
into:
builder = New StringBuilder
builder.Append("Fred")
basically replacing the dot with the name of the thing that was with'd
because that's the simplest mental model.
and trying to maintain a more complex mental model is utterly in oppostion to the use of a high level language.
'David' on Sat, 04 Aug 2007 13:09:31 GMT, sez: I haven't used VB in a while, but I always thought of 'with' as a quick way of repeatedly accessing something that had a long and tiresome-to-type-out name, e.g.:
With ReallyLongVariableName(ObscureIndex)
.Title = "blah blah"
.Description = "something else"
End With
Handy for that, but not much else it turns out :-)
'rcardare' on Sat, 04 Aug 2007 16:28:36 GMT, sez: That one is hard to grasp for me. I think maybe something like:
With builder As New StringBuilder()
.Append("Fred")
End With
'Mike Gale' on Sat, 04 Aug 2007 18:53:55 GMT, sez: The VB behaviour looks fine to me. It's what I expect.
'Mike Woodhouse' on Sat, 04 Aug 2007 20:24:41 GMT, sez: If the StringBuilder object is only needed for the duration of your With...End With, then you might consider
With New StringBuilder
.Append("Fred")
End With
which was always a favourite use for me. Although off-hand I don't actually know if it works in .Net - since I still do a fair amount of work in VBA I don't like switching dialects. I don't know if there's any benefit beyond brevity now.
Anyway, one day we'll all be using Ruby.
'mike' on Sun, 05 Aug 2007 04:12:14 GMT, sez: I'm with David and Mike I on this one. I think it might be because, as Mike II notes, this is a syntactic feature of interpreted Basic, where it wouldn't make sense to be assigning values to objects you haven't explicitly declared already. Even tho the compiler could sort out what you mean if you declare the object inside the With block, maybe, that would represent a syntax change from, um, classic VB.
I think the issue here is that it's intuitive to the primarily-VB crowd, maybe not so much to the also-VB folks. What say we?
'Jan' on Sun, 05 Aug 2007 05:19:19 GMT, sez: Here's what's going on:
Dim s As String = "1"
With s
s = "2"
Debug.Print(s.ToString)
Debug.Print(.ToString)
End With
Output:
2
1
So, With has its own variable.
If you try the same thing with a value type like integer, the output is:
2
2
Seems to be a similar mechanism as passing variables by reference.
'Jan' on Sun, 05 Aug 2007 06:57:12 GMT, sez: On further thought, scratch that "by reference" bit - not sure why it should work differently for value and reference types.
'Dave Markle' on Sun, 05 Aug 2007 09:36:22 GMT, sez: I am completely at a loss as to why ANYONE would want to use something like "With" in a .NET language in the first place. Here are my reasons:
1) It makes code of any complexity much harder to read. Long "with" statements are a nightmare to read, especially if they're interspersed with function calls and other variables...
2) You can do the same thing in less lines by just using a reference:
Instead of
With bigLongObjectName
.Foo = 5;
.Bar = "bar";
Why not just use:
Dim b as BigClass = bigLongObjectName
b.Foo = 5;
b.Bar = "bar";
'Ian Horwill' on Sun, 05 Aug 2007 16:31:51 GMT, sez: I agree with Leon: high-level languages should present a consistent abstraction of what's going on. From Jan's comment, I guess the model is that the With block specifies a default variable; for reference vars, changing the reference inside the block doesn't affect the default.
'Mark' on Mon, 06 Aug 2007 15:17:03 GMT, sez: In my case, the model that immediately came to mind was class methods. When the VB parser sees "with", I get the imression that the language starts a new, inline closure, and uses the "with"'ed variable as an implicit "this" variable ("me"(?) in VB? It's been a while). Just as class methods can't set their own "this" reference, it makes sense that code inside "with" closures would also be unable to set their own implied-variable references.
Of course, the fact that it _does_ work with value types (like integer) throws a wrench into that hypothesis. :-) Maybe the value-type behavior came out of what they needed to do to make it work for value types. *shrug*
(FWIW, I'm an also-VB guy.)
'Zooba' on Tue, 07 Aug 2007 08:18:36 GMT, sez: VB has been my primary language up until this year, with assembly language being second (C++ and C# are now primary, since I'm doing real work rather than hobby stuff), and I always interpreted the with statement as loading the structure/object address into a register and keeping it there.
The x86 architecture cannot dereference a memory value directly as some other architectures can. To follow a pointer stored in a variable it needs to be loaded into a register. So to access members of a structure allocated on a heap, the address needs to be loaded, followed by the value. The with statement loads the address and keeps it.
Of course, optimising compilers have done this automatically since they were first invented, so there's absolutely no performance impact in using with. I just though I'd share my strange HLL-ASM link.
'Luc' on Wed, 22 Aug 2007 00:32:21 GMT, sez: With is pretty handy, but you are using it wrong.
dim sb as new stringbuilder()
with sb
.append("blah")
end with
Seems counter productive to say "with" and then new up the same variable that you are "with"...ing. :P
|