ILE is an acronym which stands for Integrated Language Environment.
ILE was introduced with V3R1 of OS/400 and gave iSeries programming languages many of the capabilities that are found in modern programming languages.
Among these capabilities are...
- Static and dynamic binding to Procedures that can be coded in any ILE programming language.
- Multiple Modules can be included in a Service Program. These Service Programs are loaded at run time allowing for (something)
- Addition of the Activation Group concept for resource managment.
Program Call Evolution
Trying to put this into perspective for people who may be more experienced with what came before and still struggling to Grok implications of new features.
Traditional (pre ILE) Program Calls
Each program can contain CALL statements that call other programs, that can be in the same or a different language. Each of the called programs can in turn call others.
These calls are resolved at execution time.
Each program object is directly compiled from a source member.
With only one exception known to Al Mac, each program must be 100% written in one language, although it typically accesses objects sourced from other languages, such as DDS for layout of stuff, and CLP heavy use of IBM Commands.
The exception is SQL embedded in RPG.
ILE Static Call - Bind by Copy
- Each module (*MODULE object) is created from one source member.
- Each program (*PGM object) is created by copying or "binding" one or more modules and specifying the name of the *MODULE to initially receive control.
- Linkages are established at compile time.
- Each module can be written in any ILE program.
- Thus a combined program can have several different languages in the same program, each being in a different module.
- Static Program Call has less overhead.
- Dynamic Program Call (the prior traditional approach) remains supported.
- ILE needs more memory.
- This executes faster than the prior methods.
- Each *MODULE within each *PGM has a unique virtual address.
- Where in the prior traditional approach, when you called some program or subroutine or whatever, always have smae entry point, but can have multiple exit points, and can leave program active to help performance if expect it to be called again soon, in this reality we can have multiple entry points.
ILE Static Call - Bind by Reference
Q and A on Dynamic vs Static binding
(This section taken from a 1999 discussion on RPG400-L http://archive.midrange.com/rpg400-l/199909/msg00384.html)
First, there are several good books that you can read which give very good information on the subject - see http://www.midrange.com for links to good books in our field. These books will answer quite a few questions besides this one...
IBM have a web site where you reference every manual! It is http://publib.boulder.ibm.com/iseries/ The specific manual that addresses ILE concepts like binding is the ILE Concepts Guide. Programming -> Programming Languages -> ILE Concepts. For 7.1: http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/topic/ilec/sc41560602.htm
Q. What is the difference between Static and Dynamic binding? A. Dynamic binding is the "traditional" way for one program to call another. Static binding is the "ILE" way. Static binding is much faster at run time than dynamic binding. Dynamic binding may not be the best term to describe a dynamic program call; it's used here as a contrast between the OPM program call model and the ILE procedure call model. (Need to amplify this; maybe in the bind by reference and bind by copy sections above.)
Q. What is binding? A. Start by thinking of it as parameter binding. Since OPM parms are passed by reference, that means that the called program needs to know the addresses that the caller uses to store the parm values. In essence, the called program modifies memory within the calling program's address space.
It is more than just parameters... Like maybe the addresses of the procedures themselves... I don't know this for certain, but it seems logical to me that this would be the way you'd want to do it.
Most parameters in ILE are also passed by reference. Unless the "value" keyword is used... Essentially all this entails is passing a pointer to the variable for the parameter -- to the called program.
The called program then puts its variable in the same area of memory, which means that anything that's changed is changed for both programs.
When called by value, the programs each have different areas of memory for their variables, but the byte values are copied from the caller's area of memory to the called's area.
In my current understanding, binding is the act of finding all of the procedures that are called (except for dynamic calls, of course) and putting either a copy of the called module into the program (i.e. bound by copy) or by placing a the address of the routines to be called from their service programs into the program being created (bound by reference)
Q. What is the difference between a dynamic program call and a static procedure call? A. With dynamic binding, the "connection" between the two programs happens at the moment the CALL operation is executed. Between finding the program in the library list, verifying authority, opening the files and initialising the variables, this can be a long process (several tenths of seconds.) With static binding, almost all of the work (aside from variable initialisation and file opens) takes place at compile time. This makes a static call fast.
There is one other type of procedure call; calling a procedure in a service program. Like a static procedure (one wholly contained within your program) a service program procedure is called via CALLP (or the equivalent EVAL). The difference is that the calling program does not know where the procedure code is until run time. When the program is executed, the system performs a process called activation, when it goes out and finds the service programs conntaing the procedures your program calls. This process of activating a service program happens once during a particular job (see activation group), and is similar to the amount of time the system takes to walk the library list looking for a program the first time it is called dynamically. (This text wants some cleanup)
Q. What difference does it make to the programmer? A. If you currently program using many CALL operations, you can transition pretty quickly to CALLP because you're used to dealing with parameters. Service programs are very much like a library of commonly used procedures. If you don't currently program with many CALLs, you'll need to get used to the idea of local variables, and accessing them via parameters. (Here, CALLP is used to demonstrate calling a procedure as opposed to CALLing a program dynamically.)
Q. What is the advantage of static binding? A. Speed. We can finally break up our large programs into smaller, easier to read and maintain units without a performance penalty.
Q. What is the disadvantage of static binding? A. When you create a module, which is bound into many different program objects, it can become difficult to maintain, because when you make changes to it, you have to re-create all of the programs that use that module. You also need to determine which modules are used by a program every time you compile it which can make it difficult when you need to recompile things "en-masse". (This is bind by copy)
Q. Is there a happy medium between the speed of bound modules and the ease of maintenance of dynamic calls? A. Yes, Service Programs. Instead of writing reusable code as modules and then binding those modules to create programs, you can instead bind your reusable code into a service program. Then, when you create programs, you bind to that service program. The service program is a separate object on disk, and therefore, is a bit slower than a bound call -- but you can change a service program without having to recompile all the programs its bound to, as you would with a module. (This is bind by reference)
Q. What is binder language? A. As mentioned above, you can make changes to a service program without having to recompile the programs that call it. This is true UNLESS you change a parameter or add a new procedure that can be called. When this happens, the "public interface" (the way your service program can be called by others) has changed, and other programs will no longer know how to call your service program. To help make this easier to work with, binder language allows you to specify which procedures in your service program can be called from outside programs, and also allows you to specify "previous" interfaces to your service program, so existing programs can continue to call your service program the same way they did before the changes.
Q. What is the performance difference between bind by copy and a service program (bind by reference)? A. Simplistically, calling a "bind by copy" procedure is about as fast as a traditional EXSR call, because the called code is embedded right there in the program object. A call to a procedure in a service program is a bit more complex to explain because the performance relates to the number of procedures bound in the service program. When you call the main program, the service program is activated at the same time. The activation takes more time for each procedure bound into the service program. This "hit" happens once, when the main program is called. Actual CALLPs to the service program's procedures take about the same amount of time as an EXSR. For details on service program activation, see the ILE Concepts manual.
Q. What is the difference between CALLB and CALLP? A. CALLB follows the more traditional format of the CALL op-code, but is limited to calling procedures that are bound by reference. The limitation is that it is easy to mis-match the parameter definitions between the caller and the called procedure. CALLP requires a prototype definition, much like C. This helps to enforce parameter matching. It also allows you to use a procedure as a function, on the right side of an EVAL statement, like EVAL Title = GetTitle(EmployeeNum).
With the EXTPGM keyword on your prototype you can even use CALLP to do dynamic calls! See 'How do I prototype calls to OPM programs...' below."
Q. How do I prototype calls to OPM programs like QCMDEXC? A. Use the EXTPGM keyword on the prototype; you won't need to have an actual procedure interface:
DQCmdExc pr extpgm('QCMDEXC') D Command 80a const D Length 15p 5 const
EXTPROC allows you to have a different internal name for a procedure than its external name, much the way the RENAME keyword on the F-specs lets you use a different record format name. (Note to editor: Use the bindable APIs and C-functions as examples of when the use EXTPROC.)
Q. How do I prototype calls to a procedure in a service program? A. No special coding is required. Simply copy the procedure prototype definition from the called procedure into the calling program. By far, the easiest way to do this is to put the definition in a /COPY member, and /COPY it into every program that needs it, including the module that ends up in the service program.
Q. What is EXTPROC used for? A. EXTPROC is the way to utilize the bindable APIs like CEEDOD or the C library functions. You can create your own bindable procedures by creating a binding directory and adding the modules or service programs to it. When you use EXTPROC you are doing a bind by copy. You specify BNDDIR on the CRTRPGMOD command, and that's how the system knows where the executable code is to be found. Like EXTPGM, you only need a procedure prototype, not the procedure interface.
Q. Doesn't this seem a lot of work? A. Far too many OPM programs contain the same code over and over. That is, every program that needs to calculate a price has a separate copy of the pricing routine. When a change needs to be made, off we go into every source member to analyse how to make the change, then compile and test every one of those programs. With procedures, we can think of the pricing 'routine' as a function - plug in the customer and item and quantity, turn the crank and out comes the price. Instead of manually copying the source code into each program that needs to do pricing, we can call the procedure. Creating callable functions is a powerful programming tool which OPM paid for with a fairly high cost - imagine writing one separate program for each 'function'. Calling each function as a program would be expensive in terms of performance compared to writing a procedure, which is much lighter weight than an entire program.
This article is a stub. You can help by editing it.