loadPackage OK for extension/stringChunk.cls
loadPackage OK for utilities/indentedStream.cls
loadPackage OK for extension/extensions.cls
loadLibrary OK for rxunixsys
loadPackage OK for ncurses.cls
loadPackage OK for csvStream.cls
loadLibrary OK for hostemu
loadPackage OK for json.cls
loadPackage OK for mime.cls
loadPackage OK for rxftp.cls
loadLibrary OK for rxmath
loadPackage OK for rxregexp.cls
loadPackage OK for regex/regex.cls
loadPackage OK for smtp.cls
loadPackage OK for socket.cls
loadPackage OK for streamsocket.cls
loadPackage OK for pipeline/pipe.cls
loadPackage OK for rgf_util2/rgf_util2.rex
loadPackage OK for BSF.CLS
loadPackage OK for oorexxshell_queries.cls
loadPackage OK for pipeline/pipe_extension.cls
loadPackage OK for rgf_util2/rgf_util2_wrappers.rex

REXX-ooRexx_4.3.0(MT)_64-bit 6.04 11 Apr 2024
Input queue name: Sb946Q600003f11ad0

----------------------
-- Executor extensions
----------------------

/*
The directive ::EXTENSION delegates to the methods .class~define and .class~inherit.
The changes are allowed on predefined classes, and are propagated to existing instances.

>>-::EXTENSION--classname----+-------------------+-----------------><
                             +-INHERIT--iclasses-+

Examples of extensions:

::extension Array       inherit ArrayInitializer ArrayPrettyPrinter

::extension Object
::method isNil
    return self == .nil
*/

-- Query listing all the methods added by extension on the class String
ooRexx[sh]> ?cmi string <> (rexx)

[Info] [1] Class 'String' P. (REXX)
P. P.G.    '?'                                  : 'String' 'LogicalExtension' (logical.cls)
P. P.G.    'ABBREV2'                            : 'String' 'String' (rgf_util2_wrappers.rex)
P. PCG.    'ALNUM'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. PCG.    'ALPHA'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P...    'ARITY'                              : 'String' 'Doer' (doers.cls)
P. PCG.    'BLANK'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'C2G'                                : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'C2U'                                : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CALL'                               : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'CASEFOLD'                           : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CASELESSCONTAINS'                   : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'CASELESSENDSWITH'                   : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'CASELESSSPLIT'                      : 'String' 'StringHelpers' (string.cls)
P. P.G.    'CASELESSSTARTSWITH'                 : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'CHANGESTR2'                         : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'CHARACTER'                          : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CHARACTERS'                         : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CHECKHEXADECIMALVALUECOMPATIBILITY' : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CHECKLOGICALVALUECOMPATIBILITY'     : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CHECKNUMERICVALUECOMPATIBILITY'     : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'CHUNK'                              : 'String' 'StringHelpers' (string.cls)
P. P.G.    'CHUNKS'                             : 'String' 'StringHelpers' (string.cls)
P. PCG.    'CNTRL'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'CODEPOINTS'                         : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'COMPARE2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. PCG.    'COMPOSE'                            : 'String' 'Doer' (doers.cls)
P. P.G.    'CONTAINS'                           : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P...    'COPIPE'                             : 'String' 'Object' (pipe_extension.cls)
P. PC..    'COPIPE'                             : 'String' 'Object' (pipe_extension.cls)
P. P...    'COPIPEPROFILE'                      : 'String' 'Object' (pipe_extension.cls)
P. P.G.    'COPY'                               : 'String' 'EncodedString' (text.cls)
P. P.G.    'COUNTSTR2'                          : 'String' 'String' (rgf_util2_wrappers.rex)
P. PCG.    'CR'                                 : 'String' 'String' (CoreClasses.orx)
P. P.G.    'DELSTR2'                            : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'DELWORD2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'DEPTH'                              : 'String' 'Object' (array.cls)
P. P.G.    'DESCRIPTION'                        : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'DESCRIPTIONFORERROR'                : 'String' 'StringRexxTextInterface' (text.cls)
P. PCG.    'DIGIT'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'DISCLOSE'                           : 'String' 'Object' (array.cls)
P. P...    'DO'                                 : 'String' 'StringDoer' (doers.cls)
P. P.G.    'DO'                                 : 'String' 'Doer' (doers.cls)
P. P...    'DOER'                               : 'String' 'StringDoer' (doers.cls)
P. P.G.    'DOER'                               : 'String' 'DoerFactory' (doers.cls)
P. P...    'DOWITH'                             : 'String' 'StringDoer' (doers.cls)
P. P.G.    'DOWITH'                             : 'String' 'Doer' (doers.cls)
P. P...    'DOWITHNAMEDARGUMENTS'               : 'String' 'Doer' (doers.cls)
P. P...    'DOWNTO'                             : 'String' 'RepeaterCollector' (functionals.cls)
P. P...    'DROPC'                              : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPCI'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPFIRSTC'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPFIRSTCI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPFIRSTW'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPFIRSTWI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPLASTC'                          : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPLASTCI'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPLASTW'                          : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPLASTWI'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPUNTILC'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPUNTILCI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPUNTILW'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPUNTILWI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPW'                              : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPWHILEC'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPWHILECI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPWHILEW'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPWHILEWI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'DROPWI'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P.G.    'DUMP2'                              : 'String' 'Object' (rgf_util2_wrappers.rex)
P. P.G.    'EACH'                               : 'String' 'Object' (array.cls)
P. P...    'EACHC'                              : 'String' 'TextOrBufferOrStringIterator' (functionals.cls)
P. P...    'EACHCI'                             : 'String' 'TextOrBufferOrStringIterator' (functionals.cls)
P. P...    'EACHW'                              : 'String' 'TextOrBufferOrStringIterator' (functionals.cls)
P. P...    'EACHWI'                             : 'String' 'TextOrBufferOrStringIterator' (functionals.cls)
P. P.G.    'ENCLOSE'                            : 'String' 'Object' (array.cls)
P. P.G.    'ENCODING'                           : 'String' 'EncodedString' (text.cls)
P. P.G.    'ENCODING='                          : 'String' 'EncodedString' (text.cls)
P. P.G.    'ENDSWITH'                           : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'ENQUOTE2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'ERRORS'                             : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ESCAPE2'                            : 'String' 'String' (rgf_util2_wrappers.rex)
P. PCG.    'GENERATE'                           : 'String' 'Object' (generator.cls)
P. P.G.    'GENERATE'                           : 'String' 'Object' (generator.cls)
P. P...    'GENERATE.DOWNTO'                    : 'String' 'RepeaterGenerator' (generator.cls)
P. P...    'GENERATE.UPTO'                      : 'String' 'RepeaterGenerator' (generator.cls)
P. P...    'GENERATEC'                          : 'String' 'TextOrBufferOrStringGenerator' (generator.cls)
P. P...    'GENERATECI'                         : 'String' 'TextOrBufferOrStringGenerator' (generator.cls)
P. PCG.    'GENERATEI'                          : 'String' 'Object' (generator.cls)
P. P.G.    'GENERATEI'                          : 'String' 'Object' (generator.cls)
P. P...    'GENERATEW'                          : 'String' 'TextOrBufferOrStringGenerator' (generator.cls)
P. P...    'GENERATEWI'                         : 'String' 'TextOrBufferOrStringGenerator' (generator.cls)
P. PCG.    'GETUSERDATA'                        : 'String' 'Object' (object.cls)
P. P.G.    'GETUSERDATA'                        : 'String' 'Object' (object.cls)
P. P...    'GO'                                 : 'String' 'Doer' (doers.cls)
P. P...    'GOWITH'                             : 'String' 'Doer' (doers.cls)
P. PCG.    'GRAPH'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'GRAPHEME'                           : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'GRAPHEMES'                          : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'HASENCODING'                        : 'String' 'EncodedString' (text.cls)
P. P.G.    'HASTEXT'                            : 'String' 'EncodedString' (text.cls)
P. P...    'IFFALSE'                            : 'String' 'LogicalExtension' (logical.cls)
P. P...    'IFTRUE'                             : 'String' 'LogicalExtension' (logical.cls)
P. PCG.    'ISBUFFERORSTRING'                   : 'String' 'Object' (text.cls)
P. P.G.    'ISBUFFERORSTRING'                   : 'String' 'EncodedString' (text.cls)
P. P.G.    'ISBUFFERORSTRING'                   : 'String' 'Object' (text.cls)
P. P.G.    'ISCASEFOLD'                         : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISCCSTRIPPED'                       : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISCOMPATIBLEWITHASCII'              : 'String' 'StringRexxTextInterface' (text.cls)
P. PCG.    'ISCOMPATIBLEWITHBYTESTRING'         : 'String' 'Object' (text.cls)
P. P.G.    'ISCOMPATIBLEWITHBYTESTRING'         : 'String' 'Object' (text.cls)
P. P.G.    'ISCOMPATIBLEWITHBYTESTRING'         : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISIGNORABLESTRIPPED'                : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISLOWER'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISMARKSTRIPPED'                     : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISNASTRIPPED'                       : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISNFC'                              : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISNFD'                              : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISNFKC'                             : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISNFKD'                             : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'ISNIL'                              : 'String' 'Object' (object.cls)
P. PCG.    'ISNIL'                              : 'String' 'Object' (object.cls)
P. P.G.    'ISTEXTORBUFFERORSTRING'             : 'String' 'EncodedString' (text.cls)
P. P.G.    'ISTEXTORBUFFERORSTRING'             : 'String' 'Object' (text.cls)
P. PCG.    'ISTEXTORBUFFERORSTRING'             : 'String' 'Object' (text.cls)
P. P.G.    'ISUPPER'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'JOIN'                               : 'String' 'StringHelpers' (string.cls)
P. P.G.    'LASTPOS2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'LEFT2'                              : 'String' 'String' (rgf_util2_wrappers.rex)
P. PCG.    'LOWER'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'LOWER2'                             : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'MAKECOMPLEX'                        : 'String' 'ComplexString' (complex.cls)
P. P.G.    'MAKEREXXTEXT'                       : 'String' 'EncodedString' (text.cls)
P. P.G.    'MAKEREXXTEXTORSTRING'               : 'String' 'EncodedString' (text.cls)
P. P...    'MAP'                                : 'String' 'StringMapper' (functionals.cls)
P. P...    'MAPC'                               : 'String' 'StringMapper' (functionals.cls)
P. P...    'MAPW'                               : 'String' 'StringMapper' (functionals.cls)
P. P.G.    'MATCHER'                            : 'String' 'StringHelpers' (string.cls)
P. P.G.    'MAXIMUMCODEPOINT'                   : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'MAXIMUMUNICODECODEPOINT'            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'NEEDSOBJECT'                        : 'String' 'Doer' (doers.cls)
P. P...    'NEEDSOBJECT'                        : 'String' 'StringDoer' (doers.cls)
P. P.G.    'NFC'                                : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'NFD'                                : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'NFKC'                               : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'NFKD'                               : 'String' 'StringRexxTextInterface' (text.cls)
P. PCG.    'NL'                                 : 'String' 'String' (CoreClasses.orx)
P. PCG.    'NULL'                               : 'String' 'String' (CoreClasses.orx)
P. P.G.    'OVERLAY2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'PARSEWORDS2'                        : 'String' 'String' (rgf_util2_wrappers.rex)
P. P...    'PARTIAL'                            : 'String' 'Doer' (doers.cls)
P. PC..    'PIPE'                               : 'String' 'Object' (pipe_extension.cls)
P. P...    'PIPE'                               : 'String' 'Object' (pipe_extension.cls)
P. P...    'PIPEPROFILE'                        : 'String' 'Object' (pipe_extension.cls)
P. P.G.    'POS2'                               : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'POSIXCLASSCHARACTERS'               : 'String' 'StringHelpers' (string.cls)
P. P.G.    'PP2'                                : 'String' 'Object' (rgf_util2_wrappers.rex)
P. P.G.    'PPINDEX2'                           : 'String' 'Object' (rgf_util2_wrappers.rex)
P. P.G.    'PPSTRING'                           : 'String' 'Object' (object.cls)
P. P.G.    'PPSTRING'                           : 'String' 'StringPrettyPrinter' (string.cls)
P. PCG.    'PPSTRING'                           : 'String' 'Object' (object.cls)
P. PCG.    'PRINT'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. PCG.    'PUNCT'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'QUOTED'                             : 'String' 'StringHelpers' (string.cls)
P. P.G.    'RANK'                               : 'String' 'Object' (array.cls)
P. P...    'REDUCE'                             : 'String' 'TextOrBufferOrStringReducer' (functionals.cls)
P. P...    'REDUCEC'                            : 'String' 'TextOrBufferOrStringReducer' (functionals.cls)
P. P...    'REDUCEW'                            : 'String' 'TextOrBufferOrStringReducer' (functionals.cls)
P. P...    'REJECTC'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'REJECTCI'                           : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'REJECTW'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'REJECTWI'                           : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P.G.    'REQUESTBUFFERORSTRING'              : 'String' 'EncodedString' (text.cls)
P. P.G.    'REQUESTBUFFERORSTRING'              : 'String' 'Object' (text.cls)
P. PCG.    'REQUESTBUFFERORSTRING'              : 'String' 'Object' (text.cls)
P. PCG.    'REQUESTTEXTORBUFFERORSTRING'        : 'String' 'Object' (text.cls)
P. P.G.    'REQUESTTEXTORBUFFERORSTRING'        : 'String' 'EncodedString' (text.cls)
P. P.G.    'REQUESTTEXTORBUFFERORSTRING'        : 'String' 'Object' (text.cls)
P. P.G.    'RESHAPE'                            : 'String' 'Object' (array.cls)
P. P.G.    'RIGHT2'                             : 'String' 'String' (rgf_util2_wrappers.rex)
P. P...    'SELECTC'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'SELECTCI'                           : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'SELECTW'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'SELECTWI'                           : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P.G.    'SETENCODING'                        : 'String' 'EncodedString' (text.cls)
P. P.G.    'SETMETHOD1'                         : 'String' 'Object' (SETMETHOD1)
P. P.G.    'SETUSERDATA'                        : 'String' 'Object' (object.cls)
P. PCG.    'SETUSERDATA'                        : 'String' 'Object' (object.cls)
P. P.G.    'SHAPE'                              : 'String' 'Object' (array.cls)
P. P.G.    'SHAPETOSTRING'                      : 'String' 'Object' (array.cls)
P. P.G.    'SINGULARPLURAL'                     : 'String' 'StringHelpers' (string.cls)
P. P.G.    'SINGULARPLURALCOUNT'                : 'String' 'StringHelpers' (string.cls)
P. P.G.    'SOURCE'                             : 'String' 'Doer' (doers.cls)
P. P...    'SOURCE'                             : 'String' 'StringDoer' (doers.cls)
P. PCG.    'SPACE'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'SPLIT'                              : 'String' 'StringHelpers' (string.cls)
P. P.G.    'STARTSWITH'                         : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'SUBCHAR2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'SUBSTR2'                            : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'SUBWORD2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. PCG.    'TAB'                                : 'String' 'String' (CoreClasses.orx)
P. P...    'TAKEC'                              : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKECI'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEFIRSTC'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEFIRSTCI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEFIRSTW'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEFIRSTWI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKELASTC'                          : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKELASTCI'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKELASTW'                          : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKELASTWI'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEUNTILC'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEUNTILCI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEUNTILW'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEUNTILWI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEW'                              : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEWHILEC'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEWHILECI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEWHILEW'                         : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEWHILEWI'                        : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'TAKEWI'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P.G.    'TEXT'                               : 'String' 'EncodedString' (text.cls)
P. P.G.    'TEXT='                              : 'String' 'EncodedString' (text.cls)
P. P...    'TIMES'                              : 'String' 'RepeaterCollector' (functionals.cls)
P. P...    'TIMES.GENERATE'                     : 'String' 'RepeaterGenerator' (generator.cls)
P. P.G.    'TITLE'                              : 'String' 'StringRexxTextInterface' (text.cls)
P. P...    'TRAMPOLINE'                         : 'String' 'Doer' (doers.cls)
P. P.G.    'TRANSCODETO'                        : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'TRANSFORM'                          : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'TRANSFORMER'                        : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'U2C'                                : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNESCAPE'                           : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNICODE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNICODE16'                          : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNICODE32'                          : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNICODE8'                           : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNICODECHARACTERS'                  : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UNICODEN'                           : 'String' 'StringRexxTextInterface' (text.cls)
P. P...    'UNKNOWN'                            : 'String' 'RepeaterCollector' (functionals.cls)
P. P.G.    'UNQUOTED'                           : 'String' 'StringHelpers' (string.cls)
P. P...    'UNTILC'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'UNTILCI'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'UNTILW'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'UNTILWI'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. PCG.    'UPPER'                              : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    'UPPER2'                             : 'String' 'String' (rgf_util2_wrappers.rex)
P. P...    'UPTO'                               : 'String' 'RepeaterCollector' (functionals.cls)
P. P.G.    'UTF16'                              : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UTF16BE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UTF16LE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UTF32'                              : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UTF32BE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UTF32LE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'UTF8'                               : 'String' 'StringRexxTextInterface' (text.cls)
P. P...    'WHILEC'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'WHILECI'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'WHILEW'                             : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P...    'WHILEWI'                            : 'String' 'TextOrBufferOrStringFilter' (functionals.cls)
P. P.G.    'WORD2'                              : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'WORDINDEX2'                         : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'WORDLENGTH2'                        : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'WORDPOS2'                           : 'String' 'String' (rgf_util2_wrappers.rex)
P. P.G.    'WTF16'                              : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'WTF16BE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'WTF16LE'                            : 'String' 'StringRexxTextInterface' (text.cls)
P. P.G.    'WTF8'                               : 'String' 'StringRexxTextInterface' (text.cls)
P. PCG.    'XDIGIT'                             : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P.G.    '[]'                                 : 'String' 'StringCompatibilityWithOORexx5' (string.cls)
P. P...    '~()'                                : 'String' 'Doer' (doers.cls)
[Info] [1] Class 'String' has 442 methods
[Info] 271 lines displayed

/*
Blocks
A RexxBlock is a piece of source code surrounded by curly brackets.
{say "Hello"}

Optional tags after "{":
::routine       (abbreviation ::r, this is the default tag)
::coactivity    (abbreviation ::co)

Big picture :
A RexxSourceLiteral is an internal rexx object, created by the parser, not accessible from ooRexx scripts.
A RexxSourceLiteral holds the following properties, shared among all the RexxBlock instances created from it :
- source: the text between the curly brackets {...} as an array of lines, including the tag ::xxx if any.
- package: the package which contain the source literal.
- kind: kind of source, derived from the source's tag.
- rawExecutable: routine or method created at load-time (immediate parsing).
- executable: cached executable.
A RexxBlock is created each time the RexxSourceLiteral is evaluated, and is accessible from ooRexx scripts.
When a RexxBlock is a closure's source, it will hold a snapshot of the context's variables.
*/
ooRexx[sh]> ?cm RexxBlock

[Info] [1] Class 'RexxBlock' P. (REXX)
P. P.G.    'COPY'          : 'RexxBlock' (REXX)
P. P.G.    'KIND'          : 'RexxBlock' (REXX)
P. PCG.    'NEW'           : 'RexxBlock' (REXX)
P. P.G.    'PACKAGE'       : 'RexxBlock' (REXX)
P. P.G.    'RAWEXECUTABLE' : 'RexxBlock' (REXX)
P. P.G.    'SOURCE'        : 'RexxBlock' (REXX)
P. P.G.    'VARIABLES'     : 'RexxBlock' (REXX)
[Info] [1] Class 'RexxBlock' has 7 methods
[Info] 10 lines displayed
ooRexx[sh]> block = {say "Hello"}
ooRexx[sh]> block~rawExecutable=
(a Routine)
ooRexx[sh]> block~executable=               -- not yet executed, the cache is empty
(The NIL object)
ooRexx[sh]> block~do
Hello
ooRexx[sh]> block~executable=               -- now the cache has a value: a Routine
(a Routine)

/*
Tilde-call message "~()".
The message name can be omitted, but the list of parameters is mandatory (can be empty).
    target~()
    target~(arg1, arg2, ...)
    target~~()
    target~~(arg1, arg2, ...)
When the expression is evaluated, the target receives the message "~()" which
forwards the message "do".
*/
ooRexx[sh]> {say "hello"}~()
hello
ooRexx[sh]> ?m do                           -- classes supporting the message "do"
P. P.G.    'CLASSES' : 'Package' (REXX)
PM P.G.    'DO'      : 'Doer' (doers.cls)
PM P...    'DO'      : 'CoactivityDoer' (doers.cls)
PM P...    'DO'      : 'MethodDoer' (doers.cls)
PM P...    'DO'      : 'RexxBlockDoer' (doers.cls)
PM P...    'DO'      : 'RoutineDoer' (doers.cls)
PM P...    'DO'      : 'StringDoer' (doers.cls)
PM P...    'DO'      : 'TextDoer' (doers.cls)
.. P.G.    'MESSAGE' : 'MESSAGEPROFILEDATA' (profiling.cls)
[Info] 9 lines displayed

/*
Trailing block argument (similar to Groovy & Swift syntax for closures) :
    f{...} is equivalent to f({...})
    f(a1,a2,...){...} is equivalent to f(a1,a2,...,{...})
*/
ooRexx[sh]> 10~times{2 * arg(1)}=
[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

/*
Named arguments
They have been added because they allow to get rid of the transformation of the
block's sources at run-time (to declare positional arguments like item, index).
More precisely, this instruction:
    use auto named args
lets the caller inject named variables in the scope of the callee.
*/
ooRexx[sh]> {use auto named arg; say n1 n2 n3; .context~namedArgs}~(n1:1, n2:2, n3:3)=
1 2 3
a Directory (3 items)
'N1' :  1
'N2' :  2
'N3' :  3

-- An auto named argument never overwrites a variable already assigned
-- Here, n1 is not overwritten with 1
ooRexx[sh]> {n1=10; use auto named arg; say n1 n2 n3; .context~namedArgs}~(n1:1, n2:2, n3:3)=
10 2 3
a Directory (3 items)
'N1' :  1
'N2' :  2
'N3' :  3

/*
At parse-time, the source is transformed to accept auto named arguments, and to
return implicitely the result of the last evaluated expression.
*/
ooRexx[sh]> block = {say "Hello"}
ooRexx[sh]> block~source=
['say "Hello"']
ooRexx[sh]> block~rawExecutable~source==
an Array (shape [2], 2 items)
 1 : 'use auto named arg ; options "NOCOMMANDS" ; say "Hello"'
 2 : 'if var("result") then return result'

/*
By convention, the higher-order functions are passing the named parameters
"item" and "index". Their values are also passed as positional arguments.
The callee has the choice: using the auto named arguments, or using the positional
arguments. The callee has a total control over which arguments he accepts.
If its constraints on positional and/or named arguments are incompatible with
the expectations of the higher-order function then an error will be raised.
*/
ooRexx[sh]> 
ooRexx[sh]> 10~times{use strict arg v; 2 * v}=  -- Not compatible, an error is raised
Too many positional arguments in invocation of <anonymous>; maximum expected is 1.
Error code= 40.4
ooRexx[sh]> 10~times{use arg v; 2 * v}=         -- Compatible
[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
ooRexx[sh]> 10~times{2 * item}=                 -- No need to declare "item"
[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

/*
The arity is -1 (unknown) for all the doers, except for the blocks for which
the arity is 9999 (unlimited).
The arity is used by the higher-order functions, to decide which parameters
can be passed. For the operators, only 2 positional parameters must be passed.

For example, the implementation of ~reduce:
do while self~available
    if arity >=3 then doer~do(      accu,       self~item,        self~index,-
                              accu: accu, item: self~item, index: self~index)
                 else doer~do(      accu,       self~item,-
                              accu: accu, item: self~item)
    if var("result") then accu = result
    self~next
end
*/
ooRexx[sh]> (10,20,30)~reduce("+")=                                 -- case arity < 3
 60
ooRexx[sh]> (10,20,30)~reduce(initial:0){accu + item ** index}=     -- case arity >= 3
 27410

/*
Closure
A closure is an object, created from a block whose source first word after the
optional tag is "expose".

A closure remembers the values of the variables defined in the outer environment
of the block. The behaviour of the closure is a method generated from the block,
which is attached to the closure under the name "do". The values of the captured
variables are accessible from this method "do" using expose. Updating a variable
from the closure will have no impact on the original context (hence the name
"closure by value").
*/
ooRexx[sh]> newCounter={use arg n=0; {expose n; use arg i=0; n+=i; n}}
ooRexx[sh]> counter1 = newCounter~()        -- start at 0 (default)
ooRexx[sh]> counter2 = newCounter~(20)      -- start at 20
ooRexx[sh]> counter1~() counter2~()=        -- 0 20
'0 20'
ooRexx[sh]> do 5; counter1~(+1); counter2~(-2); end
ooRexx[sh]> counter1~() counter2~()=        -- 5 10
'5 10'

/*
Coactivity
Emulation of coroutine, named "coactivity" to follow the ooRexx vocabulary.
This is not a "real" coroutine implementation, because it's based on ooRexx
threads and synchronization. But at least you have all the functionalities of a
stackful asymmetric coroutine (resume + yield).

A stackful coroutine is a coroutine able to suspend its execution from within
nested calls. The variable .threadLocal is used to retrieve the coactivity
instance from any invocation and send it the message yield (this instance is at
the origin of the invocations stack, but is not passed as a parameter to the
invocations).
myCoactivity~start  <--------------+
    invocation                     |
        invocation                 |
            ...                    |
                invocation: .Coactivity~yield()

A coactivity remembers its internal state. It can be called several times, the
execution is resumed after the last executed ".yield[]" or "call yield".
*/
ooRexx[sh]> generator = {::coactivity i=0; do forever; call yield i; i+=1; end}
ooRexx[sh]> generator~()=
 0
ooRexx[sh]> generator~makeArray(10)=
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ooRexx[sh]> generator~()=
 11

/*
Concurrency trace
The interpreter has been modified to add thread id, activation id, variable's dictionnary id,
lock counter and lock flag in the lines printed by trace.
Concurrency trace is displayed only when env variable RXTRACE_CONCURRENCY=ON

Informations that are displayed.
RexxActivity::traceOutput(RexxActivation *activation, ...
T1       SysCurrentThreadId(),
A2       (unsigned int)activation,
V1       (activation) ? activation->getVariableDictionary() : NULL      // settings.object_variables
1        (activation) ? activation->getReserveCount() : 0               // settings.object_variables->getReserveCount()
*        (activation && activation->isObjectScopeLocked()) ? '*' : ' ') // object_scope == SCOPE_RESERVED
*/
ooRexx[sh]> -- Raw output, not easy to read
ooRexx[sh]> system RXTRACE_CONCURRENCY=ON rexx concurrency_trace.rex
00000000e519a080 000000004a817c40 0000000000000000 00000       1 *-* .demo~new~exec(1)
00000000e519a080 000000004a817c40 0000000000000000 00000         >E>   .DEMO => "The DEMO class"
00000000e519a080 000000004a817c40 0000000000000000 00000         >M>   "NEW" => "a DEMO"
00000000e519a080 000000004a817c40 0000000000000000 00000         >L>   "1"
00000000e519a080 000000004a817c40 0000000000000000 00000         >A>   "1"
00000000e519a080 000000004a820ec0 000000004a821130 00000         >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
00000000e519a080 000000004a820ec0 000000004a821130 00001*      8 *-* use arg id
00000000e519a080 000000004a820ec0 000000004a821130 00001*        >>>   "1"
00000000e519a080 000000004a820ec0 000000004a821130 00001*        >=>   ID <= "1"
00000000e519a080 000000004a820ec0 000000004a821130 00001*      9 *-* reply
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
00000000e519a080 000000004a817c40 0000000000000000 00000       2 *-* .demo~new~exec(2)
000000006ff13000 000000004a820ec0 000000004a821130 00001*     10 *-* do 2
00000000e519a080 000000004a817c40 0000000000000000 00000         >E>   .DEMO => "The DEMO class"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >L>     "2"
00000000e519a080 000000004a817c40 0000000000000000 00000         >M>   "NEW" => "a DEMO"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >>>     "2"
00000000e519a080 000000004a817c40 0000000000000000 00000         >L>   "2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*     11 *-*   say "TASK" id
00000000e519a080 000000004a817c40 0000000000000000 00000         >A>   "2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >L>     "TASK"
00000000e519a080 000000004a82e7f0 000000004a82ea60 00000         >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >V>     ID => "1"
00000000e519a080 000000004a82e7f0 000000004a82ea60 00001*      8 *-* use arg id
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >O>     " " => "TASK 1"
00000000e519a080 000000004a82e7f0 000000004a82ea60 00001*        >>>   "2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >>>     "TASK 1"
TASK 1
00000000e519a080 000000004a82e7f0 000000004a82ea60 00001*        >=>   ID <= "2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*     12 *-*   call syssleep 1
00000000e519a080 000000004a82e7f0 000000004a82ea60 00001*      9 *-* reply
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >L>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >A>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     10 *-* do 2
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >L>     "2"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >>>     "2"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     11 *-*   say "TASK" id
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >L>     "TASK"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >V>     ID => "2"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >O>     " " => "TASK 2"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >>>     "TASK 2"
TASK 2
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     12 *-*   call syssleep 1
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >L>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >A>     "1"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >>>     "0"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >>>     "0"
000000006ff13000 000000004a820ec0 000000004a821130 00001*     13 *-* end
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     13 *-* end
000000006ff13000 000000004a820ec0 000000004a821130 00001*     10 *-* do 2
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     10 *-* do 2
000000006ff13000 000000004a820ec0 000000004a821130 00001*     11 *-*   say "TASK" id
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     11 *-*   say "TASK" id
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >L>     "TASK"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >L>     "TASK"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >V>     ID => "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >V>     ID => "2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >O>     " " => "TASK 1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >O>     " " => "TASK 2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >>>     "TASK 1"
TASK 1
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >>>     "TASK 2"
000000006ff13000 000000004a820ec0 000000004a821130 00001*     12 *-*   call syssleep 1
TASK 2
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >L>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     12 *-*   call syssleep 1
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >A>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >L>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >A>     "1"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*        >>>     "0"
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     13 *-* end
000000007011f000 000000004a82e7f0 000000004a82ea60 00001*     10 *-* do 2
000000006ff13000 000000004a820ec0 000000004a821130 00001*        >>>     "0"
000000006ff13000 000000004a820ec0 000000004a821130 00001*     13 *-* end
000000006ff13000 000000004a820ec0 000000004a821130 00001*     10 *-* do 2
ooRexx[sh]> -- Human-readable output, generated by piping the output through tracer.rex
ooRexx[sh]> system RXTRACE_CONCURRENCY=ON rexx concurrency_trace.rex 2>&1 | rexx trace/tracer.rex
T1   A1                     1 *-* .demo~new~exec(1)
T1   A1                       >E>   .DEMO => "The DEMO class"
T1   A1                       >M>   "NEW" => "a DEMO"
T1   A1                       >L>   "1"
T1   A1                       >A>   "1"
T1   A2     V1                >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
T1   A2     V1      1*      8 *-* use arg id
T1   A2     V1      1*        >>>   "1"
T1   A2     V1      1*        >=>   ID <= "1"
T1   A2     V1      1*      9 *-* reply
T1   A1                     2 *-* .demo~new~exec(2)
T2   A2     V1      1*        >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
T1   A1                       >E>   .DEMO => "The DEMO class"
T2   A2     V1      1*     10 *-* do 2
T1   A1                       >M>   "NEW" => "a DEMO"
T2   A2     V1      1*        >L>     "2"
T1   A1                       >L>   "2"
T2   A2     V1      1*        >>>     "2"
T1   A1                       >A>   "2"
T2   A2     V1      1*     11 *-*   say "TASK" id
T1   A3     V2                >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
T2   A2     V1      1*        >L>     "TASK"
T1   A3     V2      1*      8 *-* use arg id
T2   A2     V1      1*        >V>     ID => "1"
T1   A3     V2      1*        >>>   "2"
T2   A2     V1      1*        >O>     " " => "TASK 1"
T1   A3     V2      1*        >=>   ID <= "2"
T2   A2     V1      1*        >>>     "TASK 1"
TASK 1
T1   A3     V2      1*      9 *-* reply
T2   A2     V1      1*     12 *-*   call syssleep 1
T3   A3     V2      1*        >I> Method "EXEC" with scope "DEMO" in package "/Users/Shared/local/rexx/oorexx/executor/sandbox/jlf/demos/concurrency_trace.rex".
T2   A2     V1      1*        >L>     "1"
T3   A3     V2      1*     10 *-* do 2
T2   A2     V1      1*        >A>     "1"
T3   A3     V2      1*        >L>     "2"
T3   A3     V2      1*        >>>     "2"
T3   A3     V2      1*     11 *-*   say "TASK" id
T3   A3     V2      1*        >L>     "TASK"
T3   A3     V2      1*        >V>     ID => "2"
T3   A3     V2      1*        >O>     " " => "TASK 2"
T3   A3     V2      1*        >>>     "TASK 2"
TASK 2
T3   A3     V2      1*     12 *-*   call syssleep 1
T3   A3     V2      1*        >L>     "1"
T3   A3     V2      1*        >A>     "1"
T2   A2     V1      1*        >>>     "0"
T3   A3     V2      1*        >>>     "0"
T2   A2     V1      1*     13 *-* end
T3   A3     V2      1*     13 *-* end
T2   A2     V1      1*     10 *-* do 2
T3   A3     V2      1*     10 *-* do 2
T2   A2     V1      1*     11 *-*   say "TASK" id
T3   A3     V2      1*     11 *-*   say "TASK" id
T2   A2     V1      1*        >L>     "TASK"
T3   A3     V2      1*        >L>     "TASK"
T2   A2     V1      1*        >V>     ID => "1"
T3   A3     V2      1*        >V>     ID => "2"
T2   A2     V1      1*        >O>     " " => "TASK 1"
T3   A3     V2      1*        >O>     " " => "TASK 2"
T2   A2     V1      1*        >>>     "TASK 1"
TASK 1
T3   A3     V2      1*        >>>     "TASK 2"
T2   A2     V1      1*     12 *-*   call syssleep 1
TASK 2
T2   A2     V1      1*        >L>     "1"
T3   A3     V2      1*     12 *-*   call syssleep 1
T2   A2     V1      1*        >A>     "1"
T3   A3     V2      1*        >L>     "1"
T3   A3     V2      1*        >A>     "1"
T2   A2     V1      1*        >>>     "0"
T3   A3     V2      1*        >>>     "0"
T2   A2     V1      1*     13 *-* end
T3   A3     V2      1*     13 *-* end
T2   A2     V1      1*     10 *-* do 2
T3   A3     V2      1*     10 *-* do 2

/*
Symmetric implementation of operator
Official ooRexx doesn't allow to define symmetric overriding of operators.
You can define a user operator on .array which supports .array~of(1,2) + 10.
But you can't define a user operator which supports 10 + .array~of(1,2).

Executor has been extended to automatically try b~"op:right"(a) when a~"op"(b)
is about to raise an exception.
If an alternate implementation exists then call it otherwise raise the exception.
The two methods Object::messageSend have been modified to let pass an additional
parameter 'processUnknown' which is true by default (legacy behavior). When this
parameter is false, and no method is found for the message, then
Object::messageSend returns false to indicate that no implementation exists.
There is no processing of the unknown message.
This is an efficient way to test if an alternate implementation exists and call it.
When the alternate implementation returns nothing, then don't complain about that.
Behave as if the alternate implementation did not exist, and raise the exception
related to the left argument.
*/
ooRexx[sh]> 1 + (10, 20)=                           -- array programming
[ 11, 21]
ooRexx[sh]> "hello"~text~utf16 "John"~text~utf16=   -- encoded strings
T'[00]h[00]e[00]l[00]l[00]o[00] [00]J[00]o[00]h[00]n'
ooRexx[sh]> 2*(3-2i)=                               -- complex numbers
(6-4i)
ooRexx[sh]> a = (1, 2); a~append(a); a=             -- self-referencing array, its depth is infinite
a1=[ 1, 2,*a1]
ooRexx[sh]> 1 + a~depth=                            -- arithmetic with infinity
(The positive infinity)
ooRexx[sh]> 5 * (a~depth - a~depth)=                -- arithmetic with indeterminate
(The indeterminate value)

/*
Global variable
When a variable has no value, the interpreter sends the message "NOVALUE" to
the object registered in .LOCAL under the name "NOVALUE" (un-documented feature,
see RexxActivation::novalueHandler).
The class GlobalVariables is used to manage global variables like i, infinity, indeterminate.
*/
ooRexx[sh]> .local~novalue=
(The GlobalVariables class)
ooRexx[sh]> ?cm globalvariables

[Info] [1] Class 'GlobalVariables' P. (novalue.cls)
P. PCG.    'DECLARE' : 'GlobalVariables' (novalue.cls)
P. PCG.    'INIT'    : 'GlobalVariables' (novalue.cls)
P. PCG.    'NOVALUE' : 'GlobalVariables' (novalue.cls)
P. PCG.    'VALUES'  : 'GlobalVariables' (novalue.cls)
[Info] [1] Class 'GlobalVariables' has 4 methods
[Info] 7 lines displayed
ooRexx[sh]> .globalvariables~values=
a Directory (4 items)
'COMPLEXINFINITY' : (The complex infinity)
'I'               : (0+1i)
'INDETERMINATE'   : (The indeterminate value)
'INFINITY'        : (The positive infinity)

-- -----------------------------------------------------------
--
-- Some examples of functionalities which depend on extensions
--
-- -----------------------------------------------------------


/*
Range iterator
*/
ooRexx[sh]> 1~9=
[ 1, 2, 3, 4, 5, 6, 7, 8, 9]

/*
The collection is displayed one item per line when the line ends with ==
*/
ooRexx[sh]> 1~9==
an Array (shape [9], 9 items)
 1 :  1
 2 :  2
 3 :  3
 4 :  4
 5 :  5
 6 :  6
 7 :  7
 8 :  8
 9 :  9

/*
The precision of the range iterator is automatically adjusted
*/
ooRexx[sh]> 1~9(by:1e-100, for:10)==
an Array (shape [10], 10 items)
 1  :  1
 2  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
 3  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002
 4  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003
 5  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
 6  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
 7  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006
 8  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007
 9  :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008
 10 :  1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009

/*
To get the last 10 values of the range, pass for:-10
*/
ooRexx[sh]> 1~9(by:1e-100, for:-10)==
an Array (shape [10], 10 items)
 1  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991
 2  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999992
 3  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999993
 4  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999994
 5  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995
 6  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996
 7  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997
 8  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998
 9  :  8.9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
 10 :  9.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

/*
Y combinator:
The Y combinator allows recursion to be defined as a set of rewrite rules.
It takes a single argument, which is a function that isn't recursive (here, no argument, use self which is a Doer).
It returns a version of the function which is recursive.
*/

/*
Inspired by http://mvanier.livejournal.com/2897.html
Y = λf.(λx.f (λv.((x x) v))) (λx.f (λv.((x x) v)))

(define Y
  (lambda (f)
    ( (lambda (a) (a a))
      (lambda (x) (f (lambda (v) ((x x) v)))))))
*/

/*
Implementation of the Y combinator with memoization:
*/
ooRexx[sh]> ?ms YM
PM P...    'YM' : 'RoutineDoer' (doers.cls)
 > 0001 use named arg verbose=.false
 > 0002     if verbose then trace i
 > 0003 
 > 0004     -- lambda_f
 > 0005     f = self -- to be closer to the notation (would be passed by parameter to lambda_f when implemented by a function instead of a method)
 > 0006     YnamedArgs = .context~namedArgs
 > 0007     table = .Table~new
 > 0008 
 > 0009     lambda_x = {
 > 0010         expose f verbose YnamedArgs table
 > 0011         if verbose then trace i
 > 0012         use strict arg x
 > 0013         lambda_v = {
 > 0014                      expose x verbose table
 > 0015                      if verbose then trace i
 > 0016                      --use strict arg v
 > 0017                      v = arg(1, "a")
 > 0018                      v_index = v~tostring
 > 0019                      r = table[v_index]
 > 0020                      if .nil <> r then return r
 > 0021                      r = x~(x)~doWith(v, namedArguments: .context~namedArgs)
 > 0022                      table[v_index] = r
 > 0023                      return r
 > 0024                 }
 > 0025         return f ~ doWith(.array~of(lambda_v), namedArguments: YnamedArgs)
 > 0026     }
 > 0027     return lambda_x ~ (lambda_x)
[Info] 28 lines displayed

/*
Application to Fibonacci:
*/
ooRexx[sh]> almost_fib = { use arg fib; {expose fib ; use arg n; if n==0 then return 0; if n==1 then return 1; if n<0 then return fib~(n+2) - fib~(n+1); return fib~(n-2) + fib~(n-1)}}

/*
The not-memoizing version needs around 15 sec.
*/
ooRexx[sh]> fib_Y = almost_fib~Y
ooRexx[sh]> fib_Y~(23)=
 28657
Duration: 3.540490
#Coactivities: 1

/*
The memoizing version calculates almost instantly.
*/
ooRexx[sh]> fib_YM = almost_fib~YM
ooRexx[sh]> fib_YM~(23)=
 28657
Duration: 0.012352
#Coactivities: 1

/*
fib_Y and fib_YM are closures.
*/
ooRexx[sh]> fib_YM~executable=
(a Closure)
ooRexx[sh]> fib_YM~executable~variables=
a Directory (1 items)
'FIB' : (a RexxBlock)
ooRexx[sh]> fib_YM~executable~variables["FIB"]~executable=
(a Closure)
ooRexx[sh]> fib_YM~executable~variables["FIB"]~executable~variables=
a Directory (7 items)
'F'          : (a Routine)
'SELF'       : (a Closure)
'SUPER'      : (The Doer class)
'TABLE'      : a Table
'VERBOSE'    :  0
'X'          : (a RexxBlock)
'YNAMEDARGS' : Directory(an Array no shape, 0 items)

/*
TABLE is the table of values memoized by fib_YM for the calculation of fib_YM~(23).
*/
ooRexx[sh]> fib_YM~executable~variables["FIB"]~executable~variables["TABLE"]=
a Table (23 items)
 0  :  0
 1  :  1
 2  :  1
 3  :  2
 4  :  3
 5  :  5
 6  :  8
 7  :  13
 8  :  21
 9  :  34
 10 :  55
 11 :  89
 12 :  144
 13 :  233
 14 :  377
 15 :  610
 16 :  987
 17 :  1597
 18 :  2584
 19 :  4181
 20 :  6765
 21 :  10946
 22 :  17711

/*
Both fib_Y and fib_YM are subject to stack overflow.
But fib_YM can be used by steps, to calculate very big fibonacci numbers, thanks to the memoization.
*/
ooRexx[sh]> numeric digits propagate 100
ooRexx[sh]> do i=1 to 500; r = fib_YM~(i*50); if i//50=0 then say "fib_YM~("i*50")="r; end
fib_YM~(2500)=1.317090516751949629522763087125316412066606964992507141887746936727530870405038425764503130123186429E+522
fib_YM~(5000)=3.878968454388325633701916308325905312082127714646245106160597214895550139044037097010822916462210799E+1044
fib_YM~(7500)=1.142396523152058704722048892865690419848718663331756079795903059573826364358830526396432108051699207E+1567
fib_YM~(10000)=3.364476487643178326662161200510754331030214846068006390656476997468008144216666236815559551363373664E+2089
fib_YM~(12500)=9.908732919346489283972390155590053108590838370898511971634619406801520847007023935403361324320167010E+2611
fib_YM~(15000)=2.918224824204913830236407223698513202230962655711828774617138735156624458079183128895718558218554766E+3134
fib_YM~(17500)=8.594475392487880685715609318313958956965186135981014406583281854302591776880967478349722433509870025E+3656
fib_YM~(20000)=2.531162323732361242240155003520607291766356485802485278951929841991312781760541315230153423463759229E+4179
fib_YM~(22500)=7.454536101973301545514060322899628474921968473702388044321015228379740189148914655473430519859925903E+4701
fib_YM~(25000)=2.195438355517303012780791914841720922849015222302155773145178112730662303998294388326731046697794993E+5224
Duration: 2.241227
#Coactivities: 1

/*
End of demonstration.
*/