# Function

## Python

#### Defining Function

Python 2.7
``````def greet():
print("Hello!")

greet()   # Hello!``````

Function is a block of code with a specific purpose that we encapsulate and run as many times as we want.

Functions are not run by themselves, and we should invoke (call) them to execute them.

Function can optionally return something one-time using the `return` keyword.

#### Arguments

Python 2.7
``````def add(a, b):
return a + b

val1 = add(2, 3)  # 5
val2 = add(3, 4)  # 7``````

Functions may receive inputs, which are called Arguments.

#### Anonymous Function

Python 2.7
``````sum = lambda a, b: a + b

val = sum(2, 3)  # 5``````

Anonymous Function in Python is called Lambda.

Lambda Functions can have any number of arguments but can only contain one expression in their block.

#### Default Argument

Python 2.7
``````def sum(a, b=1):
return a + b

val1 = sum(2)     # 3
val2 = sum(2, 3)  # 5``````

Default Arguments are arguments that have a value assigned to them by default, so whenever that argument is missing in the function call, that default value will be used.

Default Arguments should be the right most arguments in the function.

#### Keyword Arguments

Python 2.7
``````def sum(a, b=1):
return a + b

val1 = sum()      # Error: expect at least 1 argument
val2 = sum(2)     # 3
val3 = sum(2, 3)  # 5
val4 = sum(2, b=3)  # 5
val5 = sum(2, a=2)  # Error: multiple values for keyword argument
val6 = sum(a=2, 3)  # Error: non-keyword arg after keyword arg
val7 = sum(b=3, 2)  # Error: non-keyword arg after keyword arg
val8 = sum(a=2, b=3)  # 5
val9 = sum(b=3, a=2)  # 5``````

Arguments can also be passed to a function with key-value syntax.

The order of the Keyword Arguments is not important.

Keyword and Positional Arguments can be mixed in a function call.

Keyword Arguments should come after positional arguments in a function call.

#### Arbitrary Arguments

Python 2.7
``````def display(a, b, *positionals, **keywords):
print("a: " + str(a))
print("b: " + str(b))
print("Positionals: " + str(positionals))
print("Keywords: " + str(keywords))

display(1, 2, 3, 4)
# a: 1
# b: 2
# Positionals: (3, 4)
# Keywords: {}

display(1, 2, 3, d=4)
# a: 1
# b: 2
# Positionals: (3,)
# Keywords: {'d': 4}

display(1, 2, c=3, d=4)
# a: 1
# b: 2
# Positionals: ()
# Keywords: {'c': 3, 'd': 4}

display(1, b=2, c=3, d=4)
# a: 1
# b: 2
# Positionals: ()
# Keywords: {'c': 3, 'd': 4}

display(a=1, b=2, c=3 ,d=4)
# a: 1
# b: 2
# Positionals: ()
# Keywords: {'c': 3, 'd': 4}``````

If your function is intended to get a different number of arguments on each call, you can capture those extra arguments using Positional and Keyword arguments.

Positional Arguments are specified in the arguments list by `*`.

Positional Argument parameter has a type of Tuple.

Keyword Arguments are specified in the arguments list by `**`.

Keyword Argument parameter has a type of Dictionary.

You can use both Positional and Keyword arguments in your function definition at the same time.