David said:
Thank you for spending some time to look at the critique.
starting with the Syntax section.
It seems this section has recieved the most attention in many
responses. It is hardly surprising since syntax is where a lot of
things are subjective.
The long rant about multiple initializations makes some sense
Yes, that section will need to be rewritten to be more concise. Others
have had the same impression and after re-reading it myself, I get the
same view.
but I personally find all of your alternatives to be much worse and much less
readable.
Fair enough, some others have thought the same thing too. IIRC, I
think I came up with that proposal like this. I had initially given
the declarations like so:
Dim c, d, e As Integer
then later on realised that I wanted to initialise all three variables
at their point of declaration, so I assumed one could just do this:
Dim c = 1, d = 2, e As Integer = 3
but obviously the compiler didn't agree with me. It does look awkward,
because as you mention below, the type name coming after the variable
name makes a lot of usable syntax impossible.
Putting the type after the varname in declarations makes a
lot of usable syntax impossible, but that's just complaining about Basic
being Basic.
I know what you mean
. At the end of the day, I guess one could just
settle for typing a few more characters and use this:
Dim c As Integer = 1, d As Integer = 2, e As Integer = 3
and afterall, a certain degree of verbosity is, IMO, what makes VB
easier to understand so its no biggie.
The Is operator tests whether two references are identical, it makes
absolutely no sense to allow it to apply to value types. Really, that's
just not understanding what a value type is. And as for TypeOf, again
it makes absolutely no sense to apply to a value type; there is simply
no possible reasonable use of such a feature. Should the language still
allow programmers to do nonsensical things for the sake of completeness;
maybe, but that's exactly what you're ranting *against* when you
complain about the fact that Sub Main can be recursive. Make up your
mind.
I will quote myself from another group, to show my reasoning behind
that argument:
<quote start>
This is going to be an interesting problem area of the .NET CTS
resulting from the difficult (and in some ways, pointless) goal of
type unification. Everything in .NET (and hence VB7) *is* an object
because all types either directly or indirectly inherit from Object.
If you agree with me so far, then you will also agree that *all* types
in .NET are actually *reference* types its just that *some* of those
reference types (those that inherit from ValueType) have *value
semantics*. Now then, the Is operator checks if two variables refer to
the same object. By way of logical deduction, the Is operator should
work in all cases because it works on object types and every type in
..NET is an object. The problem? It doesn't. While it is easy to accept
that and just work with it, the issue is still a consistency problem
from a language design point of view and is of more relevance to those
interested in language design. Such exceptions have to be made all the
time when one attempts type unification. Other examples abound in .NET
but to see this in a different language look at this article on the
Blue language (especially section 3.3):
http://tinyurl.com/yryyz
And if you really think
Dim p as Point = {12,15}
is much simpler and easier to read than
Dim p as New Point(12, 15)
then I'm kinda glad you don't do language design.
It being easier to read is again subjective and my exposure to
C/C++ seems to be showing here (and yes, I know VB isn't C/C++ and nor
should it be). However, as for it being *simpler* (a notion which is
still subjective but one that is easier to give arguments for or
against) I said the following:
"...the variation I am suggesting, is conceptually simpler, IMO. With
the current syntax you have to understand constructors and their
semantics, use of the 'New' keyword both in variable declarations and
definitions of constructors, and finally, use of named arguments."
Opinions will differ, so it would be nice if someone can find and
present arguments that show it not to be simpler, so we can have
atleast two points of view to consider.
Because the above doesn't make perfect sense, in fact it makes
absolutely no sense at all.
Could you perhaps expand a little on your point of view? Given what
the language reference says about the Nothing keyword:
"The Nothing keyword represents the default value of any data type.
Assigning Nothing to a variable sets it to the default value for its
declared type. If that type contains variable members, they are all
set to their default values."
that syntax restriction on optional structure arguments still seems to
be an arbitrary limitation to me. Part of the problem stems from the
fact that VB.NET requires you to explicitly provide a default value
for optional parameters - a requirement which is somewhat redundant
since VB states that variables will always be automatically
initialised to the default value of their type. Maybe there is a good
reason for the limitation and if someone can point it out to me, I
will stand corrected.
I'll zoom through a few other things. First, .Length in arrays and
.Count in collections aren't measuring the same thing, and it would be
much more confusing if two properties with such different meanings had
the same name.
They have different meanings? Thats not the impression I get when I
read the documentation of those respective properties:
*Array.Length
Gets a 32-bit integer that represents the total number of elements in
all the dimensions of the System.Array.
*ICollection.Count
When implemented by a class, gets the number of elements contained in
the System.Collections.ICollection.
The big give-away being the substring "number of elements" appearing
in *both* definitions.
The constant complaints that objects must be initialized
(such as arrays and strings) just eludes me somewhat; I honestly find
the behavior to be perfectly logical and simple.
Fair enough. I honestly dont find this behaviour logical and simple:
Dim arr1() As Integer
Debug.Assert(arr1.Length = 0) 'exception thrown here
Dim arr2() As Integer = {}
Debug.Assert(arr.Length = 0) 'no exception thrown here
but again, opinions differ. My complaint is geared towards some of the
types being half way between the value-type and reference-type
categories, which is one of the unfortunate side-effects of the goal
of type unification. The basis for my complaint about the Length
property is given in the "Arrays as objects" section:
"I now have to worry about null references while am using arrays. For
instance, the Length property should logically contain zero when an
array has no elements. However, because a reference to an array
without elements is a null reference, I can't check the Length of an
uninitialised array without getting a NullReferenceException. If
arrays were not objects or the compiler was kind enough to 'cheat' and
return 0 for the expressions like "MyArray.Length" when MyArray was
null, I could retrieve certain info (array length, number of
dimensions and upper bounds of each dimension) without ever worrying
about null references."
Properties such as the number of dimensions, the upper bound of each
dimension and the length of an array should be things that you can
find out whether the array has elements or not. This is especially so
if you are not using dynamic arrays but I guess it isnt simply because
VB doesnt allow you to declare fixed size arrays. Actually that last
sentence may not be entirely true, because I came across an attribute
called VBFixedArrayAttribute that may allow declaration of fixed size
arrays but I will need to look into it.
And the idea that
zero-based arrays are more error prone is little more than personal
opinion, and one that flys in the face of an awful lot of comp sci
literature.
See my initial response to Herfried about this one.
I think you have some decent points to make,
Thank you
but it seems like half of
the essay stems from a total misunderstanding of .NET types
I am human and hence prone to being wrong, but I can confidently say
(without meaning to sound haughty) that I have a fairly good if not
firm understanding of the .NET type system. I am always open to
correction, but I have attempted to provide the basis for my reasoning
(see earlier on in this response, where I quote myself from another
group) and hopefully someone can see where I am coming from with
respect to some of my arguments about the type system.
and an insistence on working with Option Strict Off.
Actually, I write all my production code with Option Strict On. I
don't quite remember if Option Strict was On in every instance where I
wrote the snippets, but I will confirm that in the next revision of
the critique.
I agree with some of your
points, structure semantics are a mess, array declarations are error
prone, but unfortunately I also think that the good points are buried in
a morass of long rants
Yeah, I will need to revise some parts to remove the unnecessary "blah
blah" and make the points more concise.
are simply nit-picking at silly thing (e.g, the
"MustInherit" example, the disgruntled employee with bad variables names
(would names like 'AAAAAAA' be any more readable?)).
See my initial response to Herfried, for my reasoning on the
'MustInherit' example. As for the variable names consisting purely of
underscores and the disgruntled employee, the basis for my argument is
similar to that for a recursive Main(): IMO, unnecessary flexibility
is just as bad as no flexibility.
All in all, I think the essay would be much more useful if you could
separate the "this is a problematic construction and here's why" issues
from the "I would have done it this way" issues.
I am currently investigating a different format for the next
revision, so as to make the essay more useful. Many thanks for that
suggestion.
Hey, you asked for comments...
And great comments I got
. Thanks for sharing yours.
Cheers,
Eric