Dim and New

What exactly does Dim do? As I understand it, it used to be used to allocate the size of an array. Then it became used to allocate memory for a type. Then we have classes as a type. So is there a case where I would write dim v as dictionary and then never say new? What can I use v for if I haven’t instantiated it? Sometimes you need new and sometimes you don’t, is this just legacy stuff because we don’t want to break old code from previous versions.

This is where the Language Reference enters in the game.

I stopped to think at why this and why that on this kind of things decades ago.

Same apply for numerics values (numeric range for int8, int32, etc.). WHen I notice a trouble (or sometimes at writing time), I check the LR and change the code accordingly.

Last week, I used for the first time Dim f As New FolderItem. I use Xojo since REALbasic 1.0, 20 years ago or so. I cannot say why I used that syntax, but I wrote it and it worked for whet I wanted to do.

That said, someone may have a better explanation.

Do not confuse Xojo dim with standard Basic dim.
dim declares a variable.
new create a class instance
So

Dim mydict as Dictionay

declare the variable mydict as of type Dictionary but does not create an instance of a dictionary class

mydict = new dictionary 

declares a new instance of a dictionary class referenced by the variable mydict

Dim mydict As New Dictionay

Declare mydict as of type Dictionary and create and instance of the Dictionary class that will be referenced by mydict.

The Language Reference is not consistant in that case in the examples.

But they are polishing it and probably will make changes in the examples.

The docs comes AFTER the product (usually).

I understand the syntax can be inconsistent. As I’m new to Xojo, started about a year ago and got sidetracked, I’m wondering if there is some programmatic advantage to just declaring something and never instantiating it. If there isn’t then it’s just a language implementation that is inconsistent and you work around it.

You can instantiate only classes not intrinsic types like, for example, integers.

Declaring a variable to be of a class type without creating a class instance is valid: you can for example set its value, i.e. its reference to a class instance, to be the value of another variable of the same type referring to an existing instance.
It’s something like (but very different, see below) to have an integer where you don’t define its contents but copy in it the value of another integer.
When you copy the contents of a variable of a type class into another variable of the same class type you don’t create a copy of the instance (like for integers) but you have two variables referencing the same class instance.

So I can use it like a pointer?

They are “pointers”.
When you “dim” a variable of class type but you don’t assign to it a class instance reference with a “new” or copying in it the value of a class instance you get a “nil object exception” if you try to access the class contents.

Thanks. I think I’m sneaking up on an aha moment:)

DIM is used to create an instance of a VARIABLE (which can include objects)
NEW is never used alone, but with DIM to indicate a new OBJECT

valid examples

DIM x as INTEGER
DIM dt as NEW DATE // this creates a "new" date object and initializes it 
DIM dt2 as DATE // while this valid, it is a NIL pointer as it was not initialized

invalid examples

DIM x as NEW INTEGER // Integer is not considered an "object or class"

Beware there are some “OBJECTS” built in to Xojo that DO NOT REQUIRE the use of “NEW”
FolderItem is one,

Basically if you need “NEW”, you are “POINTING” at the actual class/object

And because they are pointers, you need to be aware of how they work

DIM dt as NEW DATE
DIM dt2 as DATE
dt2=dt  // now BOTH dt and dt2 point at the SAME object
dt2.totalseconds=x // this will change what DT returns as well, remember SAME OBJECT

The Recordset is a great example of a Xojo object that doesn’t require the new because they are always returned a method. In fact it will generate a compiler error now - it didn’t used to. So you’d see code like this:

Dim rs as new recordset rs = myDatabase.sqlselect(sql)
So while it wasn’t technically wrong it was a waste of resources because it would allocate the resources for the recordset and then replace it on the next line.

No, DIM is much more than just a language implementation you work around. Off the top of my head, it allows the IDE to:

  • Auto complete the name when used in code
  • Offer properties or methods available for that variable/object type (and autocomplete them)
  • Allow the compiler to ensure you are using the variable/object in a valid manner

But more important than those, WHERE you place it controls the “scope” of where it can be used. Consider:

Dim a as Integer = 10
If a < 50 Then
  Dim b as Boolean = false
Else
  Dim b as Boolean = true
End if

At this point, what is the value of b? It is neither true nor false; it does not exist because it “went out of scope” when the IF block ended. Contrast that to:

Dim a as Integer = 10
Dim b as Boolean
If a < 50 Then
  b = false
Else
  b = true
End if

In the second example, variable b still exists after the IF block (and would be false since 10 < 50). But my point is WHERE you place the DIM is vitally important to the “scope”.

As far as using New or not, as others have mentioned you use New for objects but not primitive variable types. You only need to use New on the DIM statement if you also want to “instantiate” the object to a non-null value. If you will be calling a method that returns an object and you need to define the object to hold the return value, then don’t bother to use New.

Dim myObject as CoolObject
myObject = MyMethodThatReturnsCoolObject()

If you added New on the Dim statement, then you must also supply arguments that make it a valid constructor for that object unless there is a constructor for that object that takes no arguments or they are all optional. (Like the Date object defaulting to the current time.)

Dim myObject as New CoolObject( arg1, arg2 )
myObject = MyMethodThatReturnsCoolObject()

In the above example, there is no point to using New because the object gets replaced by the return value from the method. Unless the constructor has significant time overhead (such as obtaining a value from a web service), in general computers are fast enough now you’d not perceive a performance difference without a VERY high loop iteration count.

But if you need the object to be non-null to use for anything other than a return value, at some point you must use New to instantiate it. Following my IF example for the Integer variable above, it might be something like this:

Dim a as Integer = 10
Dim myObject as CoolObject
If a < 50 Then
  myObject = New CoolObject( this )
Else
  myObject = New CoolObject( that )
End if
Dim myOtherObject as New CoolObject( somethingElse )

These are all contrived examples, but my point is both DIM and NEW exist for very valid reasons, and WHERE you use them is much more than just an inconsistent language feature you work around.

It is consistent, and understanding when and where to use them is vital to understanding “scope” and when objects are valid.

“Sugar” to me is syntax that exists to help explain what is going on
NEW IS required in some circumstances, and you can’t instantiate most objects without it

I like this discussion because I find it a little confusing under some circumstances. I liked Keeney example of creating an object “pointer” with a Dim statement and never using a New because it is destined to be the recipient of a method that returns this type of object.

Contrived example:
wholeLine is an array of CurveShape.

For the example below (2nd variant), I consider the Append statement to essentially be creating a New instance of a CurveShape without explicitly using the word New.

wholeLine is an array of CurveShape so when you Append to that array it “implicitly” creates a New instance. You do not (or do you?) need to write

1st variant

Dim someLine As CurveShape \\\\ NIL pointer wholeLine.Append(someLine) wholeLine(wholeLine.UBound) = New CurveShape \\\\ necessary? wholeLine(wholeLine.UBound).X = 6

. . . . . . . . .

2nd variant

In the example below, I assume that with “littleLine” being created within the loop that it requires the New syntax. Otherwise the littleLine.X = x1Pix + 50 would fail. This code works.

[code]For nElement As Integer = 1 To topElement

Dim littleLine As New CurveShape

x1Pix = 5 * nElement
y1Pix = 42
x2Pix = 6 * nElement
y2Pix = 15 + nElement

littleLine.X = x1Pix + 50
littleLine.Y = y1Pix + 50
littleLine.X2 = x2Pix + 50
…

littleLine.BorderColor = cBorderColor

wholeLine.Append(littleLine)

Next[/code]

But what if you had written

3rd variant

[code]Dim littleLine As New CurveShape

For nElement As Integer = 1 To topElement

x1Pix = 5 * nElement
y1Pix = 42
x2Pix = 6 * nElement
y2Pix = 15 + nElement

littleLine.X = x1Pix + 50
littleLine.Y = y1Pix + 50
littleLine.X2 = x2Pix + 50
…

littleLine.BorderColor = cBorderColor

wholeLine.Append(littleLine)

Next[/code]

Would that be equivalent to the first version? Or would all the Appended elements of wholeLine be given the properties of the last assigned values through the loop?

I apologize in advance to those who would respond to this: Why don’t you just experiment with these variants, you lazy ### !!!

I like to understand the “logic” behind what is necessary and why.

Edit: Reorganized this post to move in order of your examples.

Let’s take a look at your first code example:

Dim someLine As CurveShape \\\\ NIL pointer wholeLine.Append(someLine) wholeLine(wholeLine.UBound) = New CurveShape \\\\ necessary? wholeLine(wholeLine.UBound).X = 6

In this example, yes, the new CurveShape line is necessary. What you’ve done here is appended a non-existant object to the end of your wholeLine array. This is totally legal, as shown in my next post with the screenshot from the debugger. However, without creating a new instance of CurveShape, the line where you set the X value to 6 would cause a NilObjectException because there is no object in that slot.

For your second example:

Actually, you are explicitly using the word new to create littleLine as a new instance of CurveShape, which you then append to your array of CurveShapes. You may be misunderstanding something in there. You aren’t implicitly anything with Append, you’re explicitly appending an object to an array of objects.

On to the third example:
You were correct in guessing that every object in the array would have the same values as the last one. This is because you never create a new instance of CurveShape to work with. Even though you are appending to the array at the end of the loop each time, you are appending a reference to the same object.

Lastly,
There isn’t so much a “difference between” dim and new, they do different things and have different jobs. New creates a new instance of the class to use for that object, where dim creates the space in memory to work with an object or objects.

For a light hearted metaphor, consider this:

dim oMug as new coffeeMug

Here, dim clears off the space on your desk to place oMug, and new coffeeMug tells the compiler that you’d like to fill that space with a new instance of a coffee mug. You can’t quite do much with the mold, which would be the class coffeeMug, but because you’ve made a new instance of one and put it on your desk, you can fill it and drink from it.

Of course, all of this and more is explained in the Xojo manual. I highly suggest reading it cover to cover if you can get ahold of the old PDF/iBooks version (this version is really far more like a manual).

Here’s what an array of objects looks like in the debugger if you sprinkle in some objects that were never instantiated with new:

My understanding (which works for me but may be flawed) is that there are 3 types of class.

A Primitive (also called Intrinsic or Native) class that is understood by the compiler. These are for example Integer, String, Text etc. For these classes the compiler creates the instance as required and the “New” keyword is not available.

So the way I see it:

Dim i As Integer = 10

is translated by the compiler into

Dim i(0) As Integer i(0) = New Integer i(0) = 10

This explains why you can’t have

Dim i As Integer

And

Dim i() As Integer

declared in the same method. It also explains why Dim is required - all properties are treated as arrays of 0 or more items.

Primitive/Intrinsic/Native properties are smart (or rather the compiler is smart).

Dim i As Integer = 10 Dim j As Integer = i
In this case j & i are both pointing at the same memory space, however changing i or j will cause the compiler to create a new memory space & separate the pointers.

Strings & Text are more interesting.

Dim s As String s = "Hello" s = s + " World"
In this case s is created (New String), s gets a value (a new string is created with that value), a new pointer is s is created for the new value and the original memory becomes free.

Then there are the framework classes provided in this case by Xojo. These are for example Date, Dictionary, Database, Recordset and yes Xojo.Core.Date. These classes need to have an instance created before they are usable.

Lastly there are our classes. These are really the same as the framework classes in their implementation and I only separate them out because we can’t access the super class.

Some classes have shared methods that return an instance of a class for example SpecialFolder

Dim f As FolderItem = SpecialFolder.Documents

New is not required because the method SpecialFolder.Documents returns a folderitem. The same works with Xojo.Core.Date

Using Xojo.Core Dim d As Date = Date.Now
Date.Now returns a New Date object.

Using Xojo.Core Dim d As New Date(2018, 02, 27, TimeZone.Current)
Requires “New” because the constructor is called to create the date & process the arguments and of course the instance of the class needs to be created.