What about to add a new command named Delete?

BlitzMax Forums/BlitzMax Programming/What about to add a new command named Delete?

Fabian.(Posted 2005) [#1]
Here's an extract from Blitz runtime doc:
Keyword Delete

Description  Reserved for future expansion.

Example      Rem
             Reserved for future expansions.
             End Rem

Future's starting here and now!

So I'd suggest to add a new command named Delete which sets all vars pointing to an object to Null, calls the Delete method inside the object and releases the object's memory.
For example:
Strict

Local obj1:class = New class
Local obj2:class = obj1

If obj1 = Null
  Print "obj1 = Null" 'This line is not printed
EndIf
If obj2 = Null
  Print "obj2 = Null" 'This line is not printed
EndIf

Delete obj1 'delete this object and set obj1 and obj2 to Null.

If obj1 = Null
  Print "obj1 = Null" 'This line is printed
EndIf
If obj2 = Null
  Print "obj2 = Null" 'This line is printed
EndIf

Type class
EndType

I know the BMX reference counting system stores only how many vars are pointing to an object and not the addresses of all of them.
But I think with some tricks you still can add this command:
Each BMX object has a hidden field used by GC which stores how many vars are pointing to it; if this field reaches 0 the object is removed by GC.
I guess this field is a system integer (32bit), but I think there are never 2^32 = 4,294,967,296 vars pointing to it, so I suggest to use the last bit to store a special boolean value storing whether the object has already removed or is still used.
So Delete has only two things to do:
1.: Call Method Delete() inside the object.
2.: Set the special 'object is removed bit' to true.
But than there's the question "When is the object's memory released?"
Well; each time accessing an object var the program checks whether the object's special bit is set or not; if true it'll set this var to Null and decrements the object's hidden field; so the object will be found by GC as soon the hidden field reaches 0 and it will delete it like each other object, -well, not really:
If the object's special bit is set to true the GC doesn't call the object's Delete() method because the Delete command already called it.
Here's another example:
Strict

Local obj1:class = New class 'The object's hidden field is now set to 00000000 00000000 00000000 00000001 because there's one var pointing to it (obj1).
Local obj2:class = obj1 'Now it's set to 00000000 00000000 00000000 00000010 because there're two vars pointing to it (obj1 and obj2).

If obj1 = Null
  Print "obj1 = Null" 'This line is not printed
EndIf
If obj2 = Null
  Print "obj2 = Null" 'This line is not printed
EndIf

Delete obj1 'Now the hidden field is set to 10000000 00000000 00000000 00000010 because there're two vars pointing to it, but the object is already removed.
            'The two object vars are not really set to Null because the Delete command doesn't know the addresses of them.



                  'Before any code's executed the program checks whether the object's special bit's set or not
If obj1 = Null    'It'll notice that it's set to true so it'll set obj1 to Null and decrements the object's hidden field
                  'The hidden field is now 10000000 00000000 00000000 00000001; obj1 is Null, so (obj1 = Null) is true and the If block is executed

  Print "obj1 = Null" 'This line is printed
EndIf

                  'Before any code's executed the program checks whether the object's special bit's set or not
If obj2 = Null    'It'll notice that it's set to true so it'll set obj1 to Null and decrements the object's hidden field
                  'The hidden field is now 10000000 00000000 00000000 00000000; obj2 is Null, so (obj2 = Null) is true and the If block is executed
                  'But here the GC notices this object with no var pointing to it and releases the object's memory.

  Print "obj2 = Null" 'This line is printed
EndIf

Type class
EndType




___________________________________________
So, how do you think about it?
Any comments?


MrCredo(Posted 2005) [#2]
i posted same requests - but i gived up...
here is my old topic

http://www.blitzbasic.com/Community/posts.php?topic=50880#568839


Robert(Posted 2005) [#3]
It seems that some people are still finding hard to let the old ways die ;)

Just to pick one reason why I think the suggestion is a bad idea, it means that an object could unexpectedly disappear in one part of the code, whilst code in another part is working with it.

Why do you still want a Delete() method? If it is to perform some essential cleanup (eg. closing a file) then it has to be done in some other method which is explicitly called. The Garbage Collector's timing is not predictable.


Fabian.(Posted 2005) [#4]
I want to have a Delete command because.... I want to delete an object and to be sure that it's really deleted.
Sometimes I know that an object is invalid and must be delete otherwise it'll cause runtime errors.

Another question:
Why do you want to have no Delete command?
To have more commands is better than to have less commands.


Ferminho(Posted 2005) [#5]
To have more commands is better than to have less commands.


as long as the new ones don't decrease old ones functionality

I'm not very sure how can an unreferenced-but-not-deleted-yet object can cause runtime errors. Could you give an example?


N(Posted 2005) [#6]
You don't need Delete to know your object is freed if you're a good programmer. Really, it's as simple as that.


Koriolis(Posted 2005) [#7]
Ever heard of weak references?
If not, you're underinformed. Really, that's as simple as that.


N(Posted 2005) [#8]
Ever heard of week references?


7-day references? Nope, never heard of them.


Robert(Posted 2005) [#9]
I want to have a Delete command because.... I want to delete an object and to be sure that it's really deleted. Sometimes I know that an object is invalid and must be delete otherwise it'll cause runtime errors.


I don't understand what you mean by "object is invalid and must be delete".

Ever heard of weak references?


What does this have to do with weak references?


Fabian.(Posted 2005) [#10]
Ferminho:
as long as the new ones don't decrease old ones functionality
I'm sure they don't.
If you don't use Delete, everything's like before.

Ferminho:
I'm not very sure how can an unreferenced-but-not-deleted-yet object can cause runtime errors. Could you give an example?
I didn't say an unreferenced-but-not-deleted-yet object, I said an invalid object. For example by writing a GUI module a window object whose window has closed:
...

Type TWindow
  Field handle

  ...

  Methdo Remove() 'After user called this method object still exist, but it's invalid
    CloseHandle handle
    ...

    Extern "Win32"
      Function CloseHandle( handle )
    EndExtern
  EndMethod
EndType
What if user calls a method like SetSize after calling delete?
The function would throw a runtime error.


Warren(Posted 2005) [#11]
If you can't trust your language, then you really shouldn't be using it. If BlitzMax's garbage collector isn't working - that's a bug. So trust in the fact that once you set that variable to null, whatever it was pointing to will be collected.

You shouldn't need to have the old school, low level control that you had in the past. There's no need.

'After user called this method object still exist, but it's invalid

Correct. So set it to null like you're supposed to.


Koriolis(Posted 2005) [#12]
What does this have to do with weak references?
Not all, but lot of things. Weak references allow to point to objects that *can* be reclaimed by the system (because such references don't account for the "liveness" of the object), and when they are the references are simply nulled out. Still don't see any connection with the feature request?
Now I wouldn't call the fact that *every* object can be deleted at any time (as proposed) a very smart thing, but if some objects were specifically tagged as deletable (say by deriving from a special class), then you could easily find uses for this while still not compromising the security of your program (given than for any other class you'd rest assured that instances won't be suddenly deleted).
Or why not, precisely implement weak references, which would probably fit the original poster's need.
But I think the "special class" solution would be easier to implement efficiently, in particular because it wouldn't affect the final code for any class that doesn't inherit from such a special class (so no performance hit if you don't use it).

There's no need.
There is probably *little* need, that's a difference. But I admit I never really needed it myself (but again I mostly program in C++ where I manage the memory myself so that's hardly a proof of unusefulness in a garbage collected language).
And more to the point, in the case of the original poster it seems the feature really is unneeded. But I just don't believe someone can throw things like "you don't need it or you're a dumbass stupid programmer". That looks like plain arrogant to me. Would I have seen the least constructive argument, that would have been another story.


Fabian.(Posted 2005) [#13]
WarrenM:
Correct. So set it to null like you're supposed to.
I can't set an object to Null. I only can set variables to Null, but I don't know these variables.

WarrenM:
You shouldn't need to have the old school, low level control that you had in the past. There's no need.
Finding all variables pointing to an object and setting them to Null is low level control, just using a Delete command is much better.

In this context there're 3 types of languages:
- Languages using no GC: Everything must be deleted manually. This is not good, you've to delete each object yourself.
- Languages using a GC without Delete command: This is much better you don't have to delete each object, just forget about it. But what if an object is invalid and/or it must be removed?
- Languages using a GC and a Delete command: This is the best you've all advantages of the language using a GC without Delete comand and you can delete objects which are invalid and/or must be deleted.
To have more commands is better than to have less commands.



N(Posted 2005) [#14]
I can't set an object to Null. I only can set variables to Null, but I don't know this variables.


You wrote the code, right? How can you not know where it is?

The problem here is that you clearly don't understand how to work in a managed environment. You want something nullified on-demand, implement a Dispose method/class.

If you're careful and do not do something stupid like add the type to a thousand lists and forget about it you won't have trouble.

Instead of taking the easy way out and requesting something like this, you should probably go look at your code and fix it.


gman(Posted 2005) [#15]
Delete() function or not, the programmer always has the ability to hang themselves. Delete() at best can set every variable referencing that instance to Null for the programmer, but it cannot make the actual variables disappear. without the programmer checking for Null in all routines that could use a reference variable to that type instance after its been Delete()d, an error will occur anyway. so, it can be said that its good programming practice to always check for an instance pointer being Null before using it if there is any chance that it can be Null. to extend this for the TWindow example given, add a Method called IsValid() to TWindow that will return false if handle is 0. so now your check for Null becomes something like:
If Not MyWindow Or Not MyWindow.IsValid() Then RuntimeError "Oops"

chances are that if the programmer is trying to use a variable that is no longer valid in some way, then they probably want to know about it anyway since it is more than likely a bug in program flow.


Fabian.(Posted 2005) [#16]
Noodle Cower:
You wrote the code, right? How can you not know where it is?
What about writing modules? I'm writing the object and the module's user's writing the vars pointing to it.

To have more commands is better than to have less commands.

But I'm giving up now, not because I'm wrong, because I've not enough time to answer all posts.


Warren(Posted 2005) [#17]
But I'm giving up now, not because I'm wrong, because I've not enough time to answer all posts.

Sure, sure.


Ferminho(Posted 2005) [#18]
Excuse me for quoting you again, Fabian

as long as the new ones don't decrease old ones functionality

I'm sure they don't.
If you don't use Delete, everything's like before.


I said that because the system you suggested used extra resources and surely a more complex GC that has to do more checks, etc - that means more processing time.

Of course, maybe the overall result could be good; I'm not saying that. Just said that
To have more commands is better than to have less commands

is not necessarily true.

Thanks for the example, I understood what you meant, but I still think that your library user is a Bmax user, so he should know how GC works - in your library docs you should specify that after calling Remove and object is no longer 'valid'... or do that Remove inside the Delete method and rely on the user dereferencing your object... or keep track within the object if its valid or not - just check if Handle is null... etc.

I don't try to destroy your idea, it's just I think that a Bmax lib user has to think Bmax - not C++ or any other language. So you shouldn't worry too much about that.

Nevertheless, *maybe* if done properly could prove to be an interesting addition.


Hotcakes(Posted 2005) [#19]
What about writing modules? I'm writing the object and the module's user's writing the vars pointing to it.

It's no different to those same people using the official BRL modules without the need for Delete. If you have something you want to do, I suggest searching BRL's modules and finding an implementation that works for you. Then rip it shamelessly.