I'm skimming John Sadd's OE 4GL handlebook "expert series" (http://www.psdn.com/library/entry.jspa?categoryID=239&externalID=474) and came across this reference on page 14-24:
The traditional Progress programming technique of using SHARED variables
Shared variables are a technology fraught with dangers and has long since been obsoleted by other, better technologies in the ABL.
Why are they still being discussed in any way other than for historical reference?
There are almost certainly two or three factors involved in things like this persisting in the documentation.
One is that a lot of the documentation was written a long time ago when awareness of some best practice standards was not nearly as widely understood as it is today ... not that they are universally understood even now. For any given release, there is substantial work required to update and add new documentation to cover new features, so it is not surprising that there isn't a lot of resources available for going back to material that hasn't changed to see if it can be improved. This is unfortunate in many ways because the code examples in particular often convey approaches which are not best practice, which certainly doesn't help people who are learning the language.
Another factor is that a set of best practice standards is not well established and universally agreed upon. If there was a Strunk and White for ABL, there would be a reference point, but that doesn't exist. To you and I and a bunch of other people, shared variables are anathema, but there are still a lot of folks out there who think they are perfectly OK ... after all, it a "traditional Progress programming technique".
And, another factor I think is that PSC seems to be very conscious of the fact that there are a lot of people who are not out at the leading edge, especially if they are sitting on million line bodies of existing code. Since they want to incorporate those people, there is a pattern of saying that one can use OO or not use OO, one can use PDS or one can not use PDS, etc. They don't want to make people feel like they have to change what they are doing in order to move to the latest release. I don't think this pitch is quite clearly focused, however. To be sure, it should be clear to people that they can move to the latest release and it just works. This has long been one of PSC's great strengths and the failure of people to keep moving forward has certainly turned into one of PSC's biggest PITAs. And, clearly they should be provided with guidance on how to make old code and new code work together, something which I think is a bit weak in the current documentation. But, there also should be good guidance in best practices with new features (and what not to use in old features). My impression of the people doing the development on the OO stuff is that they actually have a pretty clear vision, even a bit religious at times. But, this doesn't seem to be making it out in to the examples.
One is that a lot of the documentation was written a
long time ago when awareness of some best practice
standards was not nearly as widely understood as it
is today ... not that they are universally understood
even now. For any given release, there is
substantial work required to update and add new
documentation to cover new features, so it is not
surprising that there isn't a lot of resources
available for going back to material that hasn't
changed to see if it can be improved.
I can go with that a few releases, but sooner or later the docs need to be gone over, updated, and cleaned up.
Another factor is that a set of best practice
standards is not well established and universally
agreed upon.
I personally don't get hung up and worry about "best practice" - there's lots different ways to skin a cat, depending on the variations of what a coder's trying to accomplish, personal quirks, etc. There should be a number of different examples showing different ways to accomplish a given goal, with a description of each one's strengths and shortcomings.
However - something as outdated as shared variables should be termed "obsolete", "legacy" or something to convey that it's an old way of doing thins. Certainly not "traditional." If going-way-back developers want to use them fine, but they should be moving to other technologies. One doesn't want new developers getting the idea that SVs are anything other than carry-overs from much prior versions of the language.
To you and I and a bunch of other people, shared
variables are anathema, but there are still a lot of
folks out there who think they are perfectly OK ...
after all, it is a "traditional Progress programming
technique".
And so is using include files in lieu of .p's and super procedures, defining multiple static queries as opposed to using dynamic query specifications and the like.
"Traditional" ways of doing things need to be replaced when better ways of doing things come along.
And, another factor I think is that PSC seems to be
very conscious of the fact that there are a lot of
people who are not out at the leading edge,
especially if they are sitting on million line bodies
of existing code.
They may not be running fully-leading-edge code, but if they're running 10.1 systems, the runtime is leading edge, which means they can use newer, better ways of doing thing. Users should be encouraged to move to more recent, better ways of doing things rather than perpetuating older, obsolete techniques. And the best way to do that is to (a) make it easy for them to do so in the language, and (b) update the docs to point them in that direction.
To be sure, it should be clear to people that
they can move to the latest release and it
just works. This has long been one of PSC's
great strengths and the failure of people to
keep moving forward has certainly turned into
one of PSC's biggest PITAs.
If it was easier for legacy developers to move things forward, maybe they would.
And, clearly they should be provided with guidance
on how to make old code and new code work together,
something which I think is a bit weak in the current
documentation.
Agreed.
But, there also should be good guidance in best
practices with new features (and what not to use
in old features).
I'd like to see better guidance in how to easily do things now that used to be rather difficult to accomplish in prior versions.
But, this doesn't seem to be making it out in to the examples.
Which is unfortunate.
Tim Kuehn
I can go with that a few releases, but sooner or later the docs need to be
gone over, updated, and cleaned up.
I agree with you that it is an important goal, but I also recognize that it is not an easy one. If someone on the outside were to go through and make a list of all the bad examples, then it might be manageable to respond to those, but fixing them internally means that someone has to do the scan who would recognize a bad example.
There should be a number of different examples showing different ways to
accomplish a given goal, with a description of each one's strengths and
shortcomings.
I'm always a fan of showing more options and explaining why one would make choices, but the specific example this thread started with is definitely a best practices issue ... well, or a worst practices issue.
Wouldn't it be interesting to have a new, separate best practices manual? That might lessen the need to fix all the old stuff.
And so is using include files in lieu of .p's and super procedures
Oh, you mean like all of the OERA code examples?
"Traditional" ways of doing things need to be replaced when better ways of
doing things come along.
Like having OERA examples using .cls?
And the best way to do that is to (a) make it easy for them to do so in the
language, and (b) update the docs to point them in that direction.
Which I think includes guidance on how to use .cls in the context of a .p application, which is why I did the whitepaper and code example on how to use a .cls file to replace a session superprocedure which is found at http://www.cintegrity.com/downloads.html ... the doc is full of references about how SPs are like objects, but is missing this piece on how to actually do it.
If it was easier for legacy developers to move things forward, maybe they would.
This, to me, is one of the very interesting challenges facing PSC.
Continuing the "Shared" thread - why is the "shared" concept being carried forward with new language elements? For instance, DEFINE [NEW ] DATASET ... and the like?
This is one place where PSC should not be consistent with other language elements in the ABL.
So maybe we should be documenting "worst practices" instead of "best practices"? Just joking, but it is something we've considered.
The problem is, as long as we do support something, we want to support it consistently. And you think we hear it about continuing old conventions, you should hear what happens when we don't! Some people report it as a critical bug even if we didn't intend to do it!
Of course, that's one of the balancing points of being in the software game. The solution that's been in my head for awhile is to let users indicate what things in the syntax they don't want to support, sort of a reverse reserved keyword kind of thing.
So maybe we should be documenting "worst practices"
instead of "best practices"?
I would submit that at the very least archaic outdated methods should not be discussed as "traditional" but "deprecated" or "when nothing better was available".
>Just joking, but it is
>something we've considered.
Not in the 10.1 docs though.
The problem is, as long as we do support something,
we want to support it consistently. And you think we
hear it about continuing old conventions, you should
hear what happens when we don't! Some people report
it as a critical bug even if we didn't intend to do
it!
I think shared anything should go away as a dangerous, outdated technique. I can understand existing "shared" support remaining in the language, but adding support for shared "stuff" in new technology like PDS???
Other methods (like "choose") have been deprecated by PSC, but nothing's been suggested to replace it.
So it's not like PSC hasn't marked things as deprecated before.
I agree with you guys on shared variables.
But in a broader sense, isn't it a good thing Progress is a multi-paradigm language ?
Take for example, PROMPT-FOR which as I understand is also being deprecated. I'd still like to write REPEAT: PROMPT-FOR, script like programs if I wanted to.
Being able to use 'deprecated' langauge elements is one thing. But obsolete if not dangerous techniques shouldn't be listed as examples of how to work with the product's current technology when there are better and safer ways to accomplish the same thing.
While I am a great fan of consistency ... a scan of PEG history for the word orthogonal will yield a number of posts on this point ... I think there is an opportunity as the language evolves to find approprate places to move forward.
We all understand why PSC has chosen to support historical syntax in later versions. That policy has its cost, of course, and I'm not sure that it has entirely fulfilled its purpose, as witness the large number of sites (vast majority?) who remain running on older releases. Nevertheless, we understand.
But, when moving into new areas, like OO, there is no need to support historical code because there is no historical code. And, there is an opportunity to provide guidance toward good usage. There is no reason to allow for a shared object, especially if you provide guidance for what it is that one does to gain the effect of "shared" without the use of shared. Not only does that provide the programmer new to this area with guidance in the right usage pattern, but it will help to educate him or her on how he or she might rework older code.
Supporting a structure because one knows that it is in wide use doesn't mean that one can't also designate it as deprecated. PSC has certainly done that with some language elements which were (and are) in wide use and I see no reason why shared shouldn't be added to that list.
It is important to continue to support existing code, at least for a significant period.
That does not make it a virtue to guide people toward usage which we now recognize as undesireable.
I know that PSC feels it necessary to "comfort" people who are used to procedural code that it is still a valid paradigm, but that doesn't mean that every verb or modifier needs to be called good.
Of course, that's one of the balancing points of
being in the software game. The solution that's been
in my head for awhile is to let users indicate what
things in the syntax they don't want to support, sort
of a reverse reserved keyword kind of thing.
I think developers would like a more expressive grammar for new code constructs like the OO-environment instead of disabling keywords. The new cls-extension was a great possibility to transparantly link cls-sources to a new compiler... I can imagine a file extension that doesn't allow GUI-statements other than tracing.
So when is the compiler going to start throwing warnings for deprecated features?
Myself, I think having the compiler throw non-fatal warnings would be a bad idea. It would cause people with some code bases to avoid upgrading and it would break a lot of automated build processes. The compiler should be silent unless there is something fatal or a good reason to expect that the code will not perform as intended (like moving colon position).
We have ProLint for telling us things like the use of deprecated features. Then one gets the warning when one is ready to do something about it.
What would really be clever would be for PSC to invest in ProRefactor so that it provided a set of rewrite rules for deprecated features.
The compiler already throws non-fatal warnings. That's nothing new. Nor is the idea that compilers, in general, should do so. IMHO Progress 4GL is fairly weak in this regard -- it doesn't warn about lots of things that it ought to warn about and that just encourages a lot of bad practices.
I don't see a problem with adding more and I don't believe that it would break any automated processes. If it does then those processes deserve to break.
I doubt that any such feature would slow down upgrade and adoption curves. It might be used as a facile excuse but it isn't the real reason.
I agree that ProRefactor's capablities should be offered -- it's silly to deprecate a feature without an alternative reccomendation. And in a lot of cases it should be generally possible to largely automate many common code conversion issues.
Myself, I think having the compiler throw non-fatal
warnings would be a bad idea. It would cause people
with some code bases to avoid upgrading and it would
break a lot of automated build processes. The
compiler should be silent unless there is something
fatal or a good reason to expect that the code will
not perform as intended (like moving colon
position).
In other environments you can tell the compiler to suppress certain warnings. And .Net has a nifty feature: the ObsoleteAttribute. You can mark your own methods as "obsolete" which either results in a compiler warning or error. And you can pass in a custom message, like what to use instead. C# example:
public class Person
{
public string GetName()
{
...
}
}
Any code that uses "person.GetName()" will get a compiler warning "Use Name instead".
My point is that we have a perfectly good tool, ProLint to do this kind of warning. If one is working on an existing module to make some changes, the nature of the change or timeframe may or may not permit cleaning up obselete items. If the time does permit, one runs it through ProLint and deals with the report. If time does not permit, one doesn't need the compile nagging 20 times when doing 20 compiles.
ProLint is wonderful but it covers a different set of problems. And not every "we" "already has it". In fact, unfortunate as it may be, most Progress users have never even heard of it.
There is plenty of room for both solutions.
If Progress is going to deprecate features (and I heartily support the idea that they should do so) then they ought to go to the trouble of updating the documentation and having the compiler remind people.
In fact, unfortunate as it may be, most Progress users have never even
heard of it.
A problem which should be fixed!
My point, though, is that one can need to compile a module many times in the process of working on it. As things are now, there is no circumstance that I have encountered where I get messages except when there is something I have to fix ... the program might run, but not as intended, e.g., the colon move. Were this "feature" added, I would have to read through these nag messages with every compile to make sure that there were no real errors lurking. What a PITA. If anything, it should be a separate process to be used when wanted or, at the least, a flag whose default is the current behavior.
Transaction warnings are pretty common and you don't "have" to fix them any more than you "have" to fix a shared variable.
As it stands there is no incentive for anyone to change bad habits -- and there are plenty of bad habits that need changing.
I think that nag messages are a long overdue idea and I hope to see some soon. I'm not sure why such an prolific proponent of best practices as yourself would want to coddle miscreants but I suppose that it would be reasonable for PSC to include an option to shut off such warnings. But the default should be "full nagging".
Without nag messages everyone gets to profess surprise that such and such a feature is deprecated when we have all known forever that it was a bad thing. If some nags were to (finally) be inserted in OE10 we might begin to see some general recognition that, oh say shared variables, are a bad idea by the time version 13 rolls out.
In fact, unfortunate as it may be, most Progress
users have never even
heard of it.
A problem which should be fixed!
So you probably own a car and a driver's license, but you still take a cab, since you don't want to be disturbed by the "fasten your seatbelt" warning in your own car.... I don't see why you need another tool that uses a different parser when the native Progress compiler has the entire and correct context.
I wonder why we have to persuade you all the time, I would rather persuade PSC...
Based on my experience with OEA, the parser behind ProLint is better than the one PSC is using ... although they really aren't trying to do the same thing.
But, I'm not arguing that PSC shouldn't enhance their tool set, I'm just arguing that I don't want mandatory nagging in the compiler. Scanning for deprecated usage is exactly the same kind of scanning for other things one doesn't want in one's code that ProLint was designed for. It gets used when one is ready, willing, and able to fix things that are undesireable without getting in the way of day to day development. PSC should license the technology and make it available to everyone.
This is a great discussion. But I would just like to mention a few things:
1) We are listening. Your observations regarding the ABL documentation, the examples therein, best practices using the ABL, new ABL features vs. older 4GL practices, etc, will definitely be looked at by the relevant PSC people. As Niel indicated and as you no doubt appreciate, it is always difficult to strike the right balance between supporting the existing base and encouraging the adoption of new features. So this feedback is very welcome.
2) We would certainly like to encourage honest feedback and robust debate on this forum. But let's foster and maintain a professional and friendly tone. A few personal snips here and few loose words there can not only degenerate the discussion but it can discourage others from joining in and offering their thoughts... and we would like to hear from everybody in the community.
Thanks.
Phil
Re Compiler warnings...
I have included the following enhancement in the list of candidates for the next feature release after 10.1B (as I said in another posting, the release has not been signed off so I cannot give you more details yet):
Compiler enhancement to allow ABL developers to list what the compiler should be generating warnings about. (Could be thought somehow as the 'reverse' to the existing keyword forget list). - ERS 1016 -
I almost suggested that! We could refer to it as the keywordtrytoforget list
Of course, couldn't one simply put the despised keywords into the forget list and get error messages now?
That would have the unfortunate effect of turning a warning into an error.
I think that Sal is proposing a reasonable compromise. If you don't want to be bothered by the list then you can simply delete it. OTOH if you don't think that the list is long enough you can add things to it.
To add to Sal's thought:
1) There should be a default list that contains all keywords which PSC has deprecated (EDITING, PUT SCREEN etc...)
2) There should be a startup parameter which points to an alternate list. In this way people compiling code bases for different purposes (GUI, ChUI, Batch, Triggers etc) can tailor the relevant warnings.
3) It would be very nice if the warning message itself were in the file and could be edited.
I can just imagine some of the warning messages that you might come up with!
Noted!
Boy, you step out of the room for a minute (well, to Greece and back and various other places) and all hell breaks loose. Now I know how all those other guys feel about being quoted out of context...Except, of course, they were guilty...
In my own defense, if this is necessary, there is an entire sub-section earlier in the book entitled "Why you generally shouldn't use shared variables", which tries to balance the "traditional" (if you'll pardon the expression) use of shared variables and more modern ABL programming techniques. If it isn't put even more strongly, it's because the book was trying to strike a balance between material for those who may be maintaining older applications and those trying to create new ones. There are a number of places in the book where I try to describe outdated features, while leaving it to others in the company to make formal definitions of what is "deprecated" and what that really means.
The Handbook is intended as an extended language tutorial, not a best practices or application design guide. As such, I felt it had to be reasonably inclusive. Also, though the book came out with the OE10 doc set, it was in fact written to Version 9, and as such has had to be updated in various ways (such as the follow-on ProDataSet book) and other materials (yet to come, in some cases).
In the PSDN materials in the OE Practices area, we are trying to establish firmer guidelines for "modern" programming in ABL, which of course will include (any day now, we promise, Thomas) material and examples on class-based programming and other features of OE10.1 and more releases to come.
So I would say that shared variables were discussed in the book "for historical reference", and if their disadvantages weren't sufficiently emphasized, well, shoot me, but we are doing our best to move the community forward while at least acknowledging that newer better programming mechanisms co-exist (happily, for the most part) with older code that remains successful for what it does and will continue to do so.
there is an entire sub-section earlier in the book
Well, yes ... but I think that Tim's point is that one should be giving a consistent message. In that section you spend most of your time on global shared and the arguments against regular shared seem to boil down to:
1) If you are using some structures of persistent procedures, you can't use shared because there is no shared context;
2) It can be confusing; and
3) If the procedures are spread across more than one machine, it isn't possible to use shared.
That's not a real clear strong message to me. The key point is that shared is a violation of desirable encapsulation and I don't see where you say that.
To be sure, there are lots of us out here with legacy apps filled with shared variables. If one is making minor tweaks, there is a strong tendancy to just leave things as they are. But, when some more fundemental work needs doing, there is no reason not to encourage people to shift to more modern techniques, thus at least improving one little corner of the application.
I.e., even if you aren't tackling best practices ... and I'm not sure that you aren't, really, in that book ... the focus should be on understanding what goes on with shared variables, why they are problematic, and what more modern techniques are desirable to use instead. Many of these applications are also filled with editing blocks too ... do you want to support people continuing to use them or point them in how to get rid of them?
will include (any day now, we promise, Thomas)
Because I will be the one writing them?
shoot me,
I think a flogging will be sufficient this time ...
Boy, you step out of the room for a minute (well, to
Greece and back and various other places) and all
hell breaks loose.
All hell?
Now I know how all those other
guys feel about being quoted out of context...
Except, of course, they were guilty...
Consider, though, that these reference books may or may not be read "in context" as you appear to be defining it. I don't think it's reasonable to expect a developer to read the entire handbook when they're looking for information on one language element. I know I didn't read the entire book, and I have no intention of doing so since I was only looking for specific material I need to figure out.
In my own defense, if this is necessary, there is
an entire sub-section earlier in the book entitled
"Why you generally shouldn't use shared variables",
which tries to balance the "traditional" (if you'll
pardon the expression) use of shared variables and
more modern ABL programming techniques.
Which may be fine if that was carried over to the rest of the book. The reference I related described shared variable programming as "traditional", not "historical".
If it isn't
put even more strongly, it's because the book was
trying to strike a balance between material for those
who may be maintaining older applications and those
trying to create new ones.
I have no issue with that.
There are a number of places in the book
where I try to describe outdated features,
Do you label them as such?
while leaving it to others in the company
to make formal definitions of what is "deprecated"
and what that really means.
And are we as users supposed to infer that?
The Handbook is intended as an extended language
tutorial, not a best practices or application design
guide.
Application design is part of language instruction, since the how one uses the language implies some sort of inherent application design. If you're writing instructions on how historical language elements worked, were used, and their general design techniques - that's fine. However, they should be labled as such and pointers provided to current languange elements and techniques that should be followed.
So I would say that shared variables were discussed
in the book "for historical reference", and if their
disadvantages weren't sufficiently emphasized,
I'm saying their disadvantages need to be consistently emphasized, not just be stuck in one spot and then that section pointed to as a disclaimer. It's not reasonable to expect current developers to read all of a reference book's contents every time a new version comes out or they're looking for help with one particular language element.
well, shoot me, but we are doing our best to
move the community forward while at least
acknowledging that newer better programming
mechanisms co-exist (happily, for the most part)
with older code that remains successful for what
it does and will continue to do so.
I'm not saying that instruction of historical language element usages should be eliminated. I would submit that whenever old language elements are described, something needs to be included saying they're old / historical and references made to other techniques which provide better / safer ways of accomplishing the same thing.
Now I'm in the "Open Edge Getting Started: Object-Oriented Programming", and what do I find on page 1-9?
Procedures can use shared variables and other mechanisms to share data between
procedures.
Should it not be:
Procedures can use parameters and other mechanisms to share data between procedures.
Why, in the docs used to describe cutting-edge ABL technology, is shared variables mentioned front-and center, when it should be relegated to "other mechanisms"?
Actually, looking at this, isn't "sharing" information between procedures generally something to be avoided except when passing values through a set of well-defined APIs - which is actually what the next sentence states:
Alternatively, a procedure can define public internal procedures or user-defined functions to allow controlled access to its data.
Shared variables need to be relegated to the "for historical information only" pile and left there.
Why this "war against shared variables"? Other languages provide equivalent constructs with the "static" keyword for session wide, global variables and "ThreadLocal" or "thread static" variables for thread-scoped variables. You can use this feature to implement the singleton pattern for instance.
The documentation (http://www.psdn.com/library/entry.jspa?externalID=437&categoryID=261) by the way states:
"...
You cannot define a NEW SHARED or NEW GLOBAL SHARED variable in a class
definition (.cls) file.
..."
So that's good news
Why this "war against shared variables"?
Because they're an insidious cancer in an application's development that should be replaced by other, newer and safer methods of sharing information between procedures, rather than being touted as a plausible option for an unwitting developer to use.
Other languages provide equivalent constructs with the "static" keyword for session wide, global variables and "ThreadLocal" or "thread static" variables for thread-scoped variables. You can use this feature to implement the singleton pattern for instance.
I'm not dealing with other languages though, I'm dealing with the ABL & it's documentation, which keeps touting shared variables as a possible solution to different problems.
The documentation (http://www.psdn.com/library/entry.jspa?externalID=437&categoryID=261) by the way states:
"... You cannot define a NEW SHARED or NEW GLOBAL SHARED variable in a class definition (.cls) file...."
So that's good news
It is good news, and I was going to mention it - but you beat me to it.
Yes, and one can make a good case that static variables are also evil and are bad OO.
Yes, and one can make a good case that static variables are also evil and are bad OO.
Static variables do have their uses, albeit in very restricted cases.
I suppose that all evil things have their uses, but that
doesn't make them good. In some cases, they might even be a
necessary evil, but I advocate making sure that everyone is clear
that they are still evil because otherwise people just start using
them freely, the way they have with shared variables. One of the
places I see this a lot, and it really drives me nuts, is in
Actuate Basic, which is OO. Over and over and over again I see
Actuate developers define global variables in order to pass some
information from one context to another when it is quite possible
to pass this info in a good OO way by having the objects
interrogate their context. People are just lazy about learning how
to do it right.
I suppose that all evil things have their uses, but that doesn't make them good.
The "Evil-ness" of something isn't necessarily about their existence, but how they're used or are abused in order to (wrongly) accomplish a particular goal.
Shared variables had their uses when procedures didn't allow for passing parameters. Now that parameters can be passed, the need for SV's no longer exists in new code.
Static variables have uses for certain restricted cases, but they can be abused by those who don't know - or haven't been managed - better. The mis-use is what makes them evil, not their existence.
I would argue that static variables are not good OO and therefore inherently evil. That this evil may be useful is a separate issue. If we understand that they are evil, then we won't be tempted to misuse them, i.e., to use them when it isn't absolutely necessary ... if any such conditions exist.
Perhaps we should stop and think about whether or not the OO kool-aid is really all that it's knocked up to be. OO has a place but it isn't the be all and end all.
Static variables also have their uses -- I'm sure that you might find a few here and there in the Progress 4gl/db source code.
Shared variables have uses too. It's true that certain vendors got (very) carried away with them 20 years ago and set some horrible examples that live on to this day inspiring bad programmers to be even worse but doesn't mean that they should be reviled in quite the same way that USE-INDEX and CAN-DO deserve to be
BTW -- I do agree that the documentation should be done differently. Good practice should be emphasized and less good practice relegated to the "notes" section or at least given less prominent billing. As it is certain features that are prone to mis-use (such as shared variables, CAN-DO and USE-INDEX) are far too prominently featured in the documentation and, in many cases, are held up as exemplars when they should not be.
Perhaps there should even be a section in the docs on "practices to be avoided"
BTW -- I do agree that the documentation should be
done differently. Good practice should be emphasized
and less good practice relegated to the "notes"
section or at least given less prominent billing. As
it is certain features that are prone to mis-use
(such as shared variables, CAN-DO and USE-INDEX) are
far too prominently featured in the documentation
and, in many cases, are held up as exemplars when
they should not be.
Such as using shared variables / temp-tables as an example of procedural programming in the new OO intro docs...
I'd make the same
translation here. What is one circumstance where a shared variable
is superior to a parameter ... other than in a version of Progress
where there were no parameters, which is a silly example?
Without wanting to intensify the war, shared variables are in fact a very powerful things and there are some very specific cases where shared variables can have very positive side affects, like improved performance.
Personally I am very much against using shared variables, but there are always trade-offs to be considered - Performance vs. Theoretical Design/Maintainability/etc. Saying "never" to shared variables is similar to saying "never" to denormalised data and we all know that there are some very specific cases where we might need to denormalise.
Do you have benchmarks to prove that they have measurable performance advantages? Are these even meaningful?
At the very least, it would seem that one would need a run statement in a loop with many iterations and, of course, this would first imply the use of a persistent procedure so that the run is a run of an IP and any fixed parameters were set once outside the loop. Unless that procedure essentially does no work ... which is not a very interesting case ... I find it very difficult to believe that the overhead of the run itself doesn't swamp out the overhead associated with a parameter versus a shared variable. And, of course, if the work done by the procedure is that trivial, why isn't it done in-line.
Static variables also have their uses
More correctly, I think it is "Static variables get
used", but where are they a better solution than a
singleton or property object and why?
And how do you think one can implement a singleton in .Net/Java for instance: right, with a static instance variable In those environments there is no class instance chain you can walk....
Shared variables have uses too.
I'd make the same translation here. What is one
circumstance where a shared variable is superior to a
parameter ... other than in a version of Progress
where there were no parameters, which is a silly
example?
Let's assume you want to stuff a frequently used object handle somewhere:
- you can walk the object chain all the time, trying to find your instantiated class instance
- or you could check the local new global shared variable
Perhaps we should stop and think about whether or
not the OO kool-aid is really all that it's knocked
up to be. OO has a place but it isn't the be all and
end all.
Tom, we know you are not a believer ...
Well now that you've reduced it to a religious question I guess there's no need to be rational
But seriously, OO is an interesting idea that makes some problem domains simpler. But it is hardly the end all and be all of programming paradigms (oops! I'm repeating myself...). Nor is it a silver bullet. Brooks proved that there are none of those to be had 20 years ago.
Or, you can put the value in
an SP or singleton object designed to provide such values and
simply retrieve it as necessary. Doing so makes it clear where it
is set and where it is used.
You have no argument that it is not a silver bullet. Did I not indicate that it is very possible to write bad OO code?
My question is that you seem to be suggesting that OO is good for some problem domains and that something else is better for other problem domains. What is that something else that is better? For what domains is it better? Do any of these relate to a domain where one would be writing ABL code of any form?
It is easy to be dismissive ... but it would be more useful to be clear about what exceptions or qualifications you are making.
I have yet to find a problem domain that I care about where OO is, IMHO, clearly "better".
Although I suspect that if I cared more I might find that OO might be better when writing complex GUIs. Then again I think that complex GUIs are probably a mistake in the first place.
There are a few areas where OO might be worth giving consideration to if the Progress implementation goes in good directions (such as the excellent decision to implement simple accessor syntax). But right now I cannot see any overwhelming advantage to be had. It's a nice check off on the marketing side though.
Or, you can put the value in an SP or singleton
object designed
But how are you going to find this singleton object when:
- there is no "static" specifier in the OO4GL (there is no "METHOD PUBLIC STATIC ..." nor a "STATIC CLASS ..." as far as I know)
- and you don't want to new up a locator object every time to locate the "Singleton"-instance in the class instance-chain?
http://www.oehive.org/PseudoSingleton
Perhaps that comes of writing OO
with public data members! Or, maybe it comes of having not
really tried ... One would have thought that I was the one old
enough to be a dinosaur, but I guess age isn't everything.
But how are you going to find this singleton
object
http://www.oehive.org/PseudoSingleton
Come on, be a sports and read all the requirements I wrote "don't want ... to locate ..in the class instance-chain". Your context class needs to be instantiated before it can find the "implementation object" by walking the object chain. So you asked for an example to streamline code: you gave the example yourself...
"Don't want" is not a requirement I take very seriously. It strikes me as a way of being presented with a solution and then denying it by defining it out of existence.
What I like about this pseudo-singleton approach is that it is usable as of 10.1A, but when we get true singletons later, one can simply collapse the action code into the finder and all the rest of the code is likely to remain the same. Yes, it is a workaround, but it is a workaround that works!
"Don't want" is not a requirement I take very
seriously.
"Don't want" means: I know the another way of doing it.
What I like about this pseudo-singleton approach is
that it is usable as of 10.1A, but when we get true
singletons later, one can simply collapse the action
code into the finder and all the rest of the code is
likely to remain the same.
That's not true, since you have instantiated and deleted this context object all over your code! With a true singleton, you don't have to instantiate the context class, but you would provide a "LoginContext.Current" property.
Yes, it is a workaround,
but it is a workaround that works!
Accessing a new global variable that's tucked away somewhere is also a workaround that works....
Works, but
it provides no upgrade path to a better implementation in the
future when it becomes available and in the meantime it provides a
bad example of violating encapsulation.