Could really do with a Delphi "WITH" equivalent
BlitzMax Forums/BlitzMax Programming/Could really do with a Delphi "WITH" equivalent
| ||
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. |
| ||
I second this! Would be very useful! |
| ||
They're called methods in BlitzMAX. |
| ||
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. |
| ||
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 ;-)) |
| ||
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) |
| ||
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. |
| ||
I vote "no" :-) ... but don't mind me, I'm just waiting for something to compile... |
| ||
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 ... |
| ||
...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... |
| ||
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. |
| ||
what about something along the lines ofWith MyHumoungousType.SomeOtherPArt.AnotherBit .x=1 .y=1 for local i:int = 0 to 10 .dosomething(.x + i) next End Withnote 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 |
| ||
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. |
| ||
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. |
| ||
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. ;-) |
| ||
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 :-) |
| ||
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. |
| ||
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. |
| ||
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 :) |
| ||
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. |
| ||
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.. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
Oh I must have missed that one. |
| ||
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. |
| ||
Yes, something like I made for my tastes http://www.blitzbasic.com/Community/posts.php?topic=66944#806575 |
| ||
Use locals.With MyType.MyObject.MYOtherObject .x = 100 .y = 200 .Mytext = "Hello" .dothis() end withcould 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. |
| ||
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"? |
| ||
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.TThis is the output you would get: 100 200 Hello! -1000 -5000 Good Bye! |
| ||
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/ |
| ||
@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. |
| ||
Ziggy: I already said that ;-) See the "MyAlias" example! Anyway at least Chalky has learnt something cool (and important!) |
| ||
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. |
| ||
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. |
| ||
haha that's pretty crazy! |
| ||
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. |
| ||
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. |
| ||
Nm...Flameduck is above the law around here anyhow. |
| ||
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 |
| ||
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. |
| ||
Both are not completely ideal, if you ask me :P In fact, is this realistic code in the first place? |
| ||
Might be a seperate issue but isn'tMyType.MyObject.MYOtherObject.x = 100 considered poor OOP? I am guessing you shouldn't be accessing 'x' directly like that. |
| ||
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 :-) |
| ||
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? |
| ||
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. |
| ||
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 IThis 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. |
| ||
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. |
| ||
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. |
| ||
@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... |
| ||
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. |
| ||
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) |
| ||
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. |
| ||
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! |
| ||
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). |
| ||
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() |
| ||
Yeah I'd have liked Private and Public a long time ago, oh well. |