2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -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>

View file

@ -0,0 +1 @@
PRINT SQR(2)

View file

@ -0,0 +1 @@
PRINT SQR 2

View file

@ -0,0 +1 @@
PRINT FN_foo(bar$, baz%)

View file

@ -0,0 +1 @@
PRINT FN_foo

View file

@ -0,0 +1 @@
PROC_foo

View file

@ -0,0 +1 @@
PROC_foo(bar$, baz%, quux)

View file

@ -0,0 +1 @@
DEF PROC_foo(a$, RETURN b%, RETURN c)

View file

@ -0,0 +1 @@
200 GOSUB 30050

View file

@ -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 */

View 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

View file

@ -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(*,*) '-----------------'

View 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.

View file

@ -0,0 +1,2 @@
H = A + B
IF (blah) H = 3*H - 7

View 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

View file

@ -0,0 +1,5 @@
TYPE MIXED
CHARACTER*12 NAME
INTEGER STUFF
END TYPE MIXED
TYPE(MIXED) LOTS(12000)

View 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);
}