Could really do with a Delphi "WITH" equivalent

BlitzMax Forums/BlitzMax Programming/Could really do with a Delphi "WITH" equivalent

Grey Alien(Posted 2007) [#1]
Sometimes I could really do with an equivalent of the Delphi With statement in Bmax. It doesn't compile to anything, it just saves lots of typing. For example:

MyHumoungousType.SomeOtherPArt.AnotherBit.X = 1
MyHumoungousType.SomeOtherPArt.AnotherBit.Y = 1
MyHumoungousType.SomeOtherPArt.AnotherBit.DoSomething()

Can be written as:
With MyHumoungousType.SomeOtherPArt.AnotherBit do
begin
  x=1
  y=1
  dosomething()
End


Yes I know in BMax I can just do:

MyAlias:TThing = MyHumoungousType.SomeOtherPArt.AnotherBit
MyAlias.x=1
MyAlias.y=1
MyAlias.DoSomething()


But that means the code actually has to create an alias an manipulate it at runtime whereas the Delphi version just change "scope" for convenience at compiletime.


SebHoll(Posted 2007) [#2]
I second this! Would be very useful!


FlameDuck(Posted 2007) [#3]
They're called methods in BlitzMAX.


N(Posted 2007) [#4]
I thought this would be a request for a C# using(){..} sort of deal, but apparently not, so I'm going to say no, your idea is useless.


Grey Alien(Posted 2007) [#5]
They're called methods in BlitzMAX.
Please expain. I know what a method is of course, all my types have them, but how does that solve this situation? You are saying I should wrap that behaviour in a method of MyHumoungousType? Sure, in the example above that's fine, but it's not always that simple and there are times when this is not practical.

Noel: It is SIMILAR to c#'s "Using" but not the same. It just lets you write clearer code and you don't have to type as much. It wasn't "useless" in Delphi, and I miss it :-( sniff. (didn't miss your attitude though when you went AWOL ;-))


grable(Posted 2007) [#6]
I thought this would be a request for a C# using(){..} sort of deal, but apparently not, so I'm going to say no, your idea is useless.

Your kidding right? so what he proposes doesnt explicitly free its scope like using, but useless??
So that would mean its useless in both Delphi and VB too then.

I use this quite a lot in Delphi, its very helpful and saves a lot of typing, i "vote" yes (not that it matters, mark does what he wants anyway)


N(Posted 2007) [#7]
Your kidding right? so what he proposes doesnt explicitly free its scope like using, but useless??
Based on what he's said, no, it's not the same.
I use this quite a lot in Delphi, its very helpful and saves a lot of typing, i "vote" yes (not that it matters, mark does what he wants anyway)
From what I can see, it's making you type more.


Brucey(Posted 2007) [#8]
I vote "no" :-)


... but don't mind me, I'm just waiting for something to compile...


Dreamora(Posted 2007) [#9]
I vote for no as well, it makes it hard to see what object is referenced to execute the method.

it sounds nice in theory but after you have been forced to port VB code, you actually understand HOW BAD it is ...


Brucey(Posted 2007) [#10]
...after you have been forced to port VB code...

Exactly!

It's much better to keep everything clear and obvious, then you can't mistake something for something else - which *will* happen...


CS_TBL(Posted 2007) [#11]
Perhaps not an option for each ide, but blide has this code completion stuff. Having those long lines is a matter of typing one instance name, some dot, selecting a menu item, a dot, selecting a menu item, etc.. The lines would still be long, but not much type work.


dmaz(Posted 2007) [#12]
what about something along the lines of
With MyHumoungousType.SomeOtherPArt.AnotherBit
  .x=1
  .y=1
  for local i:int = 0 to 10
     .dosomething(.x + i)
  next
End With
note the . (even though that can be hard to read it can be better than a bunch of MyHumoungousType.SomeOtherPArt.AnotherBit.x in some cases)

but I would rather have code substitution or even macros...
Alias a = "MyHumoungousType.SomeOtherPArt.AnotherBit"
a.x=1



Grey Alien(Posted 2007) [#13]
haha with these NO votes. If it was in there, you don't HAVE to use it you know - it's like turning off(or on) a violent movie ;-)

dmaz has a point, using . first would indicate that it wasn't an ordinary local x variable. The compiler could error if you used that syntax outside of a with statement.


N(Posted 2007) [#14]
We wouldn't have to use it, but why put it in in the first place if there's so little reason to have it? Honestly, it's a feature that serves very, very little purpose.


Winni(Posted 2007) [#15]
Hm, there were occasions when I was still coding in Borland Pascal when I also found "with" handy. Pascal... Now that was a LONG time ago. ;-)


Grey Alien(Posted 2007) [#16]
Noel: Think of it like bondage, perhaps you've never had it because you are too young (e.g. never programmed Pascal). Well if you had some in the old days you might have grown fond of it and occasionally you miss it now and then. Thus, if it can once again be incorporated into your "style" you'll be pleasantly pleased every so often when the occasion crops up to use it. If you've never known the perhaps lazy and dubious pleasure then, hey no worries, but you gotta let the old dogs have their fun ;-)

DISCLAIMER: That was a joke. I've never had bondage ... I am boring because I like mine vanilla :-)


GW(Posted 2007) [#17]
I think i remember reading that VB takes a performance hit when you use syntax like "MyHumoungousType.SomeOtherPArt.AnotherBit"
and its recommended to pass the rightmost object into a local variable if its going to be referenced a lot.


N(Posted 2007) [#18]
If you've never known the perhaps lazy and dubious pleasure then, hey no worries, but you gotta let the old dogs have their fun ;-)
What are you talking about? No I don't.


Grey Alien(Posted 2007) [#19]
yes I guess that is a good reason to do that. Years ago I wrote a mini-shooter for DOS (in C++) and I made 2 versions. One used arrays only and the other used Types. The Types one was considerably slower.

If speed is not an issue for a particular piece of code then With is still useful :)


CS_TBL(Posted 2007) [#20]
Regarding speed: if 'with' is a part of the (pre-)compiler, then there shouldn't be a speed drop, right? Just a matter of search&replace text.


Grey Alien(Posted 2007) [#21]
well having a pointer/alias to the end object of MyHumoungousType.SomeOtherPArt.AnotherBit is probably quicker than the code at runtime having to check each object referenced by the various parts of MyHumoungousType.SomeOtherPArt.AnotherBit until the end object is reached. Perhaps compiler optimisation means that the code makes a reference to the end object at the start because it knows it'g going to use it again a few times in a row - but I don't know how clever compilers are..


FlameDuck(Posted 2007) [#22]
Well if you had some in the old days you might have grown fond of it and occasionally you miss it now and then.
What? You mean like using Goto, and having to use Let for variable assignments? Don't miss that a bit.

I think i remember reading that VB takes a performance hit
Would you notice though? I mean it's not like VB is geared towards performance in the first place...

The Types one was considerably slower.
Sure. But which of the two would you rather port to Vista today?

if 'with' is a part of the (pre-)compiler, then there shouldn't be a speed drop, right?
Right. The issue is a matter of readability and maintainability.

having a pointer/alias to the end object of MyHumoungousType.SomeOtherPArt.AnotherBit is probably quicker than the code at runtime having to check each object referenced by the various parts of MyHumoungousType.SomeOtherPArt.AnotherBit until the end object is reached.
No. The code at runtime doesn't have to check anything. It knows exactly where to go - it's a completely static reference. Even if it wasn't the last access would still be either in a register, or in the cache so the actual performance penalty would be negligible.

but I don't know how clever compilers are.
Cleverer than the lions share of programmers. Compliers are the most complex piece of software in existence.


Grey Alien(Posted 2007) [#23]
FD:
What? You mean like using Goto, and having to use Let for variable assignments? Don't miss that a bit.
Nor do I miss those, but I miss With - it doesn't have to be all or nothing you know ;-)

Sure. But which of the two would you rather port to Vista today?
Agreed. I changed from BPlus to BMax so I could stop using arrays and non-OOP types.

Cleverer than the lions share of programmers. Compliers are the most complex piece of software in existence.
Guess so. I wouldn't want to write one.


TaskMaster(Posted 2007) [#24]
I also would like "With" "End With" from VB.

We had a thread about this a few months back. It also had the same spattering of yes's and no's.


Grey Alien(Posted 2007) [#25]
Oh I must have missed that one.


Czar Flavius(Posted 2007) [#26]
Why doesn't somebody just make their own pre-processor/parser with all these fancy features that just replaces the text and shoves it into the main compiler? Even I could do that if I had time.

Other things it could do are enumerations, macros/inline functions and (perhaps more tricky) constant arrays.


degac(Posted 2007) [#27]
Yes, something like I made for my tastes
http://www.blitzbasic.com/Community/posts.php?topic=66944#806575


ziggy(Posted 2007) [#28]
Use locals.
With MyType.MyObject.MYOtherObject
.x = 100
.y = 200
.Mytext = "Hello"
.dothis()
end with
could be:
Local Obj:TMyOtherObject = MyType.MyObject.MyOtherObject
Obj.x = 100
Obj.y = 200
obj.Mytext = "Hello"
Obj.DoThis()
You have to type a little more, but it is easier to mantain. I don't see a real 'need' for this implementation.


Chalky(Posted 2007) [#29]
Does this mean that by doing what ziggy did above, changing field values in object "Obj:TMyOtherObject" will also change the corresponding field values in "MyType.MyObject.MyOtherObject"?


ziggy(Posted 2007) [#30]
Yes, of course :D that's how object instancing works.

Just a little example:
Type Obj1
	Field Objfield:Obj2 = New Obj2
End Type
Type Obj2
	Field OtherObject:Obj3 = New Obj3
End Type
Type Obj3
	Field X:Int
	Field Y:Int
	Field T:String
End Type

Global MyInstance:Obj1 = New Obj1

'Test1:
MyInstance.Objfield.OtherObject.X = 100
MyInstance.Objfield.OtherObject.Y = 200
MyInstance.Objfield.OtherObject.T = "Hello!"

Print MyInstance.Objfield.OtherObject.X
Print MyInstance.Objfield.OtherObject.Y
Print MyInstance.Objfield.OtherObject.T

'Test2:
Local MyVar:Obj3 = MyInstance.Objfield.OtherObject
MyVar.T = "Good Bye!"
MyVar.X = -1000
MyVar.Y = -5000

Print MyInstance.Objfield.OtherObject.X
Print MyInstance.Objfield.OtherObject.Y
Print MyInstance.Objfield.OtherObject.T
This is the output you would get:
100
200
Hello!
-1000
-5000
Good Bye!



Chalky(Posted 2007) [#31]
Sorry ziggy - I really didn't know that - I assumed that the Obj instance would be a 'copy of' rather than a 'reference to' the MyType instance! Which is probably why you're the author of BLide, and I'm the author of... er... nothing yet..! :o/


ziggy(Posted 2007) [#32]
@Chalky: You can't copy objects, everytime you assign a value to a type variable, unless you're using the NEW keyword, you're just 'pointing' to an existing instance. that's very handy and has a lot of functionality when working on managed OO programing.

Sometimes you will see that some clases have a 'Create' function. this functions usually perform the NEW action inside their code, and return the newly created object. that's the only 'exception' I can think of.


Grey Alien(Posted 2007) [#33]
Ziggy: I already said that ;-) See the "MyAlias" example! Anyway at least Chalky has learnt something cool (and important!)


TaskMaster(Posted 2007) [#34]
Using the "Alias" technique does take a small performance hit, where as the "With" "End With" does not, because it gets compiled as if it was typed out. It is just for ease of typing and readability. I know many of you think it is harder to read, but when you get used to it, it is actually much easier to read and you don't have huge variable names pushing your code off the right edge of the screen in your IDE.


FlameDuck(Posted 2007) [#35]
I know many of you think it is harder to read, but when you get used to it, it is actually much easier to read
So it's kinda like Brainfuck? Still not seeing how it's a good idea.


Grey Alien(Posted 2007) [#36]
haha that's pretty crazy!


TaskMaster(Posted 2007) [#37]

So it's kinda like Brainfuck? Still not seeing how it's a good idea.



LOL

You're not seeing it because you have never used it. But the truth is, it is a feature that if it was there and you did not want to use it, it would not affect you at all. So, there is not really a reason to be against it.


FlameDuck(Posted 2007) [#38]
You're not seeing it because you have never used it.
Well you're wrong, but you're entitled to your opinion. BTW, the Amiga version of BlitzBasic had this, and I did use it, but like I stated previously, much like the "Let" and "Goto" statements I don't miss them at all.

I suppose the only reason you think it's a good idea is because you've never had to use someone else's source code, and insist on writing everything yourself, come hell or high water.

See? Second guessing other peoples motives is dead easy. Anyone can do it.

But the truth is, it is a feature that if it was there and you did not want to use it, it would not affect you at all.
That's not the turth - that's just something you're making up. Here is one way it would effect me. Lets make an example of someone here, like Grey Alien who thinks this is such a good idea, who contributes quite a bit of useful source code to the community, never mind the framework he's selling. Every time I wanted to use some of his source code, this would have a profound effect on me.

The only way this would not effect me is if I decided that I wanted to reinvent the wheel each time I wanted to do something, rather than standing on the shoulders of proverbial giants.

Anything that makes source code more difficult to read or understand, in a shared source environment is a bad thing.


Chroma(Posted 2007) [#39]
Nm...Flameduck is above the law around here anyhow.


TaskMaster(Posted 2007) [#40]
I don't think he is above the law. His opinion counts like any other. He is quipping my generalizations and he makes a good point.

Sure, it is possible the With - End With could be used in a manner that made it ugly to read. But, the language as it is now could also be done ugly.

Just because it has the possibility to be used poorly doesn't mean it always will, just as the features of the language that could be used now to do poor code are there.

Truthfully, which is easier to read:



or




Czar Flavius(Posted 2007) [#41]
You know by the time people have finished arguing about all these syntax preferences on all these forums you could have simply added functionality to the editor to automatically convert code between the two instantly. I mean that's what it would have to do anyway, if only in one direction. Why argue so much about it when it's so easy to accomodate both?

And FlameDuck you made a valid opinion but not an arguement. Goto was bad yes and let was useless. But their shortcomings don't affect the shortcomings of other features. You can make for loops using while loops. So if they removed for loops, what's to stop you from saying "I don't miss for loops one bit, ergo they are bad and I do not think they should be reintroduced"? You are entitled to that opinion, that you prefere not to use with, but it's no logical arguement why they should not be reintroduced, as in the case of with it doesn't allow the programmer to do anything dangerous, just express existing code differently.


CS_TBL(Posted 2007) [#42]
Both are not completely ideal, if you ask me :P In fact, is this realistic code in the first place?


tonyg(Posted 2007) [#43]
Might be a seperate issue but isn't
MyType.MyObject.MYOtherObject.x = 100 

considered poor OOP? I am guessing you shouldn't be accessing 'x' directly like that.


Grey Alien(Posted 2007) [#44]
re: poor oop, yes that's all very good in theory but when it comes down to real life coding or if you wanna make a quick test thing, sometimes having WITH would be useful for sure :-)


tonyg(Posted 2007) [#45]
It seems odd to add something to assist in what is agreed as poor coding though. If you had seperate set methods and/or (although probably also poor coding) a quickset method it'd be just as quick wouldn't it?


TaskMaster(Posted 2007) [#46]
I would not say just as quick. And as for the poor coding, poor coding is relative. When game programming and trying to eek every bit of performance, those Get's and Set's actually are just a tad bit slower.

Method SetX(Value:Int)
X=Value
End Method

SomeObject.SetX(4)

is slower than

SomeObject.X=4

since, it is setting a variable rather than calling a function and setting a variable.

I really find it strange that there are people so vehemently against it. I can understand someone not needing it or saying it isn't necessary, but to say that you don't want it in there seems odd to me.

Anyway, I can live without it, so if so many people are opposed, it is no big deal.


ziggy(Posted 2007) [#47]
I don't tink having with is a good idea, not only becouse it makes code more difficult to read, but also becouse it could introduce scope 'visual' confusion

Example:
SuperStrict
For Local X:int = 0 to 10
   Local I:Int = 8
   Print I
Next
Print I
This code generates a compilation bug, becouse the I variable outside the For block is out of scope (remember block-scoping on SuperStrict)

SuperStrict
With Somethig.MethodReturiningType1.FieldType
   .Property = "Hello"
   Local I:Int = 8
   Print I
End With
Print I


this code would compile, confusing the real scope of the I variable. I mean, it is a code block not really scope-oriented so it will not follow any other code block rules on BlitzMax, and I think this is not a good idea. Otherwise, making this with block a real scope will be absurd as it is not controlling any program flow or logic.


Dreamora(Posted 2007) [#48]
there is no confusion.
Within a With you could not declare anything, the compiler would be meant to bomb out.
With is to access and assign, not define.


dmaz(Posted 2007) [#49]
the best example of why it would be nice it Taskmaster's. I have run across that need/want in my stuff many times.

And NO, it's not bad oop. sets and gets do not necessarily make for good oop. in any case, using sets and gets here just make it more needed.

Ziggy's local scope (IMO) is really the only real good reason against it

that's why I would vote for a real alias command or macros.


ziggy(Posted 2007) [#50]
@Dreamora: Well, in some languages the with blocks allow the creation of variables and all kind of strange things. I'm thinking on Visual Basic 6...


tonyg(Posted 2007) [#51]
And NO, it's not bad oop.

I'm happy to bow down to somebody with more OO expertise. However, I was certain it was considered bad form to expose your attributes. I would also use Ziggy's local scope but probably with Set methods as well.


dmaz(Posted 2007) [#52]
yeah, you have to allow all code... otherwise I agree it is worthless. the place it is need most IS when dealing with code I think... not just initialization.

while I would agree this example of taskmasters is bad oop (because you should not just blindly set another objects variables and you could do this much cleaner with a nice oop approach) it shows why you want it... long equations.
MyType.MyObject.MYOtherObject.Velocity = Sqr(MyType.MyObject.MYOtherObject.x*MyType.MyObject.MYOtherObject.x+MyType.MyObject.MYOtherObject.y*MyType.MyObject.MYOtherObject.y)


Grey Alien(Posted 2007) [#53]
Yep for sure!

I'll say again that whereas there may be lots of "OOP Best practices", and ignoring the fact that they vary anyway depending on who is saying them, sometimes in "real life" programming when you are in a hurry or want to test something or any number of reasons, you need to "bend the rules" a bit as far as best practices go - and in situations like that WITH would come in handy...

Basically I'm a big fan of getting stuff DONE, sure best practices are useful and if you can stay close to them, great, but at the end of the day I'm programming for a RESULT which is a finished game.


dmaz(Posted 2007) [#54]
However, I was certain it was considered bad form to expose your attributes.

I think that completely depends on the language your using and who the market is that will be using your objects.

the idea that you don't expose your variables comes long ago from the information hiding school of thought and can be very useful if that what you want/need. if you are creating an interface for sale then I would want to control most manipulation of those variables and even hide the ones I don't want people to see. If I'm making a particle engine for a game, I want direct access to whatever I deem necessary . that is fine as long as I'm consistent with my design while not introducing any confusion to me or my coworkers.

many languages have embraced the "do not expose" by adding true properties and such. unfortunately, max does not have that capability built in yet.

until max gets those, I still like plain old assignment for much of my coding!


ziggy(Posted 2007) [#55]
The real problem here is not to have 'private' 'public' and 'friend' properties for methods, functions and fields in clases. In that scenario it could be a good practicle to not modify directly atributes unless you know exactly what side effects you will get. In the ideal world, with this kind of private, public and friend modifiers, you could just modify whatever the object exposes, becouse if it is exposed, modifications are allowed (or object is bad designed).


dmaz(Posted 2007) [#56]
but now we are getting off topic here... even in a great oop design there are still times when a "with" or "alias" comes in handy.

I think this is a good example for "Alias"

setvalue(typex(mylist.myobject).getotherobject().getvaluex() * typex(mylist.myobject).getotherobject().getvaluey()

Alias a = "typex(mylist.myobject).getotherobject()"
setvalue(a.getvaluex() * a.getvaluey())
setothervalue(a.getvaluex() / a.getvaluey())
...


[edit]changed objectx() to typex()


Grey Alien(Posted 2007) [#57]
Yeah I'd have liked Private and Public a long time ago, oh well.