From c8d7c37f39dbb0b8762eca8dda76090fe8349c91 Mon Sep 17 00:00:00 2001 From: Felipe Sere Date: Wed, 13 Jan 2016 21:15:20 +0000 Subject: [PATCH 1/3] Koans for Elixir functions. --- lib/koans/05_functions.ex | 76 +++++++++++++++++++++++++++++++++++++++ lib/runner.ex | 3 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 lib/koans/05_functions.ex diff --git a/lib/koans/05_functions.ex b/lib/koans/05_functions.ex new file mode 100644 index 0000000..569aad7 --- /dev/null +++ b/lib/koans/05_functions.ex @@ -0,0 +1,76 @@ +defmodule Functions do + use Koans + + def inside() do + :light + end + # A function starts with 'def', has a 'do-end' pair + koan "it returns the last statement that was called" do + assert inside() == :light + end + + def quick_inline_add(a, b), do: a * b + koan "Short functions can be defined in a single line, but check the komma and colon!" do + assert quick_inline_add(2,3) == 6 + end + + # A function can have an argument between parentheses, after the name + def will_change(choice) do + if choice do + :it_was_truthy + else + "It really wasn't" + end + end + + koan "Can return different things" do + assert will_change(true) == :it_was_truthy + assert will_change(false) == "It really wasn't" + end + + def repeat(times, message) do + String.duplicate(message, times) + end + + koan "Functions can have more than one arguement" do + assert repeat(3, "Hello ") == "Hello Hello Hello " + end + + def repeat_again(times \\ 3, message) do + String.duplicate(message, times) + end + + koan "But sometimes, you may want to default some arguments" do + assert repeat_again("Hello ") == "Hello Hello Hello " + end + + def first(foo, bar), do: "#{foo} and #{bar}" + def first(foo), do: "only #{foo}" + koan "Functions are distinguished by name and arity - the number of arguments" do + assert first("One", "Two") == "One and Two" + assert first("One") == "only One" + end + + def sum_up(thing) when is_list(thing), do: :entire_list + def sum_up(thing), do: :single_thing + + koan "You can 'guard' functions against their arguments" do + assert sum_up([1,2,3]) == :entire_list + assert sum_up(1) == :single_thing + end + + def bigger(a,b) when a > b, do: "#{a} is bigger than #{b}" + def bigger(a,b) when a <= b, do: "#{a} is not bigger than #{b}" + koan "You can also create intricate guards based on the values" do + assert bigger(10, 5) == "10 is bigger than 5" + assert bigger(4, 27) == "4 is not bigger than 27" + end + + def the_length(0), do: "It was zero" + def the_length(number), do: "The length was #{number}" + + koan "You can also 'guard' with concrete values" do + assert the_length(0) == "It was zero" + assert the_length(5) == "The length was 5" + end +end diff --git a/lib/runner.ex b/lib/runner.ex index 82c98f7..a8f3664 100644 --- a/lib/runner.ex +++ b/lib/runner.ex @@ -1,9 +1,10 @@ defmodule Runner do @modules [ Equalities, + Strings, Lists, Maps, - Strings + Functions ] def run do From 8e91473ab8e153cde1beef9f24c2953f54f6b8b3 Mon Sep 17 00:00:00 2001 From: Felipe Sere Date: Wed, 13 Jan 2016 22:08:12 +0000 Subject: [PATCH 2/3] Add annonymous functions --- lib/koans/05_functions.ex | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/koans/05_functions.ex b/lib/koans/05_functions.ex index 569aad7..0f5e1a5 100644 --- a/lib/koans/05_functions.ex +++ b/lib/koans/05_functions.ex @@ -9,9 +9,9 @@ defmodule Functions do assert inside() == :light end - def quick_inline_add(a, b), do: a * b - koan "Short functions can be defined in a single line, but check the komma and colon!" do - assert quick_inline_add(2,3) == 6 + def quick_inline_product(a, b), do: a * b + koan "Short functions can be defined in a single line, but mind the comman and colon!" do + assert quick_inline_product(2,3) == 6 end # A function can have an argument between parentheses, after the name @@ -53,7 +53,6 @@ defmodule Functions do def sum_up(thing) when is_list(thing), do: :entire_list def sum_up(thing), do: :single_thing - koan "You can 'guard' functions against their arguments" do assert sum_up([1,2,3]) == :entire_list assert sum_up(1) == :single_thing @@ -68,9 +67,23 @@ defmodule Functions do def the_length(0), do: "It was zero" def the_length(number), do: "The length was #{number}" - koan "You can also 'guard' with concrete values" do assert the_length(0) == "It was zero" assert the_length(5) == "The length was 5" end + + koan "You can also define inline functions and call them with .()" do + multiply = fn (a,b) -> a * b end + assert multiply.(2,3) == 6 + end + + koan "You can even go shorter, by using &(..) and positional arguments" do + multiply = &(&1 * &2) + assert multiply.(2,3) == 6 + end + + def two_arguments(_first, second), do: second + koan "You can also show that certain arguments are ignored in the body by adding an underscore" do + assert two_arguments(:hi_there, "the other one") == "the other one" + end end From 15108425eaa77f504da1d0d24114ca7fd4e5c20b Mon Sep 17 00:00:00 2001 From: Felipe Sere Date: Wed, 13 Jan 2016 22:20:21 +0000 Subject: [PATCH 3/3] Add function capturing --- lib/koans/05_functions.ex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/koans/05_functions.ex b/lib/koans/05_functions.ex index 0f5e1a5..c791938 100644 --- a/lib/koans/05_functions.ex +++ b/lib/koans/05_functions.ex @@ -86,4 +86,10 @@ defmodule Functions do koan "You can also show that certain arguments are ignored in the body by adding an underscore" do assert two_arguments(:hi_there, "the other one") == "the other one" end + + def multiply_then_call(number, fun), do: fun.(number*5) + def square(number), do: number * number + koan "You can 'capture' functions if you want to pass them around as values" do + assert multiply_then_call(2, &square/1) == 100 + end end