     import List, only: [flatten: 1]
     assert flatten([1, [2, 3]]) == [1, 2, 3]
   end
-  
+
   test "List of tuples syntax" do
     assert [flatten: 1, foo: "bar"] == [ { :flatten, 1 },{ :foo, "bar" }]
   end
-  
+
   test "Alias" do
     alias List, as: MyLinkedList
     import MyLinkedList, only: [flatten: 1]
     # NOTE: "alias This.That.FooBar" is the same as
     # alias This.That.FooBar, as: FooBar
   end
-  
+
   test "Attributes" do
     defmodule Hello do
       # Often used like constants in Ruby
       @planet "Earth"
-      
+
       def planet do
         @planet
       end
     end
-    
+
     assert Hello.planet == "Earth"
   end
+
+  test "Modules" do
+    # Elixir modules are actually... atoms of a specific form
+    assert List == :"Elixir.List"
+  end
+
+  test "ModulesAndFunctions-7 format" do
+    # formatting (calling io will apparently put on screen, so I call io_lib)
+    x = :io_lib.format("~.2f", [55.1234])
+    # at this point we have ['55.12'] rather than "55.12"
+    x = :erlang.iolist_to_binary(x)
+    assert x == "55.12"
+  end
+
+  test "ModulesAndFunctions-7 env var" do
+    # not overly needed, but just to practice a bit
+    import System, only: [get_env: 1]
+
+    assert get_env("_system_name") == "OSX"
+  end
+
+  test "ModulesAndFunctions-7 ext name" do
+    assert Path.extname("dave/dave_test.exs") == ".exs"
+  end
+
+  test "ModulesAndFunctions-7 current path" do
+    {:ok, _} = File.cwd()
+    _ = File.cwd!()
+
+    # raise error unless exit code is 0, using pattern matching
+    {output, 0} = System.cmd("pwd", [])
+
+    assert output |> String.strip == File.cwd!()
+  end
+
+  test "ModulesAndFunctions-7 parsing JSON" do
+    _ = "{\"age\":10,\"name\":\"Mael\"}"
+    # Exercise does not require to actually parse but just list libraries
+    # This one could work https://github.com/devinus/poison
+  end
 end

      # clauses must be grouped together!
      def of(n), do: n * of(n-1)
    end
    
    assert Factorial.of(0) == 1
    assert Factorial.of(1) == 1
    assert Factorial.of(3) == 6
  end
  
  test "ModulesAndFunctions-5" do
    defmodule GCD do
      def gcd(x,0), do: x
      def gcd(x,y), do: gcd(y, rem(x,y))
    end
    
    assert GCD.gcd(10,0) == 10
    assert GCD.gcd(10,5) == 5
  end
  
  test "Chop" do
    # defmodule Chop do
    #   def guess(n, (low.._)) when n == low, do: n
    #   def guess(n, (_..high)) when n == high, do: n
    #   def guess(n, (low..high)) when 
    #   def guess(_, (_.._)), do: "I don't know yet"
    # end
    
#    assert Chop.guess(1, (1..10)) == 1
#    assert Chop.guess(10, (1..10)) == 10
#    assert Chop.guess(4, (1..10)) == 4
  end
  
  test "Pipeline" do
    output = (1..10) |> Enum.map(&(&1 * 10)) |> Enum.filter(&(&1 > 50))
    assert output == [60, 70, 80, 90, 100]
  end
  
  test "Import" do
    # this is undocumented (afaik) but seems to work too
    # import List, [:flatten, 1]

  test "Passing functions as arguments" do
    times_2 = fn (x) -> 2 * x end
    apply = fn (fun, value) -> fun.(value) end

    assert apply.(times_2, 8) == 16
  end

  test "The & notation" do
    times_2 = &(&1 * 2)
    assert times_2.(9) == 18

    multiply = &(&1 * &2)
    assert multiply.(20, 10) == 200

    # Elixir will remove the indirection here
    # &(IO.puts(&1))
  end

  test "Tuples functions" do
    divrem = fn (a, b) -> { div(a, b), rem(a, b) } end
    assert divrem.(10, 3) == { 3, 1 }

    short_divrem = &{div(&1, &2), rem(&1, &2)}
    assert short_divrem.(10, 3) == { 3, 1 }
  end

  test "Exercise: Functions-5" do
    original = Enum.map [1,2,3,4], fn x -> x + 2 end
    rewritten = Enum.map [1,2,3,4], &(&1 + 2)
    assert original == rewritten

#    original = Enum.map [1,2,3,4], fn x -> IO.inspect(x) end
#    rewritten = Enum.map [1,2,3,4], &(IO.inspect(&1))
#    rewritten = Enum.map [1,2,3,4], &IO.inspect/1
#    assert original == rewritten
  end

  test "Module" do
    # woot, I can define a module here?
    defmodule Times do
