2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,15 +1,21 @@
|
|||
The task is to demonstrate the different syntax and semantics provided for calling a function. This may include:
|
||||
* Calling a function that requires no arguments
|
||||
* Calling a function with a fixed number of arguments
|
||||
* Calling a function with [[Optional parameters|optional arguments]]
|
||||
* Calling a function with a [[Variadic function|variable number of arguments]]
|
||||
* Calling a function with [[Named parameters|named arguments]]
|
||||
* Using a function in statement context
|
||||
* Using a function in [[First-class functions|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 [[:Category:Parameter passing|passed]] by value or by reference
|
||||
* Is partial application possible and how
|
||||
;Task:
|
||||
Demonstrate the different syntax and semantics provided for calling a function.
|
||||
|
||||
|
||||
This may include:
|
||||
:* Calling a function that requires no arguments
|
||||
:* Calling a function with a fixed number of arguments
|
||||
:* Calling a function with [[Optional parameters|optional arguments]]
|
||||
:* Calling a function with a [[Variadic function|variable number of arguments]]
|
||||
:* Calling a function with [[Named parameters|named arguments]]
|
||||
:* Using a function in statement context
|
||||
:* Using a function in [[First-class functions|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 [[:Category:Parameter passing|passed]] by value or by reference
|
||||
;* Is partial application possible and how
|
||||
|
||||
<br>
|
||||
This task is ''not'' about [[Function definition|defining functions]].
|
||||
<br><bR>
|
||||
|
|
|
|||
1
Task/Call-a-function/BBC-BASIC/call-a-function-1.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-1.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
PRINT SQR(2)
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-2.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-2.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
PRINT SQR 2
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-3.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-3.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
PRINT FN_foo(bar$, baz%)
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-4.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-4.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
PRINT FN_foo
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-5.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-5.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
PROC_foo
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-6.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-6.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
PROC_foo(bar$, baz%, quux)
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-7.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-7.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
DEF PROC_foo(a$, RETURN b%, RETURN c)
|
||||
1
Task/Call-a-function/BBC-BASIC/call-a-function-8.bbc
Normal file
1
Task/Call-a-function/BBC-BASIC/call-a-function-8.bbc
Normal file
|
|
@ -0,0 +1 @@
|
|||
200 GOSUB 30050
|
||||
|
|
@ -30,8 +30,25 @@ void h(int a, ...)
|
|||
/* call it as: (if you feed it something it doesn't expect, don't count on it working) */
|
||||
h(1, 2, 3, 4, "abcd", (void*)0);
|
||||
|
||||
/* named arguments: no such thing */
|
||||
/* statement context: is that a real phrase? */
|
||||
/* named arguments: this is only possible through some pre-processor abuse
|
||||
*/
|
||||
struct v_args {
|
||||
int arg1;
|
||||
int arg2;
|
||||
char _sentinel;
|
||||
};
|
||||
|
||||
void _v(struct v_args args)
|
||||
{
|
||||
printf("%d, %d\n", args.arg1, args.arg2);
|
||||
}
|
||||
|
||||
#define v(...) _v((struct v_args){__VA_ARGS__})
|
||||
|
||||
v(.arg2 = 5, .arg1 = 17); // prints "17,5"
|
||||
/* NOTE the above implementation gives us optional typesafe optional arguments as well (unspecified arguments are initialized to zero)*/
|
||||
v(.arg2=1); // prints "0,1"
|
||||
v(); // prints "0,0"
|
||||
|
||||
/* as a first-class object (i.e. function pointer) */
|
||||
printf("%p", f); /* that's the f() above */
|
||||
|
|
|
|||
57
Task/Call-a-function/Elixir/call-a-function.elixir
Normal file
57
Task/Call-a-function/Elixir/call-a-function.elixir
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Anonymous function
|
||||
|
||||
foo = fn() ->
|
||||
IO.puts("foo")
|
||||
end
|
||||
|
||||
foo() #=> undefined function foo/0
|
||||
foo.() #=> "foo"
|
||||
|
||||
# Using `def`
|
||||
|
||||
defmodule Foo do
|
||||
def foo do
|
||||
IO.puts("foo")
|
||||
end
|
||||
end
|
||||
|
||||
Foo.foo #=> "foo"
|
||||
Foo.foo() #=> "foo"
|
||||
|
||||
|
||||
# Calling a function with a fixed number of arguments
|
||||
|
||||
defmodule Foo do
|
||||
def foo(x) do
|
||||
IO.puts(x)
|
||||
end
|
||||
end
|
||||
|
||||
Foo.foo("foo") #=> "foo"
|
||||
|
||||
# Calling a function with a default argument
|
||||
|
||||
defmodule Foo do
|
||||
def foo(x \\ "foo") do
|
||||
IO.puts(x)
|
||||
end
|
||||
end
|
||||
|
||||
Foo.foo() #=> "foo"
|
||||
Foo.foo("bar") #=> "bar"
|
||||
|
||||
# There is no such thing as a function with a variable number of arguments. So in Elixir, you'd call the function with a list
|
||||
|
||||
defmodule Foo do
|
||||
def foo(args) when is_list(args) do
|
||||
Enum.each(args, &(IO.puts(&1)))
|
||||
end
|
||||
end
|
||||
|
||||
# Calling a function with named arguments
|
||||
|
||||
defmodule Foo do
|
||||
def foo([x: x]) do
|
||||
IO.inspect(x)
|
||||
end
|
||||
end
|
||||
|
|
@ -22,7 +22,7 @@ write(*,*) 'named arguments: ', h(c=4,b=8,a=5)
|
|||
write(*,*) '-----------------'
|
||||
write(*,*) 'function in statement context: Does not apply!'
|
||||
write(*,*) '-----------------'
|
||||
write(*,*) 'Fortran passes memorty location of variables as arguments.'
|
||||
write(*,*) 'Fortran passes memory location of variables as arguments.'
|
||||
write(*,*) 'So an argument can hold the return value.'
|
||||
write(*,*) 'function result: ', g(5,8,lresult) , ' function successful? ', lresult
|
||||
write(*,*) '-----------------'
|
||||
4
Task/Call-a-function/Fortran/call-a-function-2.f
Normal file
4
Task/Call-a-function/Fortran/call-a-function-2.f
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
REAL this,that
|
||||
DIST(X,Y,Z) = SQRT(X**2 + Y**2 + Z**2) + this/that !One arithmetic statement, possibly lengthy.
|
||||
...
|
||||
D = 3 + DIST(X1 - X2,YDIFF,SQRT(ZD2)) !Invoke local function DIST.
|
||||
2
Task/Call-a-function/Fortran/call-a-function-3.f
Normal file
2
Task/Call-a-function/Fortran/call-a-function-3.f
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
H = A + B
|
||||
IF (blah) H = 3*H - 7
|
||||
25
Task/Call-a-function/Fortran/call-a-function-4.f
Normal file
25
Task/Call-a-function/Fortran/call-a-function-4.f
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
REAL FUNCTION INTG8(F,A,B,DX) !Integrate function F.
|
||||
EXTERNAL F !Some function of one parameter.
|
||||
REAL A,B !Bounds.
|
||||
REAL DX !Step.
|
||||
INTEGER N !A counter.
|
||||
INTG8 = F(A) + F(B) !Get the ends exactly.
|
||||
N = (B - A)/DX !Truncates. Ignore A + N*DX = B chances.
|
||||
DO I = 1,N !Step along the interior.
|
||||
INTG8 = INTG8 + F(A + I*DX) !Evaluate the function.
|
||||
END DO !On to the next.
|
||||
INTG8 = INTG8/(N + 2)*(B - A) !Average value times interval width.
|
||||
END FUNCTION INTG8 !This is not a good calculation!
|
||||
|
||||
FUNCTION TRIAL(X) !Some user-written function.
|
||||
REAL X
|
||||
TRIAL = 1 + X !This will do.
|
||||
END FUNCTION TRIAL !Not the name of a library function.
|
||||
|
||||
PROGRAM POKE
|
||||
INTRINSIC SIN !Thus, not an (undeclared) ordinary variable.
|
||||
EXTERNAL TRIAL !Likewise, but also, not an intrinsic function.
|
||||
REAL INTG8 !Don't look for the result in an integer place.
|
||||
WRITE (6,*) "Result=",INTG8(SIN, 0.0,8*ATAN(1.0),0.01)
|
||||
WRITE (6,*) "Linear=",INTG8(TRIAL,0.0,1.0, 0.01)
|
||||
END
|
||||
5
Task/Call-a-function/Fortran/call-a-function-5.f
Normal file
5
Task/Call-a-function/Fortran/call-a-function-5.f
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TYPE MIXED
|
||||
CHARACTER*12 NAME
|
||||
INTEGER STUFF
|
||||
END TYPE MIXED
|
||||
TYPE(MIXED) LOTS(12000)
|
||||
91
Task/Call-a-function/Rust/call-a-function.rust
Normal file
91
Task/Call-a-function/Rust/call-a-function.rust
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
fn main() {
|
||||
// Rust has a lot of neat things you can do with functions: let's go over the basics first
|
||||
fn no_args() {}
|
||||
// Run function with no arguments
|
||||
no_args();
|
||||
|
||||
// Calling a function with fixed number of arguments.
|
||||
// adds_one takes a 32-bit signed integer and returns a 32-bit signed integer
|
||||
fn adds_one(num: i32) -> i32 {
|
||||
// the final expression is used as the return value, though `return` may be used for early returns
|
||||
num + 1
|
||||
}
|
||||
adds_one(1);
|
||||
|
||||
// Optional arguments
|
||||
// The language itself does not support optional arguments, however, you can take advantage of
|
||||
// Rust's algebraic types for this purpose
|
||||
fn prints_argument(maybe: Option<i32>) {
|
||||
match maybe {
|
||||
Some(num) => println!("{}", num),
|
||||
None => println!("No value given"),
|
||||
};
|
||||
}
|
||||
prints_argument(Some(3));
|
||||
prints_argument(None);
|
||||
|
||||
// You could make this a bit more ergonomic by using Rust's Into trait
|
||||
fn prints_argument_into<I>(maybe: I)
|
||||
where I: Into<Option<i32>>
|
||||
{
|
||||
match maybe.into() {
|
||||
Some(num) => println!("{}", num),
|
||||
None => println!("No value given"),
|
||||
};
|
||||
}
|
||||
prints_argument_into(3);
|
||||
prints_argument_into(None);
|
||||
|
||||
// Rust does not support functions with variable numbers of arguments. Macros fill this niche
|
||||
// (println! as used above is a macro for example)
|
||||
|
||||
// Rust does not support named arguments
|
||||
|
||||
// We used the no_args function above in a no-statement context
|
||||
|
||||
// Using a function in an expression context
|
||||
adds_one(1) + adds_one(5); // evaluates to eight
|
||||
|
||||
// Obtain the return value of a function.
|
||||
let two = adds_one(1);
|
||||
|
||||
// In Rust there are no real built-in functions (save compiler intrinsics but these must be
|
||||
// manually imported)
|
||||
|
||||
// In rust there are no such thing as subroutines
|
||||
|
||||
// In Rust, there are three ways to pass an object to a function each of which have very important
|
||||
// distinctions when it comes to Rust's ownership model and move semantics. We may pass by
|
||||
// value, by immutable reference, or mutable reference.
|
||||
|
||||
let mut v = vec![1, 2, 3, 4, 5, 6];
|
||||
|
||||
// By mutable reference
|
||||
fn add_one_to_first_element(vector: &mut Vec<i32>) {
|
||||
vector[0] += 1;
|
||||
}
|
||||
add_one_to_first_element(&mut v);
|
||||
// By immutable reference
|
||||
fn print_first_element(vector: &Vec<i32>) {
|
||||
println!("{}", vector[0]);
|
||||
}
|
||||
print_first_element(&v);
|
||||
|
||||
// By value
|
||||
fn consume_vector(vector: Vec<i32>) {
|
||||
// We can do whatever we want to vector here
|
||||
}
|
||||
consume_vector(v);
|
||||
// Due to Rust's move semantics, v is now inaccessible because it was moved into consume_vector
|
||||
// and was then dropped when it went out of scope
|
||||
|
||||
// Partial application is not possible in rust without wrapping the function in another
|
||||
// function/closure e.g.:
|
||||
fn average(x: f64, y: f64) -> f64 {
|
||||
(x + y) / 2.0
|
||||
}
|
||||
let average_with_four = |y| average(4.0, y);
|
||||
average_with_four(2.0);
|
||||
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue