From cab5279258d788d6495a09598c75a376d79d55eb Mon Sep 17 00:00:00 2001 From: eksperimental Date: Fri, 17 Apr 2015 09:23:42 +0700 Subject: [PATCH] update links to docs to link to internal page/section --- _posts/2013-01-27-elixir-v0-8-0-released.markdown | 6 +++--- _posts/2013-04-29-elixir-v0-8-2-released.markdown | 2 +- _posts/2013-05-23-elixir-v0-9-0-released.markdown | 2 +- _posts/2013-07-13-elixir-v0-10-0-released.markdown | 8 ++++---- _posts/2013-08-08-elixir-design-goals.markdown | 4 ++-- _posts/2013-11-05-elixir-v0-11-0-released.markdown | 6 +++--- _posts/2014-04-21-elixir-v0-13-0-released.markdown | 12 ++++++------ _posts/2014-06-17-elixir-v0-14-0-released.markdown | 10 +++++----- _posts/2014-08-07-elixir-v0-15-0-released.markdown | 4 ++-- getting-started/basic-types.markdown | 2 +- .../binaries-strings-and-char-lists.markdown | 2 +- getting-started/case-cond-and-if.markdown | 2 +- getting-started/enumerables-and-streams.markdown | 12 ++++++------ getting-started/io-and-the-file-system.markdown | 10 +++++----- getting-started/maps-and-dicts.markdown | 8 ++++---- .../meta/domain-specific-languages.markdown | 2 +- getting-started/meta/macros.markdown | 4 ++-- getting-started/meta/quote-and-unquote.markdown | 2 +- getting-started/mix-otp/agent.markdown | 12 ++++++------ .../mix-otp/dependencies-and-umbrella-apps.markdown | 6 +++--- .../distributed-tasks-and-configuration.markdown | 10 +++++----- .../mix-otp/docs-tests-and-pipelines.markdown | 2 +- getting-started/mix-otp/genevent.markdown | 2 +- getting-started/mix-otp/genserver.markdown | 4 ++-- getting-started/mix-otp/introduction-to-mix.markdown | 4 ++-- .../mix-otp/supervisor-and-application.markdown | 8 ++++---- getting-started/mix-otp/task-and-gen-tcp.markdown | 6 +++--- getting-started/module-attributes.markdown | 4 ++-- getting-started/modules.markdown | 4 ++-- getting-started/processes.markdown | 4 ++-- getting-started/recursion.markdown | 2 +- getting-started/sigils.markdown | 2 +- getting-started/try-catch-and-rescue.markdown | 2 +- getting-started/typespecs-and-behaviours.markdown | 6 +++--- 34 files changed, 88 insertions(+), 88 deletions(-) diff --git a/_posts/2013-01-27-elixir-v0-8-0-released.markdown b/_posts/2013-01-27-elixir-v0-8-0-released.markdown index 7df2f3911..dbfb0a8ab 100644 --- a/_posts/2013-01-27-elixir-v0-8-0-released.markdown +++ b/_posts/2013-01-27-elixir-v0-8-0-released.markdown @@ -30,7 +30,7 @@ String.capitalize("fiN") #=> "Fin" The example above contains a string with only two codepoints, [the codepoint fi](http://www.fileformat.info/info/unicode/char/FB01/index.htm) and [the codepoint n](http://www.fileformat.info/info/unicode/char/006E/index.htm). Look how Elixir properly capitalizes the string, returning a new string made of three codepoints (all ascii letters). -Learn more about [Unicode support with the String module](/docs/stable/elixir/String.html). +Learn more about [Unicode support with the String module](/docs/stable/elixir/#!String.html). ## AST metadata @@ -70,11 +70,11 @@ When some code call the `unless` macro above, in previous Elixir versions, it wo Elixir v0.8 ensures that the `unless` macro above will expand to the same `if` macro available when quoted, guaranteeing different libraries can integrate easily without imposing hidden requirements. -You can read more about [macros in the getting started guide](/getting-started/case-cond-and-if.html) or [go deep into the quote macro docs](/docs/stable/elixir/Kernel.SpecialForms.html#quote/2). +You can read more about [macros in the getting started guide](/getting-started/case-cond-and-if.html) or [go deep into the quote macro docs](/docs/stable/elixir/#!Kernel.SpecialForms.html#quote/2). ## A new way to manipulate pathnames -Elixir v0.8 contains a bit of house cleaning too. We have created [the Path module](/docs/stable/elixir/Path.html) to accommodate functions used to manipulate filesystem paths and have also added functions like [`System.tmp_dir` and `System.user_home`](/docs/stable/elixir/System.html) which are meant to work accross different operating systems and are very handy when scripting. +Elixir v0.8 contains a bit of house cleaning too. We have created [the Path module](/docs/stable/elixir/#!Path.html) to accommodate functions used to manipulate filesystem paths and have also added functions like [`System.tmp_dir` and `System.user_home`](/docs/stable/elixir/#!System.html) which are meant to work accross different operating systems and are very handy when scripting. ## The new HashDict diff --git a/_posts/2013-04-29-elixir-v0-8-2-released.markdown b/_posts/2013-04-29-elixir-v0-8-2-released.markdown index 1524630ff..bbbf62c9f 100644 --- a/_posts/2013-04-29-elixir-v0-8-2-released.markdown +++ b/_posts/2013-04-29-elixir-v0-8-2-released.markdown @@ -44,6 +44,6 @@ defmodule MathTest do end ``` -You can learn more about [doctests on our documentation page](/docs/stable/ex_unit/ExUnit.DocTest.html) and get more information about our latest release [on the CHANGELOG](https://github.com/elixir-lang/elixir/blob/ed27611f48ba150404c95fe15f1d6058a4287330/CHANGELOG.md). +You can learn more about [doctests on our documentation page](/docs/stable/ex_unit/#!ExUnit.DocTest.html) and get more information about our latest release [on the CHANGELOG](https://github.com/elixir-lang/elixir/blob/ed27611f48ba150404c95fe15f1d6058a4287330/CHANGELOG.md). If you are new to Elixir, [it's easy to get started with](/getting-started/introduction.html)! diff --git a/_posts/2013-05-23-elixir-v0-9-0-released.markdown b/_posts/2013-05-23-elixir-v0-9-0-released.markdown index fbded71e5..47777ea12 100644 --- a/_posts/2013-05-23-elixir-v0-9-0-released.markdown +++ b/_posts/2013-05-23-elixir-v0-9-0-released.markdown @@ -123,7 +123,7 @@ A special thanks to [Eric Meadows-Jonsson](https://github.com/ericmj) for implem We have also many other smaller improvements: * Our CLI now supports `--hidden` and `--cookie` flags which are useful for distributed modes; -* Our test framework, ExUnit, is now able to capture all the communication that happens with a registed IO device, like `:stdio` and `:stderr`, via [`ExUnit.CaptureIO`](/docs/stable/ex_unit/ExUnit.CaptureIO.html). This is very useful for testing how your software reacts to some inputs and what it prints to the terminal; +* Our test framework, ExUnit, is now able to capture all the communication that happens with a registed IO device, like `:stdio` and `:stderr`, via [`ExUnit.CaptureIO`](/docs/stable/ex_unit/#!ExUnit.CaptureIO.html). This is very useful for testing how your software reacts to some inputs and what it prints to the terminal; * `IEx` now allows files to be imported into the shell with `import_file` and also loads `~/.iex` on startup for custom configuration; * The `String`, `Enum` and `Dict` modules got more convenience functions that goes from checking unicode character validity to taking values out of a dictionary; * And many, many more! diff --git a/_posts/2013-07-13-elixir-v0-10-0-released.markdown b/_posts/2013-07-13-elixir-v0-10-0-released.markdown index 14ee6202d..50d19cc2a 100644 --- a/_posts/2013-07-13-elixir-v0-10-0-released.markdown +++ b/_posts/2013-07-13-elixir-v0-10-0-released.markdown @@ -54,11 +54,11 @@ Stream.repeatedly(fn -> :random.uniform end) |> Enum.take(3) #=> [0.4435846174457203, 0.7230402056221108, 0.94581636451987] ``` -`Stream.repeatedly/1` returns an infinite stream but that's ok we just need its first three elements. You can learn more about [stream and related functions in `Stream` module documentation](/docs/stable/elixir/Stream.html). +`Stream.repeatedly/1` returns an infinite stream but that's ok we just need its first three elements. You can learn more about [stream and related functions in `Stream` module documentation](/docs/stable/elixir/#!Stream.html). ## Sets -This release also adds [the Sets API](/docs/stable/elixir/Set.html) to Elixir and a HashSet implementation. The HashSet implementation follows [the same design goals as the HashDict implementation](/blog/2013/01/27/elixir-v0-8-0-released/) released at the beginning of this year, starting with a compact representation and expanding and contracting as needed. +This release also adds [the Sets API](/docs/stable/elixir/#!Set.html) to Elixir and a HashSet implementation. The HashSet implementation follows [the same design goals as the HashDict implementation](/blog/2013/01/27/elixir-v0-8-0-released/) released at the beginning of this year, starting with a compact representation and expanding and contracting as needed. This feature was a contribution from [Joseph Wilk](https://github.com/josephwilk) and he talks about its implementation and provides some benchmarks [on his blog](http://blog.josephwilk.net/elixir/sets-in-elixir.html). @@ -66,7 +66,7 @@ This feature was a contribution from [Joseph Wilk](https://github.com/josephwilk Another addition to this release is pretty printing. The pretty printing started as an implementation of the [Wadler paper](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf) by [Jonns Mostovoys](https://github.com/manpages) which was then improved by [Gustavo Brunoro](https://github.com/brunoro) under his Google Summer of Code project as described in [Lindig's _Strictly Prettier_ paper](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2200). -As soon as you upgrade to Elixir v0.10.0 and start IEx, you will get pretty printing for all data structures provided by Elixir. We have also added documentation to the `Inspect` module about [adding pretty printing to your own structures](/docs/stable/elixir/Inspect.html) as well as [using the document algebra for any other kind of formatting](/docs/stable/elixir/Inspect.Algebra.html). +As soon as you upgrade to Elixir v0.10.0 and start IEx, you will get pretty printing for all data structures provided by Elixir. We have also added documentation to the `Inspect` module about [adding pretty printing to your own structures](/docs/stable/elixir/#!Inspect.html) as well as [using the document algebra for any other kind of formatting](/docs/stable/elixir/#!Inspect.Algebra.html). ## Other improvements @@ -78,7 +78,7 @@ Other notable improvements are: * We are also working hard on Windows support, improving its command-line tools and working towards a green test suite, thanks to [Tom Jansens](https://github.com/tojans); -* Meta-programming in Elixir was also improved by the addition of the `binding/0` and `binding/1` macros plus the additions of `Macro.expand_once/2` and `Macro.expand_all/2` to the [`Macro` module](/docs/stable/elixir/Macro.html); +* Meta-programming in Elixir was also improved by the addition of the `binding/0` and `binding/1` macros plus the additions of `Macro.expand_once/2` and `Macro.expand_all/2` to the [`Macro` module](/docs/stable/elixir/#!Macro.html); There are also improvements to typespecs, error messages, many bug fixes and some backwards incompatible changes. We have posted a detailed [upgrade instructions on the mailing list](https://groups.google.com/forum/?fromgroups#!topic/elixir-lang-talk/ksrefrgK1eY). For a general overview, [check out the CHANGELOG](https://github.com/elixir-lang/elixir/blob/v0.10.0/CHANGELOG.md). diff --git a/_posts/2013-08-08-elixir-design-goals.markdown b/_posts/2013-08-08-elixir-design-goals.markdown index 000e1fad7..3d3dde987 100644 --- a/_posts/2013-08-08-elixir-design-goals.markdown +++ b/_posts/2013-08-08-elixir-design-goals.markdown @@ -202,9 +202,9 @@ Enum.map set, fn(x) -> x * 2 end #=> [2,4,6] ``` -Not only that, any developer can **extend** the `Enum` module to work with any data type as long as the data type implements [the `Enumerable` protocol](/docs/stable/elixir/Enumerable.html) (protocols in Elixir are based on Clojure's protocol). This is extremely convenient because the developer needs to know only the `Enum` API for enumeration, instead of memorizing specific APIs for sets, lists, dicts, etc. +Not only that, any developer can **extend** the `Enum` module to work with any data type as long as the data type implements [the `Enumerable` protocol](/docs/stable/elixir/#!Enumerable.html) (protocols in Elixir are based on Clojure's protocol). This is extremely convenient because the developer needs to know only the `Enum` API for enumeration, instead of memorizing specific APIs for sets, lists, dicts, etc. -There are many other protocols exposed by the language, like [the `Inspect` protocol](/docs/stable/elixir/Inspect.html) for pretty printing data structures and [the `Access` protocol](/docs/stable/elixir/Access.html) for accessing key-value data by key. By being extensible, Elixir ensures developers can work **with** the language, instead of **against** the language. +There are many other protocols exposed by the language, like [the `Inspect` protocol](/docs/stable/elixir/#!Inspect.html) for pretty printing data structures and [the `Access` protocol](/docs/stable/elixir/#!Access.html) for accessing key-value data by key. By being extensible, Elixir ensures developers can work **with** the language, instead of **against** the language. ## Summing up diff --git a/_posts/2013-11-05-elixir-v0-11-0-released.markdown b/_posts/2013-11-05-elixir-v0-11-0-released.markdown index d139d9a46..3a320c171 100644 --- a/_posts/2013-11-05-elixir-v0-11-0-released.markdown +++ b/_posts/2013-11-05-elixir-v0-11-0-released.markdown @@ -22,7 +22,7 @@ In this new release, IEx also supports a very simple debugging mechanism called ![IEx pry example](/images/contents/iex-pry.png) -In Elixir, your code runs in many processes that talk to each other and the Elixir shell is no different. `IEx.pry` allows another process to take over the shell, allowing the developer to inspect the binding and halt the execution of the process being "pried" (i.e. the one that invoked `IEx.pry`). We called this feature `pry` as a gentle reminder that you can only inspect existing information, you cannot change the binding over a pried process. For more information, check the docs for [`IEx.pry/1`](/docs/stable/iex/IEx.html#pry/1). +In Elixir, your code runs in many processes that talk to each other and the Elixir shell is no different. `IEx.pry` allows another process to take over the shell, allowing the developer to inspect the binding and halt the execution of the process being "pried" (i.e. the one that invoked `IEx.pry`). We called this feature `pry` as a gentle reminder that you can only inspect existing information, you cannot change the binding over a pried process. For more information, check the docs for [`IEx.pry/1`](/docs/stable/iex/#!IEx.html#pry/1). ## ExUnit @@ -59,9 +59,9 @@ fun.(1..3) #=> true ``` -You can learn more about the [new capture operator in our docs](/docs/stable/elixir/Kernel.SpecialForms.html#&/1). +You can learn more about the [new capture operator in our docs](/docs/stable/elixir/#!Kernel.SpecialForms.html#&/1). -We have also pushed improvements to [the String module](/docs/stable/elixir/String.html), including new APIs. In particular, in order to know that `String.length("josé")` has length 4 (even though it takes 5 bytes to be represented in UTF-8), we need to use some algorithms defined by the Unicode Standard. These have been implemented as specified in the [extended grapheme cluster algorithm, defined in the version 6.3.0 of the Unicode Standard](http://www.unicode.org/reports/tr29/). +We have also pushed improvements to [the String module](/docs/stable/elixir/#!String.html), including new APIs. In particular, in order to know that `String.length("josé")` has length 4 (even though it takes 5 bytes to be represented in UTF-8), we need to use some algorithms defined by the Unicode Standard. These have been implemented as specified in the [extended grapheme cluster algorithm, defined in the version 6.3.0 of the Unicode Standard](http://www.unicode.org/reports/tr29/). In the optimization front, we have pushed the first iteration of a [feature called Protocol consolidation](https://groups.google.com/forum/#!topic/elixir-lang-core/RoXAUtoyjk4), which speeds up the polymorphic dispatch done by protocols, sometimes reducing the dispatching time to 10% of the original time. We will continue working in upcoming releases to integrate protocol consolidation as a regular part of the developer workflow. diff --git a/_posts/2014-04-21-elixir-v0-13-0-released.markdown b/_posts/2014-04-21-elixir-v0-13-0-released.markdown index e7a03841e..2ea150586 100644 --- a/_posts/2014-04-21-elixir-v0-13-0-released.markdown +++ b/_posts/2014-04-21-elixir-v0-13-0-released.markdown @@ -30,11 +30,11 @@ In a nutshell, here is what new: * The [Getting Started guide](/getting-started/introduction.html) was rewritten from scratch. The previous guide was comprised of 7 chapters and was about to become 2 years old. The new guide features 20 chapters, it explores the new maps and structs (which are part of this release), and it goes deeper into topics like IO and File handling. It also includes an extra guide, still in development, about [Meta-Programming in Elixir](/getting-started/meta/quote-and-unquote.html); -* Elixir v0.13 provides a new comprehension syntax that not only works with lists, but with any [`Enumerable`](/docs/stable/elixir/Enumerable.html). The output of a comprehension is also extensible via the [`Collectable`](/docs/stable/elixir/Collectable.html) protocol; +* Elixir v0.13 provides a new comprehension syntax that not only works with lists, but with any [`Enumerable`](/docs/stable/elixir/#!Enumerable.html). The output of a comprehension is also extensible via the [`Collectable`](/docs/stable/elixir/#!Collectable.html) protocol; * Mix, Elixir's build tool, has been improved in order to provide better workflows when compiling projects and working with dependencies; -* There are many other changes, like the addition of [StringIO](/docs/stable/elixir/StringIO.html), support for [tags and filters in ExUnit](/docs/stable/ex_unit/ExUnit.Case.html) and more. Please check the [CHANGELOG](https://github.com/elixir-lang/elixir/blob/v0.13.0/CHANGELOG.md) for the complete list. +* There are many other changes, like the addition of [StringIO](/docs/stable/elixir/#!StringIO.html), support for [tags and filters in ExUnit](/docs/stable/ex_unit/#!ExUnit.Case.html) and more. Please check the [CHANGELOG](https://github.com/elixir-lang/elixir/blob/v0.13.0/CHANGELOG.md) for the complete list. Even with all those improvements, Elixir v0.13.0 is backwards compatible with Elixir v0.12.5 and upgrading should be a clean process. @@ -68,7 +68,7 @@ iex> %{"other" => value} = map A map pattern will match any map that has all the keys specified in the pattern. The values for the matching keys must also match. For example, `%{"hello" => world}` will match any map that has the key `"hello"` and assign the value to `world`, while `%{"hello" => "world"}` will match any map that has the key `"hello"` with value equals to `"world"`. An empty map pattern (`%{}`) will match all maps. -Developers can use the functions in the [`Map` module](/docs/stable/elixir/Map.html) to work with maps. For more information on maps and how they compare to other associative data structures in the language, please check the [Maps chapter in our new Getting Started guide](/getting-started/maps-and-dicts.html). Elixir Sips has also released two episodes that cover maps ([part 1](http://elixirsips.com/episodes/054_maps_part_1.html) and [part 2](http://elixirsips.com/episodes/055_maps_part_2.html)). +Developers can use the functions in the [`Map` module](/docs/stable/elixir/#!Map.html) to work with maps. For more information on maps and how they compare to other associative data structures in the language, please check the [Maps chapter in our new Getting Started guide](/getting-started/maps-and-dicts.html). Elixir Sips has also released two episodes that cover maps ([part 1](http://elixirsips.com/episodes/054_maps_part_1.html) and [part 2](http://elixirsips.com/episodes/055_maps_part_2.html)). Maps also provide special syntax for creating, accessing and updating maps with atom keys: @@ -185,7 +185,7 @@ For more information on structs, check out the [Structs chapter in the getting s With the introduction of maps and structs, some deprecations will arrive on upcoming releases. First of all, the `ListDict` data structure is being deprecated and phased out. Records are also being deprecated from the language, although it is going to be a longer process, as many projects and Elixir itself still use records in diverse occasions. -Note though only Elixir records are being deprecated. Erlang records, which are basically syntax sugar around tuples, will remain in the language for the rare cases Elixir developers need to interact with Erlang libraries that provide records. In particular, the [Record](/docs/stable/elixir/Record.html) has been updated to provide the new Record API (while keeping the old one for backwards compatibility). +Note though only Elixir records are being deprecated. Erlang records, which are basically syntax sugar around tuples, will remain in the language for the rare cases Elixir developers need to interact with Erlang libraries that provide records. In particular, the [Record](/docs/stable/elixir/#!Record.html) has been updated to provide the new Record API (while keeping the old one for backwards compatibility). Finally, structs are still in active development and new features, like `@derive`, should land in upcoming Elixir releases. For those interested, the [original maps and structs proposal is still availble](https://gist.github.com/josevalim/b30c881df36801611d13). @@ -222,7 +222,7 @@ iex> for <>, c != ?\s, into: "", do: <> "helloworld" ``` -Sets, maps and other dictionaries can also be given with the `:into` option. In general, the `:into` accepts any structure as long as it implements the [`Collectable` protocol](/docs/stable/elixir/Collectable.html). +Sets, maps and other dictionaries can also be given with the `:into` option. In general, the `:into` accepts any structure as long as it implements the [`Collectable` protocol](/docs/stable/elixir/#!Collectable.html). For example, the `IO` module provides streams, that are both `Enumerable` and `Collectable`. You can implement an echo terminal that returns whatever is typed into the shell, but in upcase, using comprehensions: @@ -275,7 +275,7 @@ That said, in the next months we plan to: * Integrate applications configuration (provided by OTP) right into Mix; * Provide an Elixir logger that knows how to print and format Elixir exceptions and stacktraces; -* Properly expose the functionality provided by Applications, Supervisors, GenServers and GenEvents and study how they can integrate with Elixir. For example, how to consume events from GenEvent as a [stream of data](/docs/stable/elixir/Stream.html)? +* Properly expose the functionality provided by Applications, Supervisors, GenServers and GenEvents and study how they can integrate with Elixir. For example, how to consume events from GenEvent as a [stream of data](/docs/stable/elixir/#!Stream.html)? * Study how patterns like tasks and agents can be integrated into the language, often picking up the lessons learned by libraries like [e2](http://e2project.org/erlang.html) and [functionality exposed by OTP itself](http://erlang.org/doc/man/rpc.html); * Rewrite the Mix and ExUnit guides to focus on applications and OTP as a whole, rebranding it to "Building Apps with Mix and OTP"; diff --git a/_posts/2014-06-17-elixir-v0-14-0-released.markdown b/_posts/2014-06-17-elixir-v0-14-0-released.markdown index 1c3d56fb2..fed504613 100644 --- a/_posts/2014-06-17-elixir-v0-14-0-released.markdown +++ b/_posts/2014-06-17-elixir-v0-14-0-released.markdown @@ -40,7 +40,7 @@ Structs allow us to provide default values for a map fields. Structs also valida #=> ** (CompileError) iex:2: unknown key :unknown for struct User ``` -We say structs are *raw* because they do not implement any of the protocols that are implemented for maps by default. For instance, we can call `Enum.each/2` for a map, which uses the [`Enumerable`](/docs/stable/elixir/Enumerable.html) protocol: +We say structs are *raw* because they do not implement any of the protocols that are implemented for maps by default. For instance, we can call `Enum.each/2` for a map, which uses the [`Enumerable`](/docs/stable/elixir/#!Enumerable.html) protocol: ```elixir Enum.each %{foo: :bar}, fn {k, v} -> @@ -134,15 +134,15 @@ update_in dungeon.rooms[room_id].users[user_id].device_codes, &Set.delete(&1, co put_in dungeon, [:rooms, room_id, :users, user_id, :username], "new username" ``` -You can read more information about nested access in [the Access protocol documentation](/docs/stable/elixir/Access.html) and in the docs for [`get_in/2`](/docs/stable/elixir/Kernel.html#get_in/2) and friends. +You can read more information about nested access in [the Access protocol documentation](/docs/stable/elixir/#!Access.html) and in the docs for [`get_in/2`](/docs/stable/elixir/#!Kernel.html#get_in/2) and friends. ## Mix and OTP OTP is a set of libraries that ships with Erlang. Erlang developers use OTP to build robust, fault-tolerant applications. -In v0.14.0, Elixir closely integrates with OTP by providing modules for building [servers](/docs/stable/elixir/GenServer.html), [event managers and event handlers](/docs/stable/elixir/GenEvent.html), [supervisors](/docs/stable/elixir/Supervisor.html) and [applications](/docs/stable/elixir/Application.html). +In v0.14.0, Elixir closely integrates with OTP by providing modules for building [servers](/docs/stable/elixir/#!GenServer.html), [event managers and event handlers](/docs/stable/elixir/#!GenEvent.html), [supervisors](/docs/stable/elixir/#!Supervisor.html) and [applications](/docs/stable/elixir/#!Application.html). -We have also introduced the concepts of [agents](/docs/stable/elixir/Agent.html) and the idea of [tasks](/docs/stable/elixir/Task.html), which can be supervised and distributed. Application configuration has been made first class in Mix, allowing developers to configure their dependencies, sometimes even using different configurations per environment (dev, test or prod by default). +We have also introduced the concepts of [agents](/docs/stable/elixir/#!Agent.html) and the idea of [tasks](/docs/stable/elixir/#!Task.html), which can be supervised and distributed. Application configuration has been made first class in Mix, allowing developers to configure their dependencies, sometimes even using different configurations per environment (dev, test or prod by default). This functionality is at the core of building applications in Erlang and Elixir. For this reason we have published a new guide called [Mix and OTP](/getting-started/mix-otp/introduction-to-mix.html) where we build a distributed key-value store to help explore all concepts mentioned above. The guide is quite fresh, so please do submit pull requests for typos and mistakes. Feedback is also welcome! @@ -154,7 +154,7 @@ With v0.14.0 we have reached many of the milestones [we have set in the previous * Provide an Elixir logger that knows how to print and format Elixir exceptions and stacktraces. Work has already started on this front as Elixir already prints errors coming from the application startup nicely; -* Continue the work of cleaning up the [Kernel module](/docs/stable/elixir/Kernel.html). In v0.14.0, we added alternatives for conversion functions, like `integer_to_binary/1` to `Integer.to_string/1`, now they must be properly deprecated and removed; +* Continue the work of cleaning up the [Kernel module](/docs/stable/elixir/#!Kernel.html). In v0.14.0, we added alternatives for conversion functions, like `integer_to_binary/1` to `Integer.to_string/1`, now they must be properly deprecated and removed; * Support mix aliases, allowing developers to easily define Mix shortcuts for their favorite tasks; diff --git a/_posts/2014-08-07-elixir-v0-15-0-released.markdown b/_posts/2014-08-07-elixir-v0-15-0-released.markdown index e99195121..db445b552 100644 --- a/_posts/2014-08-07-elixir-v0-15-0-released.markdown +++ b/_posts/2014-08-07-elixir-v0-15-0-released.markdown @@ -16,7 +16,7 @@ If you are interested in the specific details for this release, [please check ou ## Logger -Elixir now ships with a new application called logger. This application provides [the Logger module](/docs/stable/logger/Logger.html), which is the main API developers will use for logging: +Elixir now ships with a new application called logger. This application provides [the Logger module](/docs/stable/logger/#!Logger.html), which is the main API developers will use for logging: ```elixir require Logger @@ -70,7 +70,7 @@ Function: #Function<20.90072148/0 in :erl_eval.expr/5> As soon as we started working on Logger, we realized we could go further than simply translating Erlang messages and provide a fully featured logger library. At this moment, Logger also supports: * 4 log levels: debug, info, warn and error - * Custom formatting: you can specify a format string that tells exactly how messages should be logged. The default string is: "$time $metadata[$level] $message\n" but [many attributes are supported](/docs/stable/logger/Logger.Formatter.html) + * Custom formatting: you can specify a format string that tells exactly how messages should be logged. The default string is: "$time $metadata[$level] $message\n" but [many attributes are supported](/docs/stable/logger/#!Logger.Formatter.html) * Custom translators: so you can translate log messages coming from any Erlang application into Elixir syntax * Metadata: metadata allows developers to store information in the current process that will be available to all logged messages. For example, a web application can generate a `request_id`, store it as metadata, and all messages logged during that request will be properly identified with `request_id=...` in the log diff --git a/getting-started/basic-types.markdown b/getting-started/basic-types.markdown index 66fd15118..d7e892f10 100644 --- a/getting-started/basic-types.markdown +++ b/getting-started/basic-types.markdown @@ -186,7 +186,7 @@ iex> String.length("hellö") 5 ``` -The [String module](/docs/stable/elixir/String.html) contains a bunch of functions that operate on strings as defined in the Unicode standard: +The [String module](/docs/stable/elixir/#!String.html) contains a bunch of functions that operate on strings as defined in the Unicode standard: ```iex iex> String.upcase("hellö") diff --git a/getting-started/binaries-strings-and-char-lists.markdown b/getting-started/binaries-strings-and-char-lists.markdown index 930b86901..e73c72456 100644 --- a/getting-started/binaries-strings-and-char-lists.markdown +++ b/getting-started/binaries-strings-and-char-lists.markdown @@ -49,7 +49,7 @@ iex> ?ł 322 ``` -You can also use the functions in [the `String` module](/docs/stable/elixir/String.html) to split a string in its code points: +You can also use the functions in [the `String` module](/docs/stable/elixir/#!String.html) to split a string in its code points: ```iex iex> String.codepoints("hełło") diff --git a/getting-started/case-cond-and-if.markdown b/getting-started/case-cond-and-if.markdown index d9000c222..33d1960aa 100644 --- a/getting-started/case-cond-and-if.markdown +++ b/getting-started/case-cond-and-if.markdown @@ -202,7 +202,7 @@ iex> if nil do "This will" ``` -> Note: An interesting note regarding `if/2` and `unless/2` is that they are implemented as macros in the language; they aren't special language constructs as they would be in many languages. You can check the documentation and the source of `if/2` in [the `Kernel` module docs](/docs/stable/elixir/Kernel.html). The `Kernel` module is also where operators like `+/2` and functions like `is_function/2` are defined, all automatically imported and available in your code by default. +> Note: An interesting note regarding `if/2` and `unless/2` is that they are implemented as macros in the language; they aren't special language constructs as they would be in many languages. You can check the documentation and the source of `if/2` in [the `Kernel` module docs](/docs/stable/elixir/#!Kernel.html). The `Kernel` module is also where operators like `+/2` and functions like `is_function/2` are defined, all automatically imported and available in your code by default. ## `do/end` blocks diff --git a/getting-started/enumerables-and-streams.markdown b/getting-started/enumerables-and-streams.markdown index 969bbf5f7..c6603e20d 100644 --- a/getting-started/enumerables-and-streams.markdown +++ b/getting-started/enumerables-and-streams.markdown @@ -10,7 +10,7 @@ redirect_from: /getting_started/10.html ## Enumerables -Elixir provides the concept of enumerables and [the `Enum` module](/docs/stable/elixir/Enum.html) to work with them. We have already learned two enumerables: lists and maps. +Elixir provides the concept of enumerables and [the `Enum` module](/docs/stable/elixir/#!Enum.html) to work with them. We have already learned two enumerables: lists and maps. ```iex iex> Enum.map([1, 2, 3], fn x -> x * 2 end) @@ -30,9 +30,9 @@ iex> Enum.reduce(1..3, 0, &+/2) 6 ``` -Since the Enum module was designed to work across different data types, its API is limited to functions that are useful across many data types. For specific operations, you may need to reach to modules specific to the data types. For example, if you want to insert an element at a given position in a list, you should use the `List.insert_at/3` function from [the `List` module](/docs/stable/elixir/List.html), as it would make little sense to insert a value into, for example, a range. +Since the Enum module was designed to work across different data types, its API is limited to functions that are useful across many data types. For specific operations, you may need to reach to modules specific to the data types. For example, if you want to insert an element at a given position in a list, you should use the `List.insert_at/3` function from [the `List` module](/docs/stable/elixir/#!List.html), as it would make little sense to insert a value into, for example, a range. -We say the functions in the `Enum` module are polymorphic because they can work with diverse data types. In particular, the functions in the `Enum` module can work with any data type that implements [the `Enumerable` protocol](/docs/stable/elixir/Enumerable.html). We are going to discuss Protocols in a later chapter, for now we are going to move on to a specific kind of enumerable called streams. +We say the functions in the `Enum` module are polymorphic because they can work with diverse data types. In particular, the functions in the `Enum` module can work with any data type that implements [the `Enumerable` protocol](/docs/stable/elixir/#!Enumerable.html). We are going to discuss Protocols in a later chapter, for now we are going to move on to a specific kind of enumerable called streams. ## Eager vs Lazy @@ -63,11 +63,11 @@ iex> Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?)) 7500000000 ``` -Find more about the pipe operator [by reading its documentation](/docs/stable/elixir/Kernel.html#|>/2). +Find more about the pipe operator [by reading its documentation](/docs/stable/elixir/#!Kernel.html#|>/2). ## Streams -As an alternative to `Enum`, Elixir provides [the `Stream` module](/docs/stable/elixir/Stream.html) which supports lazy operations: +As an alternative to `Enum`, Elixir provides [the `Stream` module](/docs/stable/elixir/#!Stream.html) which supports lazy operations: ```iex iex> 1..100_000 |> Stream.map(&(&1 * 3)) |> Stream.filter(odd?) |> Enum.sum @@ -119,6 +119,6 @@ iex> Enum.take(stream, 10) The example above will fetch the first 10 lines of the file you have selected. This means streams can be very useful for handling large files or even slow resources like network resources. -The amount of functions and functionality in [`Enum`](/docs/stable/elixir/Enum.html) and [`Stream`](/docs/stable/elixir/Stream.html) modules can be daunting at first but you will get familiar with them case by case. In particular, focus on the `Enum` module first and only move to `Stream` for the particular scenarios where laziness is required to either deal with slow resources or large, possibly infinite, collections. +The amount of functions and functionality in [`Enum`](/docs/stable/elixir/#!Enum.html) and [`Stream`](/docs/stable/elixir/#!Stream.html) modules can be daunting at first but you will get familiar with them case by case. In particular, focus on the `Enum` module first and only move to `Stream` for the particular scenarios where laziness is required to either deal with slow resources or large, possibly infinite, collections. Next we'll look at a feature central to Elixir, Processes, which allows us to write concurrent, parallel and distributed programs in an easy and understandable way. diff --git a/getting-started/io-and-the-file-system.markdown b/getting-started/io-and-the-file-system.markdown index c890aa59d..334278fe1 100644 --- a/getting-started/io-and-the-file-system.markdown +++ b/getting-started/io-and-the-file-system.markdown @@ -8,7 +8,7 @@ redirect_from: /getting_started/12.html {% include toc.html %} -This chapter is a quick introduction to input/output mechanisms and file-system-related tasks, as well as to related modules like [`IO`](/docs/stable/elixir/IO.html), [`File`](/docs/stable/elixir/File.html) and [`Path`](/docs/stable/elixir/Path.html). +This chapter is a quick introduction to input/output mechanisms and file-system-related tasks, as well as to related modules like [`IO`](/docs/stable/elixir/#!IO.html), [`File`](/docs/stable/elixir/#!File.html) and [`Path`](/docs/stable/elixir/#!Path.html). We had originally sketched this chapter to come much earlier in the getting started guide. However, we noticed the IO system provides a great opportunity to shed some light on some philosophies and curiosities of Elixir and the VM. @@ -35,7 +35,7 @@ hello world ## The `File` module -The [`File`](/docs/stable/elixir/File.html) module contains functions that allow us to open files as IO devices. By default, files are opened in binary mode, which requires developers to use the specific `IO.binread/2` and `IO.binwrite/2` functions from the `IO` module: +The [`File`](/docs/stable/elixir/#!File.html) module contains functions that allow us to open files as IO devices. By default, files are opened in binary mode, which requires developers to use the specific `IO.binread/2` and `IO.binwrite/2` functions from the `IO` module: ```iex iex> {:ok, file} = File.open "hello", [:write] @@ -86,7 +86,7 @@ If you don't want to handle a possible error (i.e., you want it to bubble up), p ## The `Path` module -The majority of the functions in the `File` module expect paths as arguments. Most commonly, those paths will be regular binaries. The [`Path`](/docs/stable/elixir/Path.html) module provides facilities for working with such paths: +The majority of the functions in the `File` module expect paths as arguments. Most commonly, those paths will be regular binaries. The [`Path`](/docs/stable/elixir/#!Path.html) module provides facilities for working with such paths: ```iex iex> Path.join("foo", "bar") @@ -122,7 +122,7 @@ iex> IO.write(pid, "hello") After `IO.write/2`, we can see the request sent by the `IO` module (a four-elements tuple) printed out. Soon after that, we see that it fails since the `IO` module expected some kind of result that we did not supply. -The [`StringIO`](/docs/stable/elixir/StringIO.html) module provides an implementation of the `IO` device messages on top of strings: +The [`StringIO`](/docs/stable/elixir/#!StringIO.html) module provides an implementation of the `IO` device messages on top of strings: ```iex iex> {:ok, pid} = StringIO.open("hello") @@ -167,4 +167,4 @@ On the other hand, `:stdio` and files opened with `:utf8` encoding work with the Although this is a subtle difference, you only need to worry about those details if you intend to pass lists to those functions. Binaries are already represented by the underlying bytes and as such their representation is always raw. -This finishes our tour of IO devices and IO related functionality. We have learned about four Elixir modules - [`IO`](/docs/stable/elixir/IO.html), [`File`](/docs/stable/elixir/File.html), [`Path`](/docs/stable/elixir/Path.html) and [`StringIO`](/docs/stable/elixir/StringIO.html) - as well as how the VM uses processes for the underlying IO mechanisms and how to use `chardata` and `iodata` for IO operations. +This finishes our tour of IO devices and IO related functionality. We have learned about four Elixir modules - [`IO`](/docs/stable/elixir/#!IO.html), [`File`](/docs/stable/elixir/#!File.html), [`Path`](/docs/stable/elixir/#!Path.html) and [`StringIO`](/docs/stable/elixir/#!StringIO.html) - as well as how the VM uses processes for the underlying IO mechanisms and how to use `chardata` and `iodata` for IO operations. diff --git a/getting-started/maps-and-dicts.markdown b/getting-started/maps-and-dicts.markdown index 822ac69b9..206b1e678 100644 --- a/getting-started/maps-and-dicts.markdown +++ b/getting-started/maps-and-dicts.markdown @@ -76,7 +76,7 @@ iex> if(false, [do: :this, else: :that]) In general, when the keyword list is the last argument of a function, the square brackets are optional. -In order to manipulate keyword lists, Elixir provides [the `Keyword` module](/docs/stable/elixir/Keyword.html). Remember though keyword lists are simply lists, and as such they provide the same linear performance characteristics as lists. The longer the list, the longer it will take to find a key, to count the number of items, and so on. For this reason, keyword lists are used in Elixir mainly as options. If you need to store many items or guarantee one-key associates with at maximum one-value, you should use maps instead. +In order to manipulate keyword lists, Elixir provides [the `Keyword` module](/docs/stable/elixir/#!Keyword.html). Remember though keyword lists are simply lists, and as such they provide the same linear performance characteristics as lists. The longer the list, the longer it will take to find a key, to count the number of items, and so on. For this reason, keyword lists are used in Elixir mainly as options. If you need to store many items or guarantee one-key associates with at maximum one-value, you should use maps instead. Although we can pattern match on keyword lists, it is rarely done in practice since pattern matching on lists require the number of items and their order to match: @@ -140,7 +140,7 @@ iex> %{:c => c} = %{:a => 1, 2 => :b} As shown above, a map matches as long as the given keys exist in the given map. Therefore, an empty map matches all maps. -[The `Map` module](/docs/stable/elixir/Map.html) provides a very similar API to the `Keyword` module with convenience functions to manipulate maps: +[The `Map` module](/docs/stable/elixir/#!Map.html) provides a very similar API to the `Keyword` module with convenience functions to manipulate maps: ```iex iex> Map.get(%{:a => 1, 2 => :b}, :a) @@ -170,13 +170,13 @@ Both access and update syntaxes above require the given keys to exist. For examp Elixir developers typically prefer to use the `map.field` syntax and pattern matching instead of the functions in the `Map` module when working with maps because they lead to an assertive style of programming. [This blog post](http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/) provides insight and examples on how you get more concise and faster software by writing assertive code in Elixir. -> Note: Maps were recently introduced into the Erlang VM with [EEP 43](http://www.erlang.org/eeps/eep-0043.html "Erlang Enhancement Proposal #43: Maps"). Erlang 17 provides a partial implementation of the EEP, where only "small maps" are supported. This means maps have good performance characteristics only when storing at maximum a couple of dozens keys. To fill in this gap, Elixir also provides [the `HashDict` module](/docs/stable/elixir/HashDict.html) which uses a hashing algorithm to provide a dictionary that supports hundreds of thousands keys with good performance. +> Note: Maps were recently introduced into the Erlang VM with [EEP 43](http://www.erlang.org/eeps/eep-0043.html "Erlang Enhancement Proposal #43: Maps"). Erlang 17 provides a partial implementation of the EEP, where only "small maps" are supported. This means maps have good performance characteristics only when storing at maximum a couple of dozens keys. To fill in this gap, Elixir also provides [the `HashDict` module](/docs/stable/elixir/#!HashDict.html) which uses a hashing algorithm to provide a dictionary that supports hundreds of thousands keys with good performance. ## Dicts In Elixir, both keyword lists and maps are called dictionaries. In other words, a dictionary is like an interface (we call them behaviours in Elixir) and both keyword lists and maps modules implement this interface. -This interface is defined in the [the `Dict` module](/docs/stable/elixir/Dict.html) module which also provides an API that delegates to the underlying implementations: +This interface is defined in the [the `Dict` module](/docs/stable/elixir/#!Dict.html) module which also provides an API that delegates to the underlying implementations: ```iex iex> keyword = [] diff --git a/getting-started/meta/domain-specific-languages.markdown b/getting-started/meta/domain-specific-languages.markdown index 61c2420e0..ce1c2905a 100644 --- a/getting-started/meta/domain-specific-languages.markdown +++ b/getting-started/meta/domain-specific-languages.markdown @@ -162,4 +162,4 @@ Running test hello Although we have overlooked some details, this is the main idea behind creating domain specific modules in Elixir. Macros enable us to return quoted expressions that are executed in the caller, which we can then use to transform code and store relevant information in the target module via module attributes. Finally, callbacks such as `@before_compile` allow us to inject code into the module when its definition is complete. -Besides `@before_compile`, there are other useful module attributes like `@on_definition` and `@after_compile`, which you can read more about in [the docs for the `Module` module](/docs/stable/elixir/Module.html). You can also find useful information about macros and the compilation environment in the documentation for the [`Macro` module](/docs/stable/elixir/Macro.html) and [`Macro.Env`](/docs/stable/elixir/Macro.Env.html). +Besides `@before_compile`, there are other useful module attributes like `@on_definition` and `@after_compile`, which you can read more about in [the docs for the `Module` module](/docs/stable/elixir/#!Module.html). You can also find useful information about macros and the compilation environment in the documentation for the [`Macro` module](/docs/stable/elixir/#!Macro.html) and [`Macro.Env`](/docs/stable/elixir/#!Macro.Env.html). diff --git a/getting-started/meta/macros.markdown b/getting-started/meta/macros.markdown index 3693adc1f..ad2fcd825 100644 --- a/getting-started/meta/macros.markdown +++ b/getting-started/meta/macros.markdown @@ -107,7 +107,7 @@ end Constructs such as `unless/2`, `defmacro/2`, `def/2`, `defprotocol/2`, and many others used throughout this getting started guide are implemented in pure Elixir, often as a macros. This means that the constructs being used to build the language can be used by developers to extend the language to the domains they are working on. -We can define any function and macro we want, including ones that override the built-in definitions provided by Elixir. The only exceptions are Elixir special forms which are not implemented in Elixir and therefore cannot be overridden, [the full list of special forms is available in `Kernel.SpecialForms`](/docs/stable/elixir/Kernel.SpecialForms.html#summary). +We can define any function and macro we want, including ones that override the built-in definitions provided by Elixir. The only exceptions are Elixir special forms which are not implemented in Elixir and therefore cannot be overridden, [the full list of special forms is available in `Kernel.SpecialForms`](/docs/stable/elixir/#!Kernel.SpecialForms.html#summary). ## Macros hygiene @@ -219,7 +219,7 @@ iex> __ENV__.requires [IEx.Helpers, Integer, Kernel, Kernel.Typespec] ``` -Many of the functions in the `Macro` module expect an environment. You can read more about these functions in [the docs for the `Macro` module](/docs/stable/elixir/Macro.html) and learn more about the compilation environment in the [docs for `Macro.Env`](/docs/stable/elixir/Macro.Env.html). +Many of the functions in the `Macro` module expect an environment. You can read more about these functions in [the docs for the `Macro` module](/docs/stable/elixir/#!Macro.html) and learn more about the compilation environment in the [docs for `Macro.Env`](/docs/stable/elixir/#!Macro.Env.html). ## Private macros diff --git a/getting-started/meta/quote-and-unquote.markdown b/getting-started/meta/quote-and-unquote.markdown index a180eb107..6dd12896b 100644 --- a/getting-started/meta/quote-and-unquote.markdown +++ b/getting-started/meta/quote-and-unquote.markdown @@ -151,6 +151,6 @@ Macros receive quoted expressions and must return quoted expressions. However, s In other words, it is important to make a distinction between a regular Elixir value (like a list, a map, a process, a reference, etc) and a quoted expression. Some values, such as integers, atoms and strings, have a quoted expression equal to the value itself. Other values, like maps, need to be explicitly converted. Finally, values like functions and references cannot be converted to a quoted expression at all. -You can read more about `quote` and `unquote` in the [`Kernel.SpecialForms` module](/docs/stable/elixir/Kernel.SpecialForms.html). Documentation for `Macro.escape/1` and other functions related to quoted expressions can be found in the [`Macro` module](/docs/stable/elixir/Macro.html). +You can read more about `quote` and `unquote` in the [`Kernel.SpecialForms` module](/docs/stable/elixir/#!Kernel.SpecialForms.html). Documentation for `Macro.escape/1` and other functions related to quoted expressions can be found in the [`Macro` module](/docs/stable/elixir/#!Macro.html). In this introduction we have laid the groundwork to finally write our first macro, so let's move to the next chapter. diff --git a/getting-started/mix-otp/agent.markdown b/getting-started/mix-otp/agent.markdown index f243b3dc9..7dbc27d5c 100644 --- a/getting-started/mix-otp/agent.markdown +++ b/getting-started/mix-otp/agent.markdown @@ -21,16 +21,16 @@ Elixir is an immutable language where nothing is shared by default. If we want t We have talked about processes, while ETS is something new that we will explore later in this guide. When it comes to processes though, we rarely hand-roll our own process, instead we use the abstractions available in Elixir and OTP: -* [Agent](/docs/stable/elixir/Agent.html) - Simple wrappers around state. -* [GenServer](/docs/stable/elixir/GenServer.html) - "Generic servers" (processes) that encapsulate state, provide sync and async calls, support code reloading, and more. -* [GenEvent](/docs/stable/elixir/GenEvent.html) - "Generic event" managers that allow publishing events to multiple handlers. -* [Task](/docs/stable/elixir/Task.html) - Asynchronous units of computation that allow spawning a process and easily retrieving its result at a later time. +* [Agent](/docs/stable/elixir/#!Agent.html) - Simple wrappers around state. +* [GenServer](/docs/stable/elixir/#!GenServer.html) - "Generic servers" (processes) that encapsulate state, provide sync and async calls, support code reloading, and more. +* [GenEvent](/docs/stable/elixir/#!GenEvent.html) - "Generic event" managers that allow publishing events to multiple handlers. +* [Task](/docs/stable/elixir/#!Task.html) - Asynchronous units of computation that allow spawning a process and easily retrieving its result at a later time. We will explore all of these abstractions in this guide. Keep in mind that they are all implemented on top of processes using the basic features provided by the VM, like `send`, `receive`, `spawn` and `link`. ## Agents -[Agents](/docs/stable/elixir/Agent.html) are simple wrappers around state. If all you want from a process is to keep state, agents are a great fit. Let's start an `iex` session inside the project with: +[Agents](/docs/stable/elixir/#!Agent.html) are simple wrappers around state. If all you want from a process is to keep state, agents are a great fit. Let's start an `iex` session inside the project with: ```bash $ iex -S mix @@ -139,7 +139,7 @@ test "stores values by key", %{bucket: bucket} do end ``` -You can read more about ExUnit cases in the [`ExUnit.Case` module documentation](/docs/stable/ex_unit/ExUnit.Case.html) and more about callbacks in [`ExUnit.Callbacks` docs](/docs/stable/ex_unit/ExUnit.Callbacks.html). +You can read more about ExUnit cases in the [`ExUnit.Case` module documentation](/docs/stable/ex_unit/#!ExUnit.Case.html) and more about callbacks in [`ExUnit.Callbacks` docs](/docs/stable/ex_unit/#!ExUnit.Callbacks.html). ## Other agent actions diff --git a/getting-started/mix-otp/dependencies-and-umbrella-apps.markdown b/getting-started/mix-otp/dependencies-and-umbrella-apps.markdown index d0939cb9e..cf3dd1773 100644 --- a/getting-started/mix-otp/dependencies-and-umbrella-apps.markdown +++ b/getting-started/mix-otp/dependencies-and-umbrella-apps.markdown @@ -46,7 +46,7 @@ def deps do end ``` -This dependency refers to the latest version of plug in the 0.5.x version series that has been pushed to Hex. This is indicated by the `~>` preceding the version number. For more information on specifying version requirements, see the [documentation for the Version module](/docs/stable/elixir/Version.html). +This dependency refers to the latest version of plug in the 0.5.x version series that has been pushed to Hex. This is indicated by the `~>` preceding the version number. For more information on specifying version requirements, see the [documentation for the Version module](/docs/stable/elixir/#!Version.html). Typically, stable releases are pushed to Hex. If you want to depend on an external dependency still in development, Mix is able to manage git dependencies, too: @@ -70,7 +70,7 @@ mix deps.unlock # Unlock the given dependencies mix deps.update # Update the given dependencies ``` -The most common tasks are `mix deps.get` and `mix deps.update`. Once fetched, dependecies are automatically compiled for you. You can read more about deps by typing `mix help deps`, and in the [documentation for the Mix.Tasks.Deps module](/docs/stable/mix/Mix.Tasks.Deps.html). +The most common tasks are `mix deps.get` and `mix deps.update`. Once fetched, dependecies are automatically compiled for you. You can read more about deps by typing `mix help deps`, and in the [documentation for the Mix.Tasks.Deps module](/docs/stable/mix/#!Mix.Tasks.Deps.html). ## Internal dependencies @@ -210,7 +210,7 @@ defmodule KVServer do end ``` -Notice that it defines the application callback function, `start/2`, and instead of defining a supervisor named `KVServer.Supervisor` that uses the `Supervisor` module, it conveniently defined the supervisor inline! You can read more about such supervisors by reading [the Supervisor module documentation](/docs/stable/elixir/Supervisor.html). +Notice that it defines the application callback function, `start/2`, and instead of defining a supervisor named `KVServer.Supervisor` that uses the `Supervisor` module, it conveniently defined the supervisor inline! You can read more about such supervisors by reading [the Supervisor module documentation](/docs/stable/elixir/#!Supervisor.html). We can already try out our first umbrella child. We could run tests inside the `apps/kv_server` directory, but that wouldn't be much fun. Instead, go to the root of the umbrella project and run `mix test`: diff --git a/getting-started/mix-otp/distributed-tasks-and-configuration.markdown b/getting-started/mix-otp/distributed-tasks-and-configuration.markdown index 04c55750d..e5fc761cb 100644 --- a/getting-started/mix-otp/distributed-tasks-and-configuration.markdown +++ b/getting-started/mix-otp/distributed-tasks-and-configuration.markdown @@ -94,9 +94,9 @@ There are three better alternatives to `Node.spawn_link/2` that we could use in 1. We could use Erlang's [:rpc](http://erlang.org/doc/man/rpc.html) module to execute functions on a remote node. Inside the `bar@computer-name` shell above, you can call `:rpc.call(:"foo@computer-name", Hello, :world, [])` and it will print "hello world" -2. We could have a server running on the other node and send requests to that node via the [GenServer](/docs/stable/elixir/GenServer.html) API. For example, you can call a remote named server using `GenServer.call({name, node}, arg)` or simply passing the remote process PID as first argument +2. We could have a server running on the other node and send requests to that node via the [GenServer](/docs/stable/elixir/#!GenServer.html) API. For example, you can call a remote named server using `GenServer.call({name, node}, arg)` or simply passing the remote process PID as first argument -3. We could use [tasks](/docs/stable/elixir/Task.html), which we have learned about in [a previous chapter](/getting-started/mix-otp/task-and-gen-tcp.html), as they can be spawned on both local and remote nodes +3. We could use [tasks](/docs/stable/elixir/#!Task.html), which we have learned about in [a previous chapter](/getting-started/mix-otp/task-and-gen-tcp.html), as they can be spawned on both local and remote nodes The options above have different properties. Both `:rpc` and using a GenServer would serialize your requests on a single server, while tasks are effectively running asynchronously on the remote node, with the only serialization point being the spawning done by the supervisor. @@ -112,7 +112,7 @@ res = compute_something_else() res + Task.await(task) ``` -`async/await` provides a very simple mechanism to compute values concurrently. Not only that, `async/await` can also be used with the same [`Task.Supervisor`](/docs/stable/elixir/Task.Supervisor.html) we have used in previous chapters. We just need to call `Task.Supervisor.async/2` instead of `Task.Supervisor.start_child/2` and use `Task.await/2` to read the result later on. +`async/await` provides a very simple mechanism to compute values concurrently. Not only that, `async/await` can also be used with the same [`Task.Supervisor`](/docs/stable/elixir/#!Task.Supervisor.html) we have used in previous chapters. We just need to call `Task.Supervisor.async/2` instead of `Task.Supervisor.start_child/2` and use `Task.await/2` to read the result later on. ## Distributed tasks @@ -271,7 +271,7 @@ The `mix test` command also allows us to dynamically include and exclude tags. F $ elixir --sname foo -S mix test --only distributed ``` -You can read more about filters, tags and the default tags in [`ExUnit.Case` module documentation](/docs/stable/ex_unit/ExUnit.Case.html). +You can read more about filters, tags and the default tags in [`ExUnit.Case` module documentation](/docs/stable/ex_unit/#!ExUnit.Case.html). ## Application environment and configuration @@ -302,7 +302,7 @@ def table do end ``` -We use `Application.get_env/2` to read the entry for `:routing_table` in `:kv`'s environment. You can find more information and other functions to manipulate the app environment in the [Application module](/docs/stable/elixir/Application.html). +We use `Application.get_env/2` to read the entry for `:routing_table` in `:kv`'s environment. You can find more information and other functions to manipulate the app environment in the [Application module](/docs/stable/elixir/#!Application.html). Since our routing table is now empty, our distributed test should fail. Restart the apps and re-run tests to see the failure: diff --git a/getting-started/mix-otp/docs-tests-and-pipelines.markdown b/getting-started/mix-otp/docs-tests-and-pipelines.markdown index 2f3aa90a8..93c3a83d9 100644 --- a/getting-started/mix-otp/docs-tests-and-pipelines.markdown +++ b/getting-started/mix-otp/docs-tests-and-pipelines.markdown @@ -160,7 +160,7 @@ iex> KVServer.Command.parse "GET shopping\r\n" {:error, :unknown_command} ``` -You can read more about doctests in [the `ExUnit.DocTest` docs](/docs/stable/ex_unit/ExUnit.DocTest.html). +You can read more about doctests in [the `ExUnit.DocTest` docs](/docs/stable/ex_unit/#!ExUnit.DocTest.html). ## Pipelines diff --git a/getting-started/mix-otp/genevent.markdown b/getting-started/mix-otp/genevent.markdown index 625050419..209b975b9 100644 --- a/getting-started/mix-otp/genevent.markdown +++ b/getting-started/mix-otp/genevent.markdown @@ -64,7 +64,7 @@ There are a couple things that are important to highlight at this point: Therefore, `sync_notify/2` and `notify/2` are analogous to `call/2` and `cast/2` in GenServer and using `sync_notify/2` is generally recommended. It works as a backpressure mechanism in the calling process, to reduce the likelihood of messages being sent more quickly than they can be dispatched to handlers. -Be sure to check other functionality provided by GenEvent in its [module documentation](/docs/stable/elixir/GenEvent.html). For now we have enough knowledge to add an event manager to our application. +Be sure to check other functionality provided by GenEvent in its [module documentation](/docs/stable/elixir/#!GenEvent.html). For now we have enough knowledge to add an event manager to our application. ## Registry events diff --git a/getting-started/mix-otp/genserver.markdown b/getting-started/mix-otp/genserver.markdown index c4a108c81..533f97067 100644 --- a/getting-started/mix-otp/genserver.markdown +++ b/getting-started/mix-otp/genserver.markdown @@ -39,7 +39,7 @@ Instead of abusing the name registry facility, we will instead create our own *r The registry needs to guarantee the dictionary is always up to date. For example, if one of the bucket processes crashes due to a bug, the registry must clean up the dictionary in order to avoid serving stale entries. In Elixir, we describe this by saying that the registry needs to *monitor* each bucket. -We will use a [GenServer](/docs/stable/elixir/GenServer.html) to create a registry process that can monitor the bucket process. GenServers are the go-to abstraction for building generic servers in both Elixir and OTP. +We will use a [GenServer](/docs/stable/elixir/#!GenServer.html) to create a registry process that can monitor the bucket process. GenServers are the go-to abstraction for building generic servers in both Elixir and OTP. ## Our first GenServer @@ -115,7 +115,7 @@ For `call` requests, we must implement a `handle_call/3` callback that receives For `cast` requests, we must implement a `handle_cast/2` callback that receives the `request` and the current server state (`names`). The `handle_cast/2` callback returns a tuple in the format `{:noreply, new_state}`. -There are other tuple formats both `handle_call/3` and `handle_cast/2` callbacks may return. There are also other callbacks like `terminate/2` and `code_change/3` that we could implement. You are welcome to explore the [full GenServer documentation](/docs/stable/elixir/GenServer.html) to learn more about those. +There are other tuple formats both `handle_call/3` and `handle_cast/2` callbacks may return. There are also other callbacks like `terminate/2` and `code_change/3` that we could implement. You are welcome to explore the [full GenServer documentation](/docs/stable/elixir/#!GenServer.html) to learn more about those. For now, let's write some tests to guarantee our GenServer works as expected. diff --git a/getting-started/mix-otp/introduction-to-mix.markdown b/getting-started/mix-otp/introduction-to-mix.markdown index 75f92ed1c..0011666ba 100644 --- a/getting-started/mix-otp/introduction-to-mix.markdown +++ b/getting-started/mix-otp/introduction-to-mix.markdown @@ -156,7 +156,7 @@ It is important to note a couple things: 1. the test file is an Elixir script file (`.exs`). This is convenient because we don't need to compile test files before running them; -2. we define a test module named `KVTest`, use [`ExUnit.Case`](/docs/stable/ex_unit/ExUnit.Case.html) to inject the testing API and define a simple test using the `test/2` macro; +2. we define a test module named `KVTest`, use [`ExUnit.Case`](/docs/stable/ex_unit/#!ExUnit.Case.html) to inject the testing API and define a simple test using the `test/2` macro; Mix also generated a file named `test/test_helper.exs` which is responsible for setting up the test framework: @@ -221,7 +221,7 @@ Mix supports the concept of "environments". They allow a developer to customize > Note: If you add dependencies to your project, they will not inherit your project's environment, but instead run with their `:prod` environment settings! -By default, these environments behave the same and all the configurations we have seen so far will affect all three environments. Customization per environment can be done by accessing [the `Mix.env` function](/docs/stable/mix/Mix.html#env/1) in your `mix.exs` file, which returns the current environment as an atom: +By default, these environments behave the same and all the configurations we have seen so far will affect all three environments. Customization per environment can be done by accessing [the `Mix.env` function](/docs/stable/mix/#!Mix.html#env/1) in your `mix.exs` file, which returns the current environment as an atom: ```elixir def project do diff --git a/getting-started/mix-otp/supervisor-and-application.markdown b/getting-started/mix-otp/supervisor-and-application.markdown index 696b27151..00457a54b 100644 --- a/getting-started/mix-otp/supervisor-and-application.markdown +++ b/getting-started/mix-otp/supervisor-and-application.markdown @@ -16,7 +16,7 @@ In this chapter, we are going to learn about supervisors and also about applicat ## Our first supervisor -Creating a supervisor is not much different from creating a GenServer. We are going to define a module named `KV.Supervisor`, which will use the [Supervisor](/docs/stable/elixir/Supervisor.html) behaviour, inside the `lib/kv/supervisor.ex` file: +Creating a supervisor is not much different from creating a GenServer. We are going to define a module named `KV.Supervisor`, which will use the [Supervisor](/docs/stable/elixir/#!Supervisor.html) behaviour, inside the `lib/kv/supervisor.ex` file: ```elixir defmodule KV.Supervisor do @@ -140,7 +140,7 @@ def application do end ``` -The `:mod` option specifies the "application callback module", followed by the arguments to be passed on application start. The application callback module can be any module that implements the [Application](/docs/stable/elixir/Application.html) behaviour. +The `:mod` option specifies the "application callback module", followed by the arguments to be passed on application start. The application callback module can be any module that implements the [Application](/docs/stable/elixir/#!Application.html) behaviour. Now that we have specified `KV` as the module callback, we need to change the `KV` module, defined in `lib/kv.ex`: @@ -173,7 +173,7 @@ Mix makes a distinction between projects and applications. Based on the current When we say "project," you should think about Mix. Mix is the tool that manages your project. It knows how to compile your project, test your project and more. It also knows how to compile and start the application relevant to your project. -When we talk about applications, we talk about OTP. Applications are the entities that are started and stopped as a whole by the runtime. You can learn more about applications in the [docs for the Application module](/docs/stable/elixir/Application.html), as well as by running `mix help compile.app` to learn more about the supported options in `def application`. +When we talk about applications, we talk about OTP. Applications are the entities that are started and stopped as a whole by the runtime. You can learn more about applications in the [docs for the Application module](/docs/stable/elixir/#!Application.html), as well as by running `mix help compile.app` to learn more about the supported options in `def application`. ## Simple one for one supervisors @@ -356,4 +356,4 @@ One possible solution to this problem is to create another supervisor that will You can take a shot at building this new supervision tree, but we will stop here. This is because in the next chapter we will make changes to the registry that will allow the registry data to be persisted, making the `:one_for_one` strategy a perfect fit. -Remember, there are other strategies and other options that could be given to `worker/2`, `supervisor/2` and `supervise/2` functions, so don't forget to check out [the Supervisor module documentation](/docs/stable/elixir/Supervisor.html). +Remember, there are other strategies and other options that could be given to `worker/2`, `supervisor/2` and `supervise/2` functions, so don't forget to check out [the Supervisor module documentation](/docs/stable/elixir/#!Supervisor.html). diff --git a/getting-started/mix-otp/task-and-gen-tcp.markdown b/getting-started/mix-otp/task-and-gen-tcp.markdown index 3085a8113..8d71d1c37 100644 --- a/getting-started/mix-otp/task-and-gen-tcp.markdown +++ b/getting-started/mix-otp/task-and-gen-tcp.markdown @@ -62,7 +62,7 @@ end We are going to start our server by calling `KVServer.accept(4040)`, where 4040 is the port. The first step in `accept/1` is to listen to the port until the socket becomes available and then call `loop_acceptor/1`. `loop_acceptor/1` is just a loop accepting client connections. For each accepted connection, we call `serve/1`. -`serve/1` is another loop that reads a line from the socket and writes those lines back to the socket. Note that the `serve/1` function uses [the pipeline operator `|>`](/docs/stable/elixir/Kernel.html#|>/2) to express this flow of operations. The pipeline operator evaluates the left side and passes its result as first argument to the function on the right side. The example above: +`serve/1` is another loop that reads a line from the socket and writes those lines back to the socket. Note that the `serve/1` function uses [the pipeline operator `|>`](/docs/stable/elixir/#!Kernel.html#|>/2) to express this flow of operations. The pipeline operator evaluates the left side and passes its result as first argument to the function on the right side. The example above: ```elixir socket |> read_line() |> write_line(socket) @@ -131,7 +131,7 @@ For now there is a more important bug we need to fix: what happens if our TCP ac We have learned about agents, generic servers, and event managers. They are all meant to work with multiple messages or manage state. But what do we use when we only need to execute some task and that is it? -[The Task module](/docs/stable/elixir/Task.html) provides this functionality exactly. For example, it has `start_link/3` function that receives a module, function and arguments, allowing us to run a given function as part of a supervision tree. +[The Task module](/docs/stable/elixir/#!Task.html) provides this functionality exactly. For example, it has `start_link/3` function that receives a module, function and arguments, allowing us to run a given function as part of a supervision tree. Let's give it a try. Open up `lib/kv_server.ex`, and let's change the supervisor in the `start/2` function to the following: @@ -225,7 +225,7 @@ def start(_type, _args) do end ``` -We simply start a [`Task.Supervisor`](/docs/stable/elixir/Task.Supervisor.html) process with name `KVServer.TaskSupervisor`. Remember, since the acceptor task depends on this supervisor, the supervisor must be started first. +We simply start a [`Task.Supervisor`](/docs/stable/elixir/#!Task.Supervisor.html) process with name `KVServer.TaskSupervisor`. Remember, since the acceptor task depends on this supervisor, the supervisor must be started first. Now we just need to change `loop_acceptor/2` to use `Task.Supervisor` to serve each request: diff --git a/getting-started/module-attributes.markdown b/getting-started/module-attributes.markdown index 950dfda3a..13116f5b6 100644 --- a/getting-started/module-attributes.markdown +++ b/getting-started/module-attributes.markdown @@ -74,7 +74,7 @@ iex> h Math.sum # Access the docs for the sum function We also provide a tool called [ExDoc](https://github.com/elixir-lang/ex_doc) which is used to generate HTML pages from the documentation. -You can take a look at the docs for [Module](/docs/stable/elixir/Module.html) for a complete list of supported attributes. Elixir also uses attributes to define [typespecs](/docs/stable/elixir/Kernel.Typespec.html), via: +You can take a look at the docs for [Module](/docs/stable/elixir/#!Module.html) for a complete list of supported attributes. Elixir also uses attributes to define [typespecs](/docs/stable/elixir/#!Kernel.Typespec.html), via: * `@spec` - provides a specification for a function. * `@callback` - provides a specification for the behaviour callback. @@ -95,7 +95,7 @@ defmodule MyServer do end ``` -> Note: Unlike Erlang, user defined attributes are not stored in the module by default. The value exists only during compilation time. A developer can configure an attribute to behave closer to Erlang by calling [`Module.register_attribute/3`](/docs/stable/elixir/Module.html#register_attribute/3). +> Note: Unlike Erlang, user defined attributes are not stored in the module by default. The value exists only during compilation time. A developer can configure an attribute to behave closer to Erlang by calling [`Module.register_attribute/3`](/docs/stable/elixir/#!Module.html#register_attribute/3). Trying to access an attribute that was not defined will print a warning: diff --git a/getting-started/modules.markdown b/getting-started/modules.markdown index f6d607903..06fcf6000 100644 --- a/getting-started/modules.markdown +++ b/getting-started/modules.markdown @@ -8,7 +8,7 @@ redirect_from: /getting_started/8.html {% include toc.html %} -In Elixir we group several functions into modules. We've already used many different modules in the previous chapters such as [the `String` module](/docs/stable/elixir/String.html): +In Elixir we group several functions into modules. We've already used many different modules in the previous chapters such as [the `String` module](/docs/stable/elixir/#!String.html): ```iex iex> String.length "hello" @@ -174,7 +174,7 @@ iex> fun.([1, [[2], 3]], [4, 5]) [1, 2, 3, 4, 5] ``` -`&List.flatten(&1, &2)` is the same as writing `fn(list, tail) -> List.flatten(list, tail) end`. You can read more about the capture operator `&` in [the `Kernel.SpecialForms` documentation](/docs/stable/elixir/Kernel.SpecialForms.html#&/1). +`&List.flatten(&1, &2)` is the same as writing `fn(list, tail) -> List.flatten(list, tail) end`. You can read more about the capture operator `&` in [the `Kernel.SpecialForms` documentation](/docs/stable/elixir/#!Kernel.SpecialForms.html#&/1). ## Default arguments diff --git a/getting-started/processes.markdown b/getting-started/processes.markdown index 19d7f4239..7afb832f0 100644 --- a/getting-started/processes.markdown +++ b/getting-started/processes.markdown @@ -132,7 +132,7 @@ receive do end ``` -This time the process failed and brought the parent process down as they are linked. Linking can also be done manually by calling `Process.link/1`. We recommend you to take a look at [the `Process` module](/docs/stable/elixir/Process.html) for other functionality provided by processes. +This time the process failed and brought the parent process down as they are linked. Linking can also be done manually by calling `Process.link/1`. We recommend you to take a look at [the `Process` module](/docs/stable/elixir/#!Process.html) for other functionality provided by processes. Process and links play an important role when building fault-tolerant systems. In Elixir applications, we often link our processes to supervisors which will detect when a process dies and start a new process in its place. This is only possible because processes are isolated and don't share anything by default. And if processes are isolated, there is no way a failure in a process will crash or corrupt the state of another. @@ -231,7 +231,7 @@ iex> flush :world ``` -Using processes around state and name registering are very common patterns in Elixir applications. However, most of the time, we won't implement those patterns manually as above, but by using one of the many of the abstractions that ships with Elixir. For example, Elixir provides [agents](/docs/stable/elixir/Agent.html) which are simple abstractions around state: +Using processes around state and name registering are very common patterns in Elixir applications. However, most of the time, we won't implement those patterns manually as above, but by using one of the many of the abstractions that ships with Elixir. For example, Elixir provides [agents](/docs/stable/elixir/#!Agent.html) which are simple abstractions around state: ```iex iex> {:ok, pid} = Agent.start_link(fn -> %{} end) diff --git a/getting-started/recursion.markdown b/getting-started/recursion.markdown index 4c2593c80..0d1c2df07 100644 --- a/getting-started/recursion.markdown +++ b/getting-started/recursion.markdown @@ -104,7 +104,7 @@ Here we have used recursion to traverse a list doubling each element and returni Recursion and [tail call](http://en.wikipedia.org/wiki/Tail_call) optimization are an important part of Elixir and are commonly used to create loops. However, when programming in Elixir you will rarely use recursion as above to manipulate lists. -The [`Enum` module](/docs/stable/elixir/Enum.html), which we're going to see in the next chapter, already provides many conveniences for working with lists. For instance, the examples above could be written as: +The [`Enum` module](/docs/stable/elixir/#!Enum.html), which we're going to see in the next chapter, already provides many conveniences for working with lists. For instance, the examples above could be written as: ```iex iex> Enum.reduce([1, 2, 3], 0, fn(x, acc) -> x + acc end) diff --git a/getting-started/sigils.markdown b/getting-started/sigils.markdown index 2d8fe2cab..21da80944 100644 --- a/getting-started/sigils.markdown +++ b/getting-started/sigils.markdown @@ -37,7 +37,7 @@ iex> "HELLO" =~ ~r/hello/i true ``` -Check out the [`Regex` module](/docs/stable/elixir/Regex.html) for more information on other modifiers and the supported operations with regular expressions. +Check out the [`Regex` module](/docs/stable/elixir/#!Regex.html) for more information on other modifiers and the supported operations with regular expressions. So far, all examples have used `/` to delimit a regular expression. However sigils support 8 different delimiters: diff --git a/getting-started/try-catch-and-rescue.markdown b/getting-started/try-catch-and-rescue.markdown index dce238562..d3385b9aa 100644 --- a/getting-started/try-catch-and-rescue.markdown +++ b/getting-started/try-catch-and-rescue.markdown @@ -87,7 +87,7 @@ iex> File.read! "unknown" (elixir) lib/file.ex:305: File.read!/1 ``` -Many functions in the standard library follow the pattern of having a counterpart that raises an exception instead of returning tuples to match against. The convention is to create a function (`foo`) which returns `{:ok, result}` or `{:error, reason}` tuples and another function (`foo!`, same name but with a trailing `!`) that takes the same arguments as `foo` but which raises an exception if there's an error. `foo!` should return the result (not wrapped in a tuple) if everything goes fine. The [`File` module](/docs/stable/elixir/File.html) is a good example of this convention. +Many functions in the standard library follow the pattern of having a counterpart that raises an exception instead of returning tuples to match against. The convention is to create a function (`foo`) which returns `{:ok, result}` or `{:error, reason}` tuples and another function (`foo!`, same name but with a trailing `!`) that takes the same arguments as `foo` but which raises an exception if there's an error. `foo!` should return the result (not wrapped in a tuple) if everything goes fine. The [`File` module](/docs/stable/elixir/#!File.html) is a good example of this convention. In Elixir, we avoid using `try/rescue` because **we don't use errors for control flow**. We take errors literally: they are reserved to unexpected and/or exceptional situations. In case you actually need flow control constructs, *throws* should be used. That's what we are going to see next. diff --git a/getting-started/typespecs-and-behaviours.markdown b/getting-started/typespecs-and-behaviours.markdown index 409cd6867..1ed6f7906 100644 --- a/getting-started/typespecs-and-behaviours.markdown +++ b/getting-started/typespecs-and-behaviours.markdown @@ -17,7 +17,7 @@ Elixir is a dynamically typed language, so all types in Elixir are inferred by t ### Function specifications -By default, Elixir provides some basic types, such as `integer` or `pid`, as well as more complex types: for example, the `round/1` function, which rounds a float to its nearest integer, takes a `number` as an argument (an `integer` or a `float`) and returns an `integer`. As you can see [in its documentation](/docs/stable/elixir/Kernel.html#round/1), `round/1`'s typed signature is written as: +By default, Elixir provides some basic types, such as `integer` or `pid`, as well as more complex types: for example, the `round/1` function, which rounds a float to its nearest integer, takes a `number` as an argument (an `integer` or a `float`) and returns an `integer`. As you can see [in its documentation](/docs/stable/elixir/#!Kernel.html#round/1), `round/1`'s typed signature is written as: ``` round(number) :: integer @@ -30,7 +30,7 @@ round(number) :: integer def round(number), do: # implementation... ``` -Elixir supports compound types as well. For example, a list of integers has type `[integer]`. You can see all the types provided by Elixir [in the typespecs docs](/docs/stable/elixir/Kernel.Typespec.html). +Elixir supports compound types as well. For example, a list of integers has type `[integer]`. You can see all the types provided by Elixir [in the typespecs docs](/docs/stable/elixir/#!Kernel.Typespec.html). ### Defining custom types @@ -48,7 +48,7 @@ defmodule LousyCalculator do end ``` -As you can see in the example, tuples are a compound type and each tuple is identified by the types inside it. To understand why `String.t` is not written as `string`, have another look at the [typespecs docs](/docs/stable/elixir/Kernel.Typespec.html). +As you can see in the example, tuples are a compound type and each tuple is identified by the types inside it. To understand why `String.t` is not written as `string`, have another look at the [typespecs docs](/docs/stable/elixir/#!Kernel.Typespec.html). Defining function specs this way works, but it quickly becomes annoying since we're repeating the type `{number, String.t}` over and over. We can use the `@type` directive in order to declare our own custom type.