diff --git a/README.md b/README.md index af23978..8eec58d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ Welcome to the home for [my personal livebooks](https://github.com/christhekeele/livebooks/tree/latest/livebooks): Elixir experiments, guides, and accompanying source code. Their history can be accessed [on GitHub](https://github.com/christhekeele/livebooks) by the clicking the "view source" -`` icon next to the title of every page. Corrections, proposals, and discussions can be made in the GitHub [issues](https://github.com/christhekeele/livebooks/issues), [pull requests](https://github.com/christhekeele/livebooks/pulls), and [discussions](https://github.com/christhekeele/livebooks/discussions) pages respectively. +`` icon next to the title of every page. Corrections, proposals, and discussions can be made in the GitHub [pull requests](https://github.com/christhekeele/livebooks/pulls), [issues](https://github.com/christhekeele/livebooks/issues), and [discussions](https://github.com/christhekeele/livebooks/discussions) pages respectively. diff --git a/lib/livebook/helpers.ex b/lib/livebook/helpers.ex new file mode 100644 index 0000000..85965b7 --- /dev/null +++ b/lib/livebook/helpers.ex @@ -0,0 +1,55 @@ +defmodule Livebook.Helpers do + @moduledoc """ + Common helpers for these livebooks. + """ + + defmacro __using__(_opts \\ []) do + quote do + import unquote(__MODULE__), only: [defmodule: 3] + unquote(__MODULE__).start_patching_modules() + end + end + + @doc """ + Inspired by [this macro](https://github.com/brettbeatty/experiments_elixir/blob/master/module_patching.livemd). + """ + defmacro defmodule(alias, version, do_block) do + [do: block] = do_block + module = Macro.expand(alias, __CALLER__) + version = Macro.expand(version, __CALLER__) + version_namespace = version |> to_string |> String.to_atom() + module_namespace = Module.concat(module, version_namespace) + store_block(module, version, block) + + quote do + defmodule unquote(module_namespace) do + (unquote_splicing(patches_so_far(module, version))) + end + + alias unquote(module_namespace), as: unquote(module) + end + |> IO.inspect() + end + + defp store_block(module, version, block) do + :ets.insert(__MODULE__, {{module, version}, block}) + end + + defp patches_so_far(module, version) do + __MODULE__ + |> :ets.select([{{{module, :"$1"}, :"$2"}, [{:"=<", :"$1", version}], [:"$2"]}]) + |> Enum.flat_map(&unblock/1) + end + + defp unblock(ast) + defp unblock({:__block__, _meta, block}), do: block + defp unblock(ast), do: [ast] + + def start_patching_modules do + with :undefined <- :ets.whereis(__MODULE__) do + __MODULE__ = :ets.new(__MODULE__, [:ordered_set, :named_table]) + end + + :ok + end +end diff --git a/lib/livebooks.ex b/lib/livebooks.ex deleted file mode 100644 index dec0ef9..0000000 --- a/lib/livebooks.ex +++ /dev/null @@ -1,3 +0,0 @@ -defmodule Livebooks do - @moduledoc false -end diff --git a/livebooks/surreal.livemd b/livebooks/surreal.livemd index 7b0a8e6..7affdc7 100644 --- a/livebooks/surreal.livemd +++ b/livebooks/surreal.livemd @@ -1,11 +1,29 @@ # Surreal Numbers ```elixir -Mix.install([ - {:ets, "~> 0.9.0"}, - {:eternal, "~> 1.2"} -]) +Mix.install( + [ + {:ets, "~> 0.9.0"}, + {:eternal, "~> 1.2"}, + {:livebooks, github: "christhekeele/livebooks", tag: "latest"} + ], + force: true +) +``` + +## Video Format + +[Watch the ElixirConf 2022 lightning talk here!](https://www.youtube.com/watch?v=f1lNK5gDlwA&t=235s) + +## Helpers + +```elixir +use Livebook.Helpers +``` +## Caching + +```elixir require Logger defmodule Surreal.Guards do @@ -50,10 +68,6 @@ end Surreal.Cache.init() ``` -## Video Format - -[Watch the ElixirConf 2022 lightning talk here!](https://www.youtube.com/watch?v=f1lNK5gDlwA&t=235s) - ## Axioms * Zero @@ -96,7 +110,7 @@ five_eighths = {[one_half], [three_quarters]} ## Module ```elixir -defmodule Surreal do +defmodule Surreal, 1 do import Kernel, except: [-: 1, +: 2, -: 2, *: 2, /: 2, <>: 2] import Surreal.Guards @@ -108,7 +122,7 @@ end ## Set Concatenation ```elixir -defmodule Surreal do +defmodule Surreal, 2 do import Kernel, except: [-: 1, +: 2, -: 2, *: 2, /: 2, <>: 2] import Surreal.Guards