Skip to content

Instantly share code, notes, and snippets.

View crbelaus's full-sized avatar

Cristian Álvarez Belaustegui crbelaus

View GitHub Profile
@crbelaus
crbelaus / slugify.ex
Created March 11, 2024 08:22
Slugify a string in Elixir
# Copied from https://mudssrali.com/blog/slugify-a-string-in-elixir
# and then modified to drop leading and trailing dashes.
defmodule String do
# 1. Convert a string to downcase
# 2. Remove any leading and trailing spaces
# 3. Convert graphemes to normal characters (e.g. á, é)
# 4. Replace non-alphanumeric characters with an empty string
# 5. Replace multiple spaces or dashes with a single dash
# 6. Remove any leading and trailing dashes
@crbelaus
crbelaus / trans1_runtime_errors.ex
Last active June 29, 2019 12:53
Shows an example of Trans 1.0 runtinme errors
# Trans 1.0 did not perform safety checks when building queries.
# Adding conditions on a non-existing field would result un runtime errors.
iex> Article
...> |> Article.with_translation(:es, :fake, "this field does not exist")
...> |> Repo.all
** (ArgumentError) The field `fake` is not declared as translatable
@crbelaus
crbelaus / trans1_interface_pollution.ex
Last active June 29, 2019 12:54
Shows an example of a module using Trans 1.0 and it's added functions
# Using tab to autocomplete shows the functions added by Trans
# Those functions pollute the module interface and add database
# and query concerns to the schema module
iex(5)> Article.
changeset/1 changeset/2 with_translation/4
with_translation/5 with_translations/2 with_translations/3
@crbelaus
crbelaus / trans1_querybuilder_example.ex
Created April 14, 2017 11:35
Shows an example of the QueryBuilder of Trans 1.0
# Fetch articles titled "La République" in French
iex> Article
...> |> Trans.QueryBuilder.with_translation(:fr, :title, "La République")
...> |> Repo.all
# SELECT a0."id", a0."title", a0."body", a0."translations"
# FROM "articles" AS a0
# WHERE (a0."translations"->"fr"->>"title" = "La République")
@crbelaus
crbelaus / trans2_querybuilder_examples.ex
Last active June 29, 2019 12:56
Shows examples of the Trans 2.0 QueryBuilder
# Fetch Articles titled "Trans" in French and having an English comment
# containing the word "good"
iex> Repo.all(from a in Article,
...> join: c in assoc(a, :comments),
...> where: translated(Article, a.title, :fr) == "Trans",
...> where: ilike(translated(Comment, c.comment, :en), "good"))
# SELECT a0."id", a0."title", a0."body", a0."translations"
# FROM "articles" AS a0
# INNER JOIN "comments" AS c1 ON a0."id" = c1."article_id"
# WHERE ((a0."translations"->"fr"->>"title") = "Trans")
@crbelaus
crbelaus / if_anaphoric_invocation.exs
Last active June 29, 2019 13:02
Shows an example of IEx invocation of `if_anaphoric.ex`.
iex(1)> require Anaphora
Anaphora
iex(2)> Anaphora.if Universe.response_to_everything do
...(2)> # La variable 'it' se crea automaticamente durante la
...(2)> # macro expansión.
...(2)> Universe.proclaim it
...(2)> end
"Whoa! The data is 42"
@crbelaus
crbelaus / if_anaphoric.ex
Last active June 29, 2019 13:01
Implements an anaphoric if as `Anaphora.if` and shows how it can be used. #anaphora
defmodule Universe do
def response_to_everything do
:timer.sleep(5000) # Simulate complex calculations for 5 seconds
42
end
def proclaim(data), do: "Whoa! The data is #{data}"
end
defmodule Anaphora do
@crbelaus
crbelaus / if_scoped_variable.exs
Last active June 29, 2019 13:00
A simple example of a memoization of a complex calculation. This example shows how the `with` construction can be used to create a new scope to which the variable `result` is bounded and not available outside. #anaphora
defmodule Universe do
def response_to_everything do
:timer.sleep(5000) # Simulate complex calculations for 5 seconds
42
end
def proclaim(data), do: "Whoa! The data is #{data}"
end
with result <- Universe.response_to_everything do
@crbelaus
crbelaus / if_memoized_variable.exs
Last active June 29, 2019 12:59
A simple example memoization of a complex calculation that gets used twice. This example also shows how the original variable is bounded to the parent scope and available after the `if` execution finishes. #anaphora
defmodule Universe do
def response_to_everything do
:timer.sleep(5000) # Simulate complex calculations for 5 seconds
42
end
def proclaim(data), do: "Whoa! The data is #{data}"
end
@crbelaus
crbelaus / fibo.exs
Last active February 7, 2016 11:48
The exercise of @miguelff (https://gist.github.com/miguelff/08d87b5823c55b82bc02) woke up my curiosity about how tail recursion optimization could improve the performance over the "traditional" recursive Fibonacci solution.
defmodule Fibo do
def recursive(n) when n <= 2, do: 1
def recursive(n), do: recursive(n-1) + recursive(n-2)
def tail_rec(n, prev \\ 0, current \\ 1)
def tail_rec(0, prev, _), do: prev
def tail_rec(n, prev, current), do: tail_rec(n - 1, current, current + prev)
end
defmodule Benchmark do