<commit_before>* Elixir Sips - Tools and Libraries

** Elixir Standard Library

*** Enum

- `Enum.all?` - Returns `true` when all items in the collection
  returns `true` for a provided *predicate*.
- `Enum.any?` - Returns `true` when any item in the collection
  returns `true` for a provided *predicate*.
- `Enum.at` - Returns an item from collection by zero-based index. If
  there is no such index, returns `nil`.
- `Enum.chunks` - Returns chunks of collection by specified size, step
  and padding.
- `Enum.chunks_by` - Starts a new chunk at each place that returns
  `true` for the provided *predicate*.
- `Enum.concat` - Concatenates list of lists into a single list. Also
  works with ranges.
- `Enum.count` - It returns number of items in the collection, but
  also with provided *predicate* it returns number of items that
  returns `true` when applied to it.
- `Enum.drop` - It drops the first `count` items in the collection.
- `Enum.drop_while` - It drops items in the beginning of the
  collection while *predicate* returns `true`.
- `Enum.each` - Invokes *predicate* for each element in the
  collection.
- `Enum.empty?` - Returns `true` when collection is empty.
- `Enum.fetch` - Returns tuple with atom `:ok` and element on the
  given index in the collection if exists, or `:error` when it does
  not. If you call it with `!` at the end, it raises an
  `OutOfBoundsError` (this version returns only value, not a tuple
  when succeeds).
- `Enum.filter` - It filters the collection, by a given *predicate*.
- `Enum.filter_map` - It filters and maps the value in the one
  pass. You have to specify two *funs*.
- `Enum.find` - It returns first item, which returns `true` from a
  given *predicate*. You can specify a default, instead of `nil`.
- `Enum.find_index` - As above, but it returns an index.
- `Enum.find_value` - As above, but it returns value returned from a
  provided *fun*.
- `Enum.first` - Returns first element from the collection or `nil` if
  the collection is empty.
- `Enum.flat_map` - Returns a modified collection, modification is
  performed by a *fun* provided in the invocation which has to return
  a collection.
- `Enum.join` - Joins a collection with a *joiner*. By default
  *joiner* is an empty binary.
- `Enum.map` - Maps a collection, each item in new collection is a
  result of provided *fun*.
- `Enum.map_join` - Maps and join collection at one pass. Defaults as
  above.
- `Enum.map_reduce` - Performs map-reduce on a collection in one
  pass. Provided *fun* should return a tuple which has in first
  element new mapped element and in second one updated accumulator.
- `Enum.max` - Maximum value from collection.
- `Enum.max_by` - Maximum value from collection transformed by a given
  *fun*.
- `Enum.min` - Minimum value from collection.
- `Enum.min_by` - Minimum value from collection transformed by a given
  *fun*.
- `Enum.member?` - Checks if a value is a member of collection.
- `Enum.partition` - Partitions a collection into two collections, one
  collection contain elements which returned *truthy* value by a given
  predicate, second one which returned *falsy* value.
- `Enum.reduce` - Reducer across collection by a given *fun*. First
  argument used as a starting value.
- `Enum.reject` - Rejects values which are return `true` for a given
  *predicate*.
- `Enum.reverse` - Reverses the collection.
- `Enum.shuffle` - Shuffles the collection.
- `Enum.slice` - Returns a subset list for a given collections. It
  expects an index and a size of subset.
- `Enum.sort` - Merge sort algorithm invoked on a collection. You can
  pass a *comparator fun*.
- `Enum.split` - Splits a collection in a given index, if index is
  negative it counts backwards
- `Enum.split_while` - Splits a collection into two while *predicate*
  returns `true`.
- `Enum.take` - Takes first `n` elements from a collection.
- `Enum.take_every` - It takes every element starting from the first
  incremented by a provided `step`.
- `Enum.take_while` - Takes first elements while *predicate* returns
  `true`.
- `Enum.to_list` - Converts collection to a list.
- `Enum.uniq` - Removes duplicated items.
- `Enum.with_index` - It returns collection where each element is a
  tuple which contains an actual value and index (beware of order in a
  tuple).
- `Enum.zip` - Zips together two collections, resulting collection is
  a list of tuples. If the second list is shorter, missing values are
  filled with `nil`.

** Erlang Standard Library

*** gs

- Deprecated *Erlang* graphics subsystem, replaces by *wx*.
  - It will be removed in incoming release - *18.0*.

*** xmerl

- Built-in *Erlang* module for parsing *XML*.
- [[../tools/xml_parsing][Example usage]]

*** dbg

- Tracing functions, processes and messages in *Erlang* / *Elixir*.
  - Help methods - `:dbg.h`
  - List of actual traces - `:dbg.i`
  - Trace invocation - `:dbg.c(:"Elixir.Foo", :bar, [])`
  - Start tracer server - `:dbg.tracer`
    - Trace process interactions - `:dbg.p(pid, [:m, :procs])`

*** ssh

- Built-in module for interacting with SSH.
- OTP is shipped with an implementation of SSH daemon.
  - You can connect to it from the any authorized *Erlang* shell.
  - Interacting with *Elixir* code needs to be done in particular way,
    but it is pleasant and possible.

** OTP

*OTP* is a *Open Telecom Platform*. Set of libraries for building
reliable and distributed systems.

*** gen_server

- Generic request/reply server implementation.
- [[../OTP/gen_server_playground][Example implementation with tests]]

*** gen_fsm

- Generic *finite state machine* implementation.
- [[../OTP/gen_fsm_playground][Example implementation with tests]]

*** gen_event

- Generic *event handler and dispatcher* implementation.
- [[../OTP/zeldacat][Example implementation with tests]]

*** supervisor

- Generic behavior for managing, observing and restarting other
  processes.
- [[../OTP/supervised_list_server][Example implementation with tests]]

*** gen_tcp

- Module with set of functions related with TCP connection handling
  and sockets.
- [[../OTP/tcp_server][Example implementation with tests]]

*** Distribution

- `iex --name "foo@0.0.0.0"` - the same as adding name to the Erlang
  session.
  - `:erlang.register(:shell, self)` - registering the named process
    across the cluster.
  - For local sessions, you don't have to setup a *cookie* (it is
    already shared because of the file defined in your home
    directory).
    - For remote nodes you have to define the *identical cookie*, it
      is the only security mechanism built-in to the Erlang VM.
  - Joe Armstrong's favorite program:
    ```
    receive do
      {:become, some_fn} -> some_fn.()
    end
    ```

*** Port

- Interacting with external programs, as if they are acting as a
  simple process.
  - `Port.open({:spawn, "ls"}, [])`
    - You received result asynchronously, to your mailbox as a normal
      message from the different process.
  - Another example:
    ```
    port = Port.open(
      {:spawn, "bash --noediting -i"},
      [:stderr_to_stdout, :binary, :exit_status]
    )
    ```
    - Interacting:
      - `send(port, {self, {:command, "pwd\n"}})`
      - `send(port, {self, {:command, <<27>>}})`

*** Observer

- Graphical tool for inspection a running *Erlang* / *Elixir* system
  and its processes.
  - `:observer.start`

** Hex

- Package manager and repository for *BEAM* languages.
  - Not only limited to the *Elixir* environment.
  - List of local tasks - `mix local`.
    - Searching packages - `mix hex.search actor`.
    - Package information - `mix hex.info exactor`.
  - Using *API* pragmatically:
    - `Hex.API.get_package("exactor")`
    - `Hex.API.get_release("exactor", "0.3.0")`

** Ecto

- https://github.com/elixir-lang/ecto
- A database wrapper and language integrated query for Elixir.
- [[../tools/ecto_test][Example usage]]

** Amnesia

- https://github.com/meh/amnesia
- Wrapper for Erlang's Mnesia database written in Elixir.
** HTTP Clients

- Note: none of modules presented below is an *Elixir* library:
  - httpc (built-in `:inets` client).
  - ibrowse (external dependency).
  - hackney (external dependency).
- [[../tools/http_client_survey][Example usage]]

** ExActor

- Library that simplifies generation and using of `gen_server`.
- [[../tools/exactor_test][Example usage]]

** Plug

- Web framework for *Elixir*.
  - It allows you to built composable web applications.
  - It is similar regarding behavior and features to *Ruby's Rack* or
    *Python's WSGI*.
  - Build as an replacement for *Dynamo*.

*** Plug.Static

- Serving static assets with proper *mime/type* by default
  from directory `/priv/static`.
  - You can use it instead the complicated *Cowboy* handler.

** Weber

- Elixir MVC web framework.
  - https://github.com/elixir-web/weber
  - Note: it is not compatible with *Elixir 1.0*.
- Nice benchmark performed (with use of `wrk`):
  - Rack (GET request with *Hello World*): ~350 req/s
  - Node.js (GET request with *Hello World*): ~11k req/s
  - Weber in Elixir (standard template, more than previous): ~14k req/s

** IEx.pry

- Built-in inspection tool for running processes.
  - After invoking `IEx.pry` it will ask you to allow open a new
    session. After accepting that you will have access to the whole
    lexical scope of actually running process.
  - [[../tools/iex_pry_test][Sample project]]

** Deprecated / Abandoned Libraries

*** Elixiak

- Elixir library for *Riak*.
  - https://github.com/drewkerrigan/elixiak
  - Note: it is not compatible with *Elixir 1.0*.
- [[../tools/elixiak_playground][Example usage with tests]]

*** Dynamo

- https://github.com/dynamo/dynamo
- It is a *Sinatra*-like web framework written in *Elixir*.
- Unfortunately it is discontinued - you should use *Plug* instead.

*** ExLager

- Elixir wrapper for Basho library called *Lager*.
- [[../OTP/supervised_list_server][Example usage]]

*** Releases (*relex* and *pogo*)

- Unit of deployment for Erlang is a *release*. It is an application<commit_msg>Adding notes about deployment to Heroku and ExConf module.<commit_after>* Elixir Sips - Tools and Libraries

** Elixir Standard Library

*** Enum

- `Enum.all?` - Returns `true` when all items in the collection
  returns `true` for a provided *predicate*.
- `Enum.any?` - Returns `true` when any item in the collection
  returns `true` for a provided *predicate*.
- `Enum.at` - Returns an item from collection by zero-based index. If
  there is no such index, returns `nil`.
- `Enum.chunks` - Returns chunks of collection by specified size, step
  and padding.
- `Enum.chunks_by` - Starts a new chunk at each place that returns
  `true` for the provided *predicate*.
- `Enum.concat` - Concatenates list of lists into a single list. Also
  works with ranges.
- `Enum.count` - It returns number of items in the collection, but
  also with provided *predicate* it returns number of items that
  returns `true` when applied to it.
- `Enum.drop` - It drops the first `count` items in the collection.
- `Enum.drop_while` - It drops items in the beginning of the
  collection while *predicate* returns `true`.
- `Enum.each` - Invokes *predicate* for each element in the
  collection.
- `Enum.empty?` - Returns `true` when collection is empty.
- `Enum.fetch` - Returns tuple with atom `:ok` and element on the
  given index in the collection if exists, or `:error` when it does
  not. If you call it with `!` at the end, it raises an
  `OutOfBoundsError` (this version returns only value, not a tuple
  when succeeds).
- `Enum.filter` - It filters the collection, by a given *predicate*.
- `Enum.filter_map` - It filters and maps the value in the one
  pass. You have to specify two *funs*.
- `Enum.find` - It returns first item, which returns `true` from a
  given *predicate*. You can specify a default, instead of `nil`.
- `Enum.find_index` - As above, but it returns an index.
- `Enum.find_value` - As above, but it returns value returned from a
  provided *fun*.
- `Enum.first` - Returns first element from the collection or `nil` if
  the collection is empty.
- `Enum.flat_map` - Returns a modified collection, modification is
  performed by a *fun* provided in the invocation which has to return
  a collection.
- `Enum.join` - Joins a collection with a *joiner*. By default
  *joiner* is an empty binary.
- `Enum.map` - Maps a collection, each item in new collection is a
  result of provided *fun*.
- `Enum.map_join` - Maps and join collection at one pass. Defaults as
  above.
- `Enum.map_reduce` - Performs map-reduce on a collection in one
  pass. Provided *fun* should return a tuple which has in first
  element new mapped element and in second one updated accumulator.
- `Enum.max` - Maximum value from collection.
- `Enum.max_by` - Maximum value from collection transformed by a given
  *fun*.
- `Enum.min` - Minimum value from collection.
- `Enum.min_by` - Minimum value from collection transformed by a given
  *fun*.
- `Enum.member?` - Checks if a value is a member of collection.
- `Enum.partition` - Partitions a collection into two collections, one
  collection contain elements which returned *truthy* value by a given
  predicate, second one which returned *falsy* value.
- `Enum.reduce` - Reducer across collection by a given *fun*. First
  argument used as a starting value.
- `Enum.reject` - Rejects values which are return `true` for a given
  *predicate*.
- `Enum.reverse` - Reverses the collection.
- `Enum.shuffle` - Shuffles the collection.
- `Enum.slice` - Returns a subset list for a given collections. It
  expects an index and a size of subset.
- `Enum.sort` - Merge sort algorithm invoked on a collection. You can
  pass a *comparator fun*.
- `Enum.split` - Splits a collection in a given index, if index is
  negative it counts backwards
- `Enum.split_while` - Splits a collection into two while *predicate*
  returns `true`.
- `Enum.take` - Takes first `n` elements from a collection.
- `Enum.take_every` - It takes every element starting from the first
  incremented by a provided `step`.
- `Enum.take_while` - Takes first elements while *predicate* returns
  `true`.
- `Enum.to_list` - Converts collection to a list.
- `Enum.uniq` - Removes duplicated items.
- `Enum.with_index` - It returns collection where each element is a
  tuple which contains an actual value and index (beware of order in a
  tuple).
- `Enum.zip` - Zips together two collections, resulting collection is
  a list of tuples. If the second list is shorter, missing values are
  filled with `nil`.

** Erlang Standard Library

*** gs

- Deprecated *Erlang* graphics subsystem, replaces by *wx*.
  - It will be removed in incoming release - *18.0*.

*** xmerl

- Built-in *Erlang* module for parsing *XML*.
- [[../tools/xml_parsing][Example usage]]

*** dbg

- Tracing functions, processes and messages in *Erlang* / *Elixir*.
  - Help methods - `:dbg.h`
  - List of actual traces - `:dbg.i`
  - Trace invocation - `:dbg.c(:"Elixir.Foo", :bar, [])`
  - Start tracer server - `:dbg.tracer`
    - Trace process interactions - `:dbg.p(pid, [:m, :procs])`

*** ssh

- Built-in module for interacting with SSH.
- OTP is shipped with an implementation of SSH daemon.
  - You can connect to it from the any authorized *Erlang* shell.
  - Interacting with *Elixir* code needs to be done in particular way,
    but it is pleasant and possible.

** OTP

*OTP* is a *Open Telecom Platform*. Set of libraries for building
reliable and distributed systems.

*** gen_server

- Generic request/reply server implementation.
- [[../OTP/gen_server_playground][Example implementation with tests]]

*** gen_fsm

- Generic *finite state machine* implementation.
- [[../OTP/gen_fsm_playground][Example implementation with tests]]

*** gen_event

- Generic *event handler and dispatcher* implementation.
- [[../OTP/zeldacat][Example implementation with tests]]

*** supervisor

- Generic behavior for managing, observing and restarting other
  processes.
- [[../OTP/supervised_list_server][Example implementation with tests]]

*** gen_tcp

- Module with set of functions related with TCP connection handling
  and sockets.
- [[../OTP/tcp_server][Example implementation with tests]]

*** Distribution

- `iex --name "foo@0.0.0.0"` - the same as adding name to the Erlang
  session.
  - `:erlang.register(:shell, self)` - registering the named process
    across the cluster.
  - For local sessions, you don't have to setup a *cookie* (it is
    already shared because of the file defined in your home
    directory).
    - For remote nodes you have to define the *identical cookie*, it
      is the only security mechanism built-in to the Erlang VM.
  - <NAME>'s favorite program:
    ```
    receive do
      {:become, some_fn} -> some_fn.()
    end
    ```

*** Port

- Interacting with external programs, as if they are acting as a
  simple process.
  - `Port.open({:spawn, "ls"}, [])`
    - You received result asynchronously, to your mailbox as a normal
      message from the different process.
  - Another example:
    ```
    port = Port.open(
      {:spawn, "bash --noediting -i"},
      [:stderr_to_stdout, :binary, :exit_status]
    )
    ```
    - Interacting:
      - `send(port, {self, {:command, "pwd\n"}})`
      - `send(port, {self, {:command, <<27>>}})`

*** Observer

- Graphical tool for inspection a running *Erlang* / *Elixir* system
  and its processes.
  - `:observer.start`

** Hex

- Package manager and repository for *BEAM* languages.
  - Not only limited to the *Elixir* environment.
  - List of local tasks - `mix local`.
    - Searching packages - `mix hex.search actor`.
    - Package information - `mix hex.info exactor`.
  - Using *API* pragmatically:
    - `Hex.API.get_package("exactor")`
    - `Hex.API.get_release("exactor", "0.3.0")`

** Ecto

- https://github.com/elixir-lang/ecto
- A database wrapper and language integrated query for Elixir.
- [[../tools/ecto_test][Example usage]]

** Amnesia

- https://github.com/meh/amnesia
- Wrapper for Erlang's Mnesia database written in Elixir.
** HTTP Clients

- Note: none of modules presented below is an *Elixir* library:
  - httpc (built-in `:inets` client).
  - ibrowse (external dependency).
  - hackney (external dependency).
- [[../tools/http_client_survey][Example usage]]

** ExActor

- Library that simplifies generation and using of `gen_server`.
- [[../tools/exactor_test][Example usage]]

** Plug

- Web framework for *Elixir*.
  - It allows you to built composable web applications.
  - It is similar regarding behavior and features to *Ruby's Rack* or
    *Python's WSGI*.
  - Build as an replacement for *Dynamo*.

*** Plug.Static

- Serving static assets with proper *mime/type* by default
  from directory `/priv/static`.
  - You can use it instead the complicated *Cowboy* handler.

** Weber

- Elixir MVC web framework.
  - https://github.com/elixir-web/weber
  - Note: it is not compatible with *Elixir 1.0*.
- Nice benchmark performed (with use of `wrk`):
  - Rack (GET request with *Hello World*): ~350 req/s
  - Node.js (GET request with *Hello World*): ~11k req/s
  - Weber in Elixir (standard template, more than previous): ~14k req/s

** IEx.pry

- Built-in inspection tool for running processes.
  - After invoking `IEx.pry` it will ask you to allow open a new
    session. After accepting that you will have access to the whole
    lexical scope of actually running process.
  - [[../tools/iex_pry_test][Sample project]]

** ExConf

- Nice module for managing configuration with built-in DSL.
  - It is very easy to create multiple configuration environments.

** Deployment (Heroku)

- `BUILD_PACK_URL=https://github.com/HashNuke/heroku-buildpack-elixir.git`
  - `heroku create --buildpack $BUILD_PACK_URL"`
  - `elixir_buildpack.config` - BEAM configuration file.
    - `erlang_version=17.5`
    - `elixir_version=1.0.4`
    - `rebar_version=(tag 2.5.1)`
    - `always_build_deps=false`
  - `Procfile` - Process configuration.
    - `web: MIX_ENV=prod mix run --no-halt`

** Deprecated / Abandoned Libraries

*** Elixiak

- Elixir library for *Riak*.
  - https://github.com/drewkerrigan/elixiak
  - Note: it is not compatible with *Elixir 1.0*.
- [[../tools/elixiak_playground][Example usage with tests]]

*** Dynamo

- https://github.com/dynamo/dynamo
- It is a *Sinatra*-like web framework written in *Elixir*.
- Unfortunately it is discontinued - you should use *Plug* instead.

*** ExLager

- Elixir wrapper for Basho library called *Lager*.
- [[../OTP/supervised_list_server][Example usage]]

*** Releases (*relex* and *pogo*)

- Unit of deployment for Erlang is a *release*. It is an application
{'fraction_non_alphanumeric': 0.1121250364042326, 'fraction_numerical': 0.0026696437239103, 'mean_word_length': 3.3901555508203707, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 10, 'https://': 11, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '522062', 'n_tokens_mistral': 6393, 'n_tokens_neox': 6247, 'n_words': 2530}