Idea Details

PERFORM local action - F32434

Last activity 02-06-2019 03:01 PM
DARIUS PANAHY's profile image
02-19-2016 03:45 AM

An idea raised by a couple of customers at the recent Edge conferences this week is to have a local PERFORM capability in an action block. The concept is that you can specify a named local block of code in the action diagram (much like an event handler in a p-step or a COBOL paragraph).

 

You then have a method for calling it, for example PERFORM <LOCAL BLOCK>. No view matching will be needed since it will share views with the AB.

 

This will allow common code to be invoked without needing to place it in a separate CAB and also means that the common code is private to the AB and not public.

 

A very simple example is provided below. The concept of placing code in separate blocks also allows for simplification of the main action block's structure, making it easier to define, understand and maintain. It is a common technique used in most programming languages and the customers who raised the idea felt that it would be a very welcome addition to Gen.

 

|  +- READ db customer

|  +- WHEN successful

|  |  +- UPDATE db customer

|  |  +--

|  |  PERFORM log_updates

|  +- WHEN not found

|  |  +- CREATE db customer

|  |  +--

|  |  PERFORM log_updates

|  +--

+--

+- LOCAL ACTION log_updates

|  NOTE some common logic here

+--


Comments

02-06-2019 03:01 PM

This idea has been moved to "currently-planned". We intend to implement the idea in a future release (or continuous delivery). At this time no target date has been set.

 

Best Regards,

 

Rob Thompson

05-06-2016 03:19 PM

The status of this idea has been set to Under Review as it has more than 10 votes.  CA will consider this idea for a future release of Gen.  If this idea is something you'd be interested in, please vote for it.

03-09-2016 02:22 PM

Note that the 'never change anything to avoid any impact to the customer' applies only to changing the schema.  We are obviously changing and adding functionality more quickly (as can be seen by the interim releases for 8.5 which came out at a rate of 1 per quarter and we'd like to continue a similar pace) but we want to do it in a way that has minimal impact on customers who are not using the new functionality.  And we also want to get to a point where Ideas submitted on the community site can go through the stages in a period counted in months rather than years.

03-09-2016 01:48 PM

I agree with your general comments about code construction - writing well designed code is critical, and being able to incrementally refine from broad strokes to finer details is crucial.

 

I disagree, however, that you can't use a USE statement to achieve the outcomes you're looking for.  I've seen plenty of well written Gen code where the high level PStep or CAB reads and flows largely like an orchestration CAB, where it's an easily understood flow where CABs do all the important work.  In some ways, a CAB works better - it is provided with solely the state that is required, whereas a local function/loop capability allows for unintended use of variables that are beyond the remit of the purpose of the function.

 

I can definitely see some value in the idea offered here - I can think of some small, but crucial ways in which it could greatly help (particularly around GUI/UI statements in PSteps).  However, I think this is addressing some more core issues (eg modularisation) from a very specific point of view, and not it's broader implication.

03-09-2016 04:41 AM

I really appreciate such a feature. To me it is all about good design and a visible structure of such a design in your code. Like in a step-wise refinement or top-down design method the objective is to decompose a problem into many sub-problems and establish the overall structure and the relationships between the various tasks of the solution. In this sense such local code blocks should accomplish clearly identifiable tasks and given names which can tell a story of your design. And this is definitely not a question of the size of an action block. It is true for any size of logic. In addition I would even omit a  key word like PERFORM or be able to make it invisible, as it is boilerplate code that does not add any value to the story the code is telling you.

 

I would like to add, that I do a lot of Gen trainings since many years and I always try to get my trainees enthusiastic about Gen. And believe my, in todays Java minded world this is really a tough job. Sometimes I feel like an museum attendant. The absence of a local modularization feature is
always an issue. This is not a question of simplicity of Gen which needs to be guarded. Developers are used to refactor code just to make it easier to understand. I like to say that you need to use a piece of code first, before you can reuse it. Identifying such pieces of code which fulfil a clearly identifiable task
and refactor it into a code block with a proper name is a best practice. Single Level of Abstraction and Separation of Concerns are accepted principles. A local action feature would enable to follow such best practices and principles with Gen a lot more than a USE statement can do.

 

If this can be done without even changing the schema, just do it.

03-09-2016 01:53 AM

From a customer point of view I like the idea. The missing capabilities to better structure the code are one of the frequently stated drawbacks. I am a bit concerned about the approach of CA to 'never change anything to avoid any impact to the customer' as certainly the perception is that GEN becomes more and more outdated and some new functionality could help to perceive the tool as a living system rather than a legacy one.

03-08-2016 02:16 PM

We consider a schema change to occur when the actual schema version is changed and we have added new objects, properties and/or associations to that schema.  We have not done any of that for any of the 8.x releases.  See the Object Decomposition Report supplied with the toolset (odrpta.chm) for information about the current schema.

 

We don't change the schema very often because of the impact it has on the customer (pretty much everyone should regen even if it is not explicitly required) and because of the overhead it has on Gen development.  The changes to the S tables during the 8.5 IR was due to minor changes that would not require a schema change and could be done w/o it.

 

As to documenting ideas, I think the discussion helps us to understand not only what to implement and maybe how to implement it, but also to understand the real value of the idea from an end users perspective and why it is important.  Sometimes that is more important than the details (although obviously the details are important as well).

03-08-2016 01:20 AM

Darius,

 

Agreed, documentation is important - getting it out and debating it publicly is a good thing, transparency for all parties is a good thing.  I don't think that CA should be so wedded to the idea of avoiding a schema change.  In practice, they've done it with the IR series for 8.5 where at least one of the IRs required a reload of the S tables because of data changes.  So even if not explicitly bumped, there was implementation changes - it was just an unversioned update.

 

Hopefully CA will engage with this idea - it's good for us to discuss, but it would be heartening for CA themselves to weigh in and debate, like JC has done with some of the ideas in the past.  I think such debates have helped drive out requirements and different aspects.

 

I suspect we'll see little obvious action given how close they are to a release, but it doesn't preclude getting it on the radar for an early IR for the 8.6 series.  However, I would be surprised if many ideas raised through Ideation are implemented as is - they might be point solutions, but many have broader or practical impacts that would make for a potentially more useful, generic solution.

03-07-2016 05:12 AM

Daniel,

 

The main reason for documenting the idea in the form of a detailed solution rather than a pure set of requirements is to suggest something that it is achievable as an interim enhancement and hence come up with a proposed solution that does not require a schema change and would be a relatively simple change to the generators and action diagrammer.

 

I accept that ideally the community would suggest ideas in the form of issues or requirements and CA will then decide how best to implement them and of course in this instance it is CA's decision on whether they want to implement the requirement in this way, some other solution or not at all.

 

It is useful to also document the broader issues and stimulate further debate on these and if these lead to other suggestions that could also be accommodated without a schema change and hence stand a chance of being considered, then now would be a good time to suggest them since there may well be better ways of achieving the same results.

 

My concern with just suggesting a pure set of requirements divorced from the practicalities of implementing them in the current schema is that we would end up waiting a long time to see them...

03-07-2016 04:46 AM

Darius,

 

It sounds like to me you're describing a broader set of issues, and that you see this is as the solution.  Part of the problem I have with ideation here is that we're largely presenting (myself included) solutions, rather than problems, to CA.  But if I'm reading you correctly (and adding my own flavours), we're largely looking at:

 

1) Inability to alter the visible scope of a CAB - if it's a CAB, it's visible to all, no concept of private/protected CABs that belong to a component/parent

2) Fragility of the code generators/underlying implementation - minor changes can impact the ability for HPVM to occur, it's not transparent to the developer, and it is not obvious to fix

3) Readability and understanding of the flow of code when things start getting buried in CABs

4) View pollution through redundancy

5) Developer cognitive burden

6) Inability to perform certain things in CABs that can only be done at a PStep level (eg Sort, MAKE/SET statements, etc - one of my own making, I know)

 

For me, I think that any CAB that has thousands of statements is a poor one - it's far too much for one person to carry in their head, has a complex algorithm that isn't broken down into simpler pieces, etc - except for UI PSteps, where you can't avoid it.  But I realise different folks have different views on that - for me, I'd much rather a high level CAB that strings together portions through a combination of USE statements where you can see the algorithm without needing the detail.

 

Arguably, Gen isn't other programming languages, and shouldn't be seen that way - it's far simpler by nature, and it's power (and some of it's restrictions) is in that simplicity.  Adding function pointers, lambdas, GOTOs, etc etc, just increase the cost of training with a debatable level of improvement in general code for LOB applications.

 

However, I don't think each of these problems have to be resolved through a LOCAL perform capability.  Work can surely be done to look at hiding CABs in a private component scope (#1).  Improvements to the generators can help dealing with HPVM (#2).  I would argue that #3 and #5 can be dealt with by an improved toolset - it would be possible to logically do an "Expand" on a USE statement, and intelligently inline the CAB of interest, though obviously without modification capability and some degree of interpretation.  #6 can be dealt with by improvements to CA on how CABs can be constructed.  #4 - well, you're just not going to get away with that with a USE statement.  And I appreciate an HPVM issue is just one of the others you mentioned - perhaps it's possible for a USEd CAB to have broader access to the caller's views, if such a feature is desired?  It would limit deployment - but it also means #6 would be addressed as well.

 

I can certainly see some value in this proposal - but I think a better approach would be to deal with the underlying symptoms and see if there's a better/more fitting way.  Perhaps there isn't!

03-07-2016 04:08 AM

The value in this was not really for performance benefits but to provide a way of better structuring a large action block without needing to place common but private code in separate action blocks.

 

I am all in favour of reusing code and avoiding duplication and the ease with which you can use a common action block and pass complex data structures is a big strength of Gen. Local actions should not be used to develop code that could be reused across multiple action blocks or as an alternative to good structuring of program logic.

 

However there is a development overhead in placing code in called action blocks when that code is completely private to the caller and will not be reused. For example, to maintain high performance view passing requires some discipline in ensuring that the views are always kept in synch, not only matching attributes but also their order in the view structure. Passing persistent views is also more complex since the views have to be defined as persistent and you also need to check whether the view should be locked or not. These are not huge disadvantages, but using a local action that shares the views with the main action block would be simpler than having a called action block that is only used once by the caller.

 

If you are developing an action block that will need thousands of statements, the ability to develop the logic as a main routine with separate local actions (whether reused or not) makes the action block much simpler to structure and maintain and avoids the additional complexity of called action blocks.

 

I think that having a choice of local or common action blocks makes sense and brings Gen in line with other  programming languages that support these features.

 

I also hope that that this is a fairly easy enhancement to implement and hence will not divert too many development resources from other projects.

03-06-2016 06:44 PM

I can't see the value in this at all. 
I'm all for re-using common code - but place the re-usable code within an action block which can be re-used (potentially) more widely.  With regards to performance, we built and ran high volume performance tests to measure the overhead cost of action block "A" calling action block "B", and compared it to the statements coded within the action block. When perfect view matching is used, and high-performance view passing is on (typically standard practice), there was no measurable overhead in the cost of the call to action block "B" from "A".

02-19-2016 04:07 AM

Interesting. I think, if provided, it'd also be useful for a LOCAL ACTION to be able to PERFORM another LOCAL AB. An escape out of the LOCAL at any point would return the logic to the last call point, as if the end of the LOCAL AB had been reached.

 

Should the LOCAL crash/abend I think it'd also be useful to be able to see which part of the MAIN AB or last LOCAL AB it was previously called from.