× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Hi, Steve:

Please see my embedded replies below.

> Steve Richter wrote:
On 2/24/08, Mark S. Waterbury <mark.s.waterbury@xxxxxxx> wrote:
Steve:

Let's examine each of these supposed "limiting features" in i5/OS:

"no managed code" -- i5/OS, OS/400 and even CPF have always had the equivalent of "managed code" -- it's called "MI" or "TIMI". You cannot create "native" IMPI or PowerPC instruction streams and execute them under OS/400 or i5/OS using documented interfaces.
more like the JVM in terms of the intent of my usage. the specific feature I have in mind is the object encapsulation of program variables and the use of references to access those variables. The programmer working with a framework or better, OS, that integrates managed code has a huge advantage over the less fortunate.
If I understand what you are saying, you can do this now and it's not that hard. Create a service program that has "private data" with several procedures (getter and setter methods) to manipulate the private data managed by the service program (which represents an "object" in OO programming). You can do this in ILE RPG IV or even COBOL as well as C or C++. For example, suppose I want to encapsulate the EMPLOYEE object. I can have a service program named "EMPLOYEE" with procedures with names like this (following your penchant for using long and meaningful names):

getEmployeeName
setEmployeeName
getEmployeeAddress
setEmployeeAddress
getEmployeeCity
setEmployeeCity
getEmployeeState
setEmployeeState
getEmployeeZipCode
setEmployeeZipCode
getEmployeeSalary
setEmployeeSalaryth
getEmployeeStartDate
setEmployeeStartDate
getEmployeeEndDate
setEmployeeEndDate
getEmployeeDepartment
setEmployeeDepartment
... and so on ... you get the idea?

Now, this EMPLOYEE object maintains dynamically allocated data in memory. This could be data stored in an EMPLOYEE database table, for persistence and for use in reporting, etc. But when the application wants to manipulate the employee data, it uses the methods of the EMPLOYEE "class" or "object" (service program). That way, you can incorporate (and encapsulate) all of your business logic and "business rules" to enforce whatever rules are needed by your application.

I think this is a very natural approach and ILE service programs and their architecture support this design model very well. With this approach, you could even write your own "frameworks" in RPG IV, or whatever is your favorite ILE language.
"10 character object names" -- You can use very long procedure names in modules and service programs. Once you add a *MODULE or *SRVPGM to a binding directory, you never need to directly refer to the 10-character name of those modules or service programs. When ILE programs are bound to *SRVPGMs, the service programs are loaded and activated automatically, as needed.
right, and a majority of shops dont use service programs because of their complexity and the danger of the signature violation and worse, export mismatch when hardcoding the signature.
Do you really think service programs and signatures are "too hard"? :-o I don't think that's why many shops do not use them. I think it is largely because many of the older ISVs did not adopt ILE techniques, and so many of the existing vendor packages are still written in OPM RPG/400, or RPG IV, but in "compatibility mode" (CVTRPGSRC, then CRTBNDRPG and runs in the *DFTACTGRP).
Also, with DB2/400, you can use much longer names for tables and views (and DB2/400 generates the i5/OS 10-character names for the underlying *FILE objects automatically).
stored procedures as seen on the network, from an odbc client such as crystal reports, only see the 10 character name.
Others have responded to this one already.
You can also use field names much longer than 10 characters in DB2/400 tables and views.
having two names for fields and files is arguably worse than a single name. short names are a problem for programmers.
Others have responded to this. I will just add that aliases permit those who want or need to use longer names to do so, while those of us who can "cope with" shorter names (or those of us with "legacy code") can use shorter names, even at the same time, against the same files (and fields). What's wrong with that?
"segment space limits" -- as originally architected, MI space objects are limited to 16 megabytes maximum size. OS/400 or i5/OS regularly uses multiple MI objects to create many of the OS/400 or i5/OS objects we are familiar with.
You can use more than one *USRSPC object to create your own very large "persistent heap" to contain complex data
structures whose total size is much larger than 16 megabytes.
linking spaces like this is the equivalent of GOTOs in program code. bad practice.
I have never heard this technique compared to "GOTOs" (and note that not all GOTOs are "harmful") nor have I hever heard this technique called "bad practice." What are you basing this on? IBM does it all the time; many i5/OS or OS/400 objects are composed of multiple MI objects. (Of course, IBM has built the necessary logic into SAVE and RESTORE that knows how to deal with any "embedded" pointers during the restore.)
another problem with this linkage method is you cant use CRTDUPOBJ and SAVOBJ to refer to your single linked object.
If you have a requirement to save and restore all of the "related" user spaces for a given "composite object", it is not that hard to do. To make it easier to save them all and restore them all, I suggest you create a library specifically to contain all of these related user spaces. Then you can use SAVLIB and RSTLIB, with some "pre-processing" and "post-processing" as follows. Pre-processing (before save): use the MATPTRL MI instruction to materialize all pointer locations within each user space. For each such pointer, you could use MATPTR to obtain the 2 byte type/subtype and the 10-character name of the *USRSPC, and use SUBSPPFO to obtain the 4-byte binary offset. Notice that this information will fit within the 16-byte MI pointer [type/subtype/name/offset]. (So we are translating all pointers to a symbolic form that can be saved and restored again.) Post-processing (after restore): when referencing any of these "pointers" in your data structures, you will use a procedure that first attempts to use the pointer directly. If the procedure gets an exception (e.g. pointer not valid, because the tag bits will not be set once we store the [type/subtype/name/offset] in there), then it must contain a symbolic quadruple [type/subtype/name/offset]. The procedure will use the 2-byte type/subtype and 10-character name, and issue a RSLVP to obtain a system pointer, then use ADDSPP to add the 4-byte binary offset to get the new space pointer into that space, and replace the [type/subtype/name, offset] quadruple with the new MI space pointer. Notice that this is a form of "lazy evaluation." Or, you can just start at the 'root' of your data structures and walk through all pointers, resolving as you go, immediately after the restore. (I prefer "lazy evaluation" because it incurs the overhead of translating the symbolic quadruple back to a real pointer only when it is actually needed again.) This approach allows you to create your own persistent composite objects of any size, using standard i5/OS features, and you can save and restore them, even across LPARs or machines or different releases.
You can store pointers in one *USRSPC that point into other user spaces, and vice versa.
pointers are invalidated when a space is restored onto the system.
True enough, but certainly not insurmountable. See my previous paragraph above.
Also, if you must have access to a very large contiguous memory space, OS/400 has supported teraspace since V4R4, which supports up to several terabytes of contiguous temporary address space.
which brings us back to the inferior Linux and Windows model where you use one set of data structures in a running program and another set when storing your data structures to permanent, shared storage.
If you store only "relative pointers" (64-bit offsets) rather than absolute 64-bit pointer addresses, you can use mmap() to map the contents of your teraspace into an IFS stream file (see Unix APIs) -- then, you can have "persistent" very large objects.
better to increase the pointer size to 64 bytes so you can have an 8 byte offset and 8 byte segment. just do something so the programmer does not have to work with so many low level details if they want to take advantage of what SLS has to offer. The 16meg limitation must be a hinderance to those IBMers who work on the OS and use spaces.
A 16 byte MI pointer contains 128 bits, and this has almost nothing to do with the fact that an MI space object has an architected maximum size of 16 megabytes. (Note: only 24 bits or 3 bytes are needed to address 16 million bytes). So, how would increasing pointer size to 64 bytes (512 bits) overcome that architectural limitation? 64-bits (8 bytes) can address 18.4 quintillion bytes (that's 18,446,744,073,709,551,616 bytes!) And OS/400 has supported teraspaces since V4R4, which can linearly address up to several terabytes of temporary memory space (hence, the name teraspace).
"outdated ILE" -- ILE now provides something that resembles what you call "reflection" with the QBNRPII API in V6R1, also available as PTFs for V5R3 and V5R4. i5/OS's.
good to know, thanks. is the interface information sufficient so that procedure prototypes are not needed by the RPG compiler? if so, the replacement of the /COPY with a "using service_program_name" in RPG would have been a great feature in v6r1.
If you feel strongly about this, then you should submit a DCR to suggest this to IBM as an enhancement to all of the ILE compilers. (This actually sounds very reasonable to me.)
ILE is a runtime environment. ILE supports structured exception handling.. You say ILE does not support object-oriented programming, but that is really up to each language compiler and its runtime routines. IBM supports C++ as an ILE language, and C++ is a fully object-oriented language. And i5/OS V6R1 ILE can now activate *SRVPGMs "on demand" rather than activating all referenced *SRVPGMs when the first ILE *PGM that references them is activated. ILE has a very advanced binder (or linker) -- you can bind multiple *MODULEs to create a *PGM or *SRVPGM (with CRTPGM and CRTSRVPGM), and you can replace one or more *MODULEs in existing *PGMs or *SRVPGMs (with UPDPGM and UPDSRVPGM). You can even control the ILE signatures that are generated by using optional binder language source statements. (Because ILE has been around for 14 years, is that why you think it is not "modern"?)
details, details, details. the .NET programmer does not have to know any of this. There is no need for binding source and signatures. Use the Power6 processor to its potential and find the procedure being called at runtime in the library list of the job. Similar to the external program call, one of the many great innovations of the original S/38.
Yes, Steve, the devil is almost always in the details.
-Steve
Cheers,

Mark

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.