Functions are treated as first class citizens in Elixir. This means that:
Anonymous functions, in contrast to named functions, don't have a static reference available to them, they are only available if they are assigned to a variable or immediately invoked.
We might use anonymous functions to:
Anonymous functions start with the reserved word fn
, the arguments are separated from the body of the function with the ->
token, and they are finished with an end
. As with named functions, the last expression in the function is implicitly returned to the calling function.
To invoke a function reference, you must use a .
between the reference variable and the list of arguments:
function_variable = fn param ->
param + 1
end
function_variable.(1)
# => 2
You can even use short hand capture notation to make this more concise:
variable = &(&1 + 1)
variable.(1)
# => 2
Elixir supports many functions for working with bits found in the Bitwise module.
band/2
: bitwise ANDbsl/2
: bitwise SHIFT LEFTbsr/2
: bitwise SHIFT RIGHTbxor/2
: bitwise XORbor/2
: bitwise ORbnot/1
: bitwise NOTHere is an example of how to use a bitwise function:
Bitwise.bsl(1, 3)
# => 8
All bitwise functions only work on integers.
If you are running Elixir version 1.9 or lower, you will need to call require Bitwise
at the beginning of the module definition to be able to use the Bitwise module.
In this exercise, you've been tasked with writing the software for an encryption device that works by performing transformations on data. You need a way to flexibly create complicated functions by combining simpler functions together.
For each task, return an anonymous function that can be invoked from the calling scope.
All functions should expect integer arguments. Integers are also suitable for performing bitwise operations in Elixir.
Implement Secrets.secret_add/1
. It should return a function which takes one argument and adds to it the argument passed in to secret_add
.
adder = Secrets.secret_add(3)
adder.(2)
# => 5
Implement Secrets.secret_subtract/1
. It should return a function which takes one argument and subtracts the secret passed in to secret_subtract
from that argument.
subtractor = Secrets.secret_subtract(2)
subtractor.(3)
# => 1
Implement Secrets.secret_multiply/1
. It should return a function which takes one argument and multiplies it by the secret passed in to secret_multiply
.
multiplier = Secrets.secret_multiply(7)
multiplier.(3)
# => 21
Implement Secrets.secret_divide/1
. It should return a function which takes one argument and divides it by the secret passed in to secret_divide
.
divider = Secrets.secret_divide(3)
divider.(32)
# => 10
Make use of integer division so the output is compatible with the other functions' expected input.
Implement Secrets.secret_and/1
. It should return a function which takes one argument and performs a bitwise and operation on it and the secret passed in to secret_and
.
ander = Secrets.secret_and(1)
ander.(2)
# => 0
Implement Secrets.secret_xor/1
. It should return a function which takes one argument and performs a bitwise xor operation on it and the secret passed in to secret_xor
.
xorer = Secrets.secret_xor(1)
xorer.(3)
# => 2
Implement Secrets.secret_combine/2
. It should return a function which takes one argument and applies to it the two functions passed in to secret_combine
in order.
add_one = Secrets.secret_add(1)
multiply_by_2 = Secrets.secret_multiply(2)
combined = Secrets.secret_combine(add_one, multiply_by_2)
combined.(3)
# => 8
Sign up to Exercism to learn and master Elixir with 57 concepts, 159 exercises, and real human mentoring, all for free.