This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,13 @@
@echo off
::call a function with no arguments
call :myFunction
::call a function with arguments
call :myFunction arg1 "arg 2"
::initiate a "function".
:myFunction
echo arg1 - %1
echo arg2 - %~2
goto :eof

View file

@ -0,0 +1,65 @@
CALL "No-Arguments"
*> Fixed number of arguments.
CALL "2-Arguments" USING Foo Bar
CALL "Optional-Arguments" USING Foo
CALL "Optional-Arguments" USING Foo Bar
*> If an optional argument is omitted and replaced with OMITTED, any following
*> arguments can still be specified.
CALL "Optional-Arguments" USING Foo OMITTED Bar
*> Interestingly, even arguments not marked as optional can be omitted without
*> a compiler warning. It is highly unlikely the function will still work,
*> however.
CALL "2-Arguments" USING Foo
*> COBOL does not support a variable number of arguments, or named arguments.
*> Values to return can be put in either one of the arguments or, in OpenCOBOL,
*> the RETURN-CODE register.
*> A standard function call cannot be done in another statement.
CALL "Some-Func" USING Foo
MOVE Return-Code TO Bar
*> Intrinsic functions can be used in any place a literal value may go (i.e. in
*> statements) and are optionally preceded by FUNCTION.
*> Intrinsic functions that do not take arguments may optionally have a pair of
*> empty parentheses.
*> Intrinsic functions cannot be defined by the user.
MOVE FUNCTION PI TO Bar
MOVE FUNCTION MEDIAN(4, 5, 6) TO Bar
*> Built-in functions/subroutines typically have prefixes indicating which
*> compiler originally incorporated it:
*> - C$ - ACUCOBOL-GT
*> - CBL_ - Micro Focus
*> - CBL_OC_ - OpenCOBOL
*> Note: The user could name their functions similarly if they wanted to.
CALL "C$MAKEDIR" USING Foo
CALL "CBL_CREATE_DIR" USING Foo
CALL "CBL_OC_NANOSLEEP" USING Bar
*> Although some built-in functions identified by numbers.
CALL X"F4" USING Foo Bar
*> Parameters can be passed in 3 different ways:
*> - BY REFERENCE - this is the default way in OpenCOBOL and this clause may
*> be omitted. The address of the argument is passed to the function.
*> The function is allowed to modify the variable.
*> - BY CONTENT - a copy is made and the function is passed the address
*> of the copy, which it can then modify. This is recomended when
*> passing a literal to a function.
*> - BY VALUE - the function is passed the address of the argument (like a
*> pointer). This is mostly used to provide compatibility with other
*> languages, such as C.
CALL "Modify-Arg" USING BY REFERENCE Foo *> Foo is modified.
CALL "Modify-Arg" USING BY CONTENT Foo *> Foo is unchanged.
CALL "C-Func" USING BY VALUE Bar
*> Partial application is impossible as COBOL does not support first-class
*> functions.
*> However, as functions are called using a string of their PROGRAM-ID,
*> you could pass a 'function' as an argument to another function, or store
*> it in a variable, or get it at runtime.
ACCEPT Foo *> Get a PROGRAM-ID from the user.
CALL "Use-Func" USING Foo
CALL Foo USING Bar

View file

@ -0,0 +1,52 @@
# Calling a function that requires no arguments
foo()
# Calling a function with a fixed number of arguments
foo 1
# Calling a function with optional arguments
# (Optional arguments are done using an object with named keys)
foo 1, optionalBar: 1, optionalBaz: 'bax'
# Calling a function with a variable number of arguments
# for a function `foo` defined as `foo = ( args... ) ->`
foo 1, 2, 3, 4
# Calling a function with named arguments
# (Named arguments are done using an object with named keys)
foo bar: 1, bax: 'baz'
# Using a function in statement context
x = foo 1
# Using a function in first-class context within an expression
# (For `foo` defined as `foo = ( x ) -> x + 1`
x = [ 1, 2, 3 ].map foo
# Obtaining the return value of a function
x = foo 1
# Arguments are passed by value, even objects. Objects
# are passed as the _value_ of the reference to an object.
# Example:
bar = ( person ) ->
# Since `person` is a reference
# to the person passed in, we can assign
# a new value to its `name` key.
person.name = 'Bob'
# Since `person` is just the value of
# the original reference, assigning to it
# does not modify the original reference.
person = new Person 'Frank'
# Partial application is only possible manually through closures
curry = ( f, fixedArgs... ) ->
( args... ) -> f fixedArgs..., args...
# Example usage
add = ( x, y ) -> x + y
add2 = curry add, 2
add2 1 #=> 3

View file

@ -0,0 +1,12 @@
no_argument()
one_argument( Arg )
optional_arguments( Arg, [{opt1, Opt1}, {another_opt, Another}] )
variable_arguments( [Arg1, Arg2 | Rest] )
names_arguments([{name1, Arg1}, {another_name, Another}] )
% Statement context?
% First class context?
Result = obtain_result( Arg1 )
% No way to distinguish builtin/user functions
% Subroutines?
% Arguments are passed by reference, but you can not change them.
% Partial application is possible (a function returns a function that has one argument bound)

View file

@ -0,0 +1,28 @@
-- Calling a function with a fixed number of arguments
multiply x y = x * y
multiply 10 20 -- returns 200
-- Calling a function that requires no arguments
-- Normally, you use constant instead of function without arguments:
twopi = 6.28
-- But you can also pass special value as the first argument indicating function call:
twopi () = 6.28 -- definition
twopi :: Num a => () -> a -- its type
twopi () -- returns 6.28
-- Partial application and auto-currying is built-in.
multiply_by_10 = (10 * )
map multiply_by_10 [1, 2, 3] -- [10, 20, 30]
multiply_all_by_10 = map multiply_by_10
multiply_all_by_10 [1, 2, 3] -- [10, 20, 30]
-- TODO:
-- Calling a function with optional arguments
-- Calling a function with a variable number of arguments
-- Calling a function with named arguments
-- Using a function in statement context
-- Using a function in first-class context within an expression
-- Obtaining the return value of a function
-- Distinguishing built-in functions and user-defined functions
-- Distinguishing subroutines and functions
-- Stating whether arguments are passed by value or by reference

View file

@ -0,0 +1 @@
myMethod()

View file

@ -0,0 +1,3 @@
myMethod(List<String> list){
// If I change the contents of the list here, the caller will see the change
}

View file

@ -0,0 +1 @@
myMethod(97, 3.14)

View file

@ -0,0 +1,7 @@
int myMethod(int a, double b){
// return result of doing sums with a and b
}
int myMethod(int a){
return f(a, 1.414);
}

View file

@ -0,0 +1,2 @@
System.out.println( myMethod( 97, 3.14 ) );
System.out.println( myMethod( 97 ) );

View file

@ -0,0 +1,4 @@
void printAll(String... strings){
for ( String s : strings )
System.out.println( s );
}

View file

@ -0,0 +1,2 @@
printAll( "Freeman" );
printAll( "Freeman", "Hardy", "Willis" );

View file

@ -0,0 +1,5 @@
int myMethod( Map<String,Object> params ){
return
((Integer)params.get("x")).intValue()
+ ((Integer)params.get("y")).intValue();
}

View file

@ -0,0 +1 @@
System.out.println( myMethod(new HashMap<String,Object>(){{put("x",27);put("y",52);}}) );

View file

@ -0,0 +1 @@
int i = myMethod(x);

View file

@ -0,0 +1,57 @@
// no arguments
f()
// fixed arguments
def f(a, b) { ... } // as an aside, functions defined with 'def' use type inference for parameters and return types
f(1, 'a')
// optional arguments
def f(a, b = 0) { ... }
f("hello")
f("goodbye", 2)
f("hey", b = 2) // using the name makes more sense if there's more than one optional argument, obviously
// variable number of arguments
def f(params args) { ... }
def g(a, b, params rest) { ... }
f(1, 2, 3) // arguments should all have the same type or may be coerced to a supertype
g(1.0, 2, "a", "hello")
// named arguments
f(a = 'a', b = 0)
f(b = 0, a = 'a')
f('a', b = 0) // if mixing named and unnamed args, unnamed must be first and in correct order
// statement context
if (f(foo) == 42)
WriteLine($"$foo is the meaning to life, the universe and everything.")
else WriteLine($"$foo is meaningless.")
// first class function in an expression
def a = numList.FoldLeft(f)
// obtaining return value
def a = f(3)
// distinguishing built-in from user functions
// N/A?
// distinguishing subroutines from functions
// N/A
// stating whether passed by value or by reference
// .NET distinguishes between value types and reference types; if a reference type is passed by reference (using ref or out),
// the reference is passed by reference, which would allow a method to modify the object to which the reference refers
def f(a, ref b) { ... }
mutable someVar = "hey there" // doesn't make sense to pass immutable value by ref
f(2, ref someVar)
def g(a, out b) { ... }
mutable someOtherVar // if passed by ref using 'out', the variable needn't be initialized
g(2, out someOtherVar)
// partial application
def f(a, b) { ... }
def g = f(2, _)
def h = f(_, 2)
def a = g(3) // equivalent to: def a = f(2, 3)
def b = h(3) // equivalent to: def b = f(3, 2)

View file

@ -0,0 +1,137 @@
/*REXX program to demonstrate various methods of calling a REXX function*/
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function that REQUIRES no arguments.
In the REXX language, there is no way to require the caller to not
pass arguments, but the programmer can check if any arguments were
(or weren't) passed.
*/
yr=yearFunc()
say 'year=' yr
exit
yearFunc: procedure
if arg()\==0 then call sayErr "SomeFunc function won't accept arguments."
return left(date('Sorted'),3)
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function with a fixed number of arguments.
I take this to mean that the function requires a fixed number of
arguments. As above, REXX doesn't enforce calling (or invoking)
a (any) function with a certain number of arguments, but the
programmer can check if the correct number of arguments have been
specified (or not).
*/
ggg=FourFunc(12,abc,6+q,zz%2,'da 5th disagreement')
say 'ggg squared=' ggg**2
exit
FourFunc: procedure; parse arg a1,a2,a3; a4=arg(4) /*another way get a4*/
if arg()\==4 then do
call sayErr "FourFunc function requires 4 arguments,"
call sayErr "but instead it found" arg() 'arguments.'
exit 13
end
return a1+a2+a3+a4
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function with optional arguments.
Note that not passing an argument isn't the same as passing a null
argument (a REXX variable whose value is length zero).
*/
x=12; w=x/2; y=x**2; z=x//7 /* z is x modulo seven.*/
say 'sum of w, x, y, & z=' SumIt(w,x,y,,z) /*pass 5 args, 4th is null*/
exit
SumIt: procedure; sum=0
do j=1 for arg()
if arg(j,'E') then sum=sum+arg(j) /*the Jth arg may have been omitted*/
end
return sum
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function with a variable number of arguments.
This situation isn't any different then the previous example.
It's up to the programmer to code how to utilize the arguments.
*/
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function with named arguments.
REXX allows almost anything to be passed, so the following is one
way this can be accomplished.
*/
what=parserFunc('name=Luna',"gravity=.1654",'moon=yes')
say 'name=' common.name
gr=common.gr
say 'gravity=' gr
exit
parseFunc: procedure expose common.
do j=1 for arg()
parse var arg(j) name '=' val
upper name
call value 'COMMON.'name,val
end
return arg()
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function in statement context.
REXX allows functions to be called (invoked) two ways, the first
example (above) is calling a function in statement context.
*/
/*┌────────────────────────────────────────────────────────────────────┐
Calling a function in within an expression.
This is a variant of the first example.
*/
yr=yearFunc()+20
say 'two decades from now, the year will be:' yr
exit
/*┌────────────────────────────────────────────────────────────────────┐
Obtaining the return value of a function.
There are two ways to get the (return) value of a function.
*/
currYear=yearFunc()
say 'the current year is' currYear
call yearFunc
say 'the current year is' result
/*┌────────────────────────────────────────────────────────────────────┐
Distinguishing built-in functions and user-defined functions.
One objective of the REXX language is to allow the user to use any
function (or subroutine) name whether or not there is a built-in
function with the same name (there isn't a penality for this).
*/
qqq=date() /*number of real dates that Bob was on. */
say "Bob's been out" qqq 'times.'
www='DATE'('USA') /*returns date in format mm/dd/yyy */
exit /*any function in quotes is external. */
date: return 4
/*┌────────────────────────────────────────────────────────────────────┐
Distinguishing subroutines and functions.
There is no programatic difference between subroutines and
functions if the subroutine returns a value (which effectively
makes it a function). REXX allows you to call a function as if
it were a subroutine.
*/
/*┌────────────────────────────────────────────────────────────────────┐
In REXX, all arguments are passed by value, never by name, but it
is possible to accomplish this if the variable's name is passed
and the subroutine/function could use the built-in-function VALUE
to retrieve the variable's value.
*/
/*┌────────────────────────────────────────────────────────────────────┐
In the REXX language, partial application is possible, depending
how partial application is defined; I prefer the 1st definition (as
(as per the "discussion" for "Partial Function Application" task:
1. The "syntactic sugar" that allows one to write (some examples
are: map (f 7 9) [1..9]
or: map(f(7,_,9),{1,...,9})
*/

View file

@ -0,0 +1,77 @@
/* REXX ***************************************************************
* 29.07.2013 Walter Pachl trying to address the task concisely
***********************************************************************
* f1 Calling a function that requires no arguments
* f2 Calling a function with a fixed number of arguments
* f3 Calling a function with optional arguments
* f4 Calling a function with a variable number of arguments
* f5 Calling a function with named arguments
* f6 Using a function in statement context
* f7 Using a function within an expression
* f8 Obtaining the return value of a function
* f8(...) is replaced by the returned value
* call f8 ... returned value is in special vatiable RESULT
* f9 Distinguishing built-in functions and user-defined functions
* bif is enforced by using its name quoted in uppercase
* fa,fb Distinguishing subroutines and functions
* Stating whether arguments are passed by value or by reference
* Arguments are passed by value
* ooRexx supports passing by reference (Use Arg instruction)
* Is partial application possible and how
* no ideas
**********************************************************************/
say f1()
Say f2(1,2,3)
say f2(1,2,3,4)
say f3(1,,,4)
Say f4(1,2)
Say f4(1,2,3)
a=4700; b=11;
Say f5('A','B')
f6() /* returned value is used as command */
x=f7()**2
call f8 1,2; Say result '=' f8(1,2)
f9: Say 'DATE'('S') date()
call fa 11,22; Say result '=' fa(1,,
2) /* the second comma above is for line continuation */
Signal On Syntax
Call fb 1,2
x=fb(1,2)
Exit
f1: Return 'f1 doesn''t need an argument'
f2: If arg()=3 Then
Return 'f2: Sum of 3 arguments:' arg(1)+arg(2)+arg(3)
Else
Return 'f2: Invalid invocation:' arg() 'arguments. Needed: 3'
f3: sum=0
do i=1 To arg()
If arg(i,'E')=0 Then Say 'f3: Argument' i 'omitted'
Else sum=sum+arg(i)
End
Return 'f3 sum=' sum
f4: sum=0; Do i=1 To arg(); sum=sum+arg(i); End
Return 'f4: Sum of' arg() 'arguments is' sum
f5: Parse Arg p1,p2
Say 'f5: Argument 1 ('p1') contains' value(p1)
Say 'f5: Argument 2 ('p2') contains' value(p2)
Return 'f5: sum='value(p1)+value(p2)
f6: Say 'f6: dir ft.rex'
Return 'dir ft.rex'
f7: Say 'f7 returns 7'
Return 7
f8: Say 'f8 returns arg(1)+arg(2)'
Return arg(1)+arg(2)
date: Say 'date is my date function'
Return translate('ef/gh/abcd','DATE'('S'),'abcdefgh')
fa: Say 'fa returns arg(1)+arg(2)'
Return arg(1)+arg(2)
fb: Say 'fb:' arg(1)','arg(2)
Return
Syntax:
Say 'Syntax raised in line' sigl
Say sourceline(sigl)
Say 'rc='rc '('errortext(rc)')'
If sigl=39 Then
Say 'fb cannot be invoked as function (it does not return a value'
Exit