Elixir 中表达式的惰性评估
Lazy evaluation of expression in Elixir
我想弄清楚在 clojure 中是否有一个类似于 delay
的宏来获得一个可以稍后计算的惰性表达式/变量。
用例是 Map.get/3
的默认值,因为默认值来自数据库调用,所以我更希望只在需要时调用它。
执行此操作的一种方法是使用进程。例如,地图可以包装在像 GenServer 或 Agent 这样的进程中,其中默认值将被延迟计算。
默认值可以是进行昂贵调用的函数。如果 Map.get/3
未被用于 return 函数,您可以检查该值是否是一个函数,如果它是 returned 则调用它。像这样:
def default_value()
expensive_db_call()
end
def get_something(dict, key) do
case Map.get(dict, key, default_value) do
value when is_fun(value) ->
value.() # invoke the default function and return the result of the call
value ->
value # key must have existed, return value
end
end
当然,如果地图包含函数,则此类解决方案可能行不通。
同时检查 Elixir 的 Stream 模块。虽然我不知道它是否有助于解决您的特定问题,但它确实允许进行惰性评估。来自文档:
Streams are composable, lazy enumerables. Any enumerable that generates items one by one during enumeration is called a stream. For example, Elixir’s Range is a stream:
the Stream documentation 中提供了更多信息。
Elixir 的宏可用于编写用于条件评估的简单包装函数。我在下面列出了一个要点,尽管它可能是 better/smarter 方式。
"Generic" 懒惰有点难解决,因为这是一个相当宽泛的问题。流允许可枚举的惰性,但我不确定表达式的惰性意味着什么。例如 x = 1 + 2
的惰性形式是什么?什么时候评估?
想到表达式的惰性形式是过程表达式:
def x, do: 1 + 2
因为 x 的值在实际调用表达式之前不会被计算(据我所知)。如果我在这一点上错了,我相信其他人会纠正我。但我认为这不是你想要的。
也许您想重新表述您的问题——省略流和枚举值的惰性求值。
Map.get_lazy
和 Keyword.get_lazy
在需要时推迟生成默认值,链接下面的文档
你可以将它包裹在一个匿名函数中,然后在调用该函数时对其进行计算:
iex()> lazy = fn -> :os.list_env_vars() end
#Function<45.79398840/0 in :erl_eval.expr/5>
iex()> lazy.()
我想弄清楚在 clojure 中是否有一个类似于 delay
的宏来获得一个可以稍后计算的惰性表达式/变量。
用例是 Map.get/3
的默认值,因为默认值来自数据库调用,所以我更希望只在需要时调用它。
执行此操作的一种方法是使用进程。例如,地图可以包装在像 GenServer 或 Agent 这样的进程中,其中默认值将被延迟计算。
默认值可以是进行昂贵调用的函数。如果 Map.get/3
未被用于 return 函数,您可以检查该值是否是一个函数,如果它是 returned 则调用它。像这样:
def default_value()
expensive_db_call()
end
def get_something(dict, key) do
case Map.get(dict, key, default_value) do
value when is_fun(value) ->
value.() # invoke the default function and return the result of the call
value ->
value # key must have existed, return value
end
end
当然,如果地图包含函数,则此类解决方案可能行不通。
同时检查 Elixir 的 Stream 模块。虽然我不知道它是否有助于解决您的特定问题,但它确实允许进行惰性评估。来自文档:
Streams are composable, lazy enumerables. Any enumerable that generates items one by one during enumeration is called a stream. For example, Elixir’s Range is a stream:
the Stream documentation 中提供了更多信息。
Elixir 的宏可用于编写用于条件评估的简单包装函数。我在下面列出了一个要点,尽管它可能是 better/smarter 方式。
"Generic" 懒惰有点难解决,因为这是一个相当宽泛的问题。流允许可枚举的惰性,但我不确定表达式的惰性意味着什么。例如 x = 1 + 2
的惰性形式是什么?什么时候评估?
想到表达式的惰性形式是过程表达式:
def x, do: 1 + 2
因为 x 的值在实际调用表达式之前不会被计算(据我所知)。如果我在这一点上错了,我相信其他人会纠正我。但我认为这不是你想要的。
也许您想重新表述您的问题——省略流和枚举值的惰性求值。
Map.get_lazy
和 Keyword.get_lazy
在需要时推迟生成默认值,链接下面的文档
你可以将它包裹在一个匿名函数中,然后在调用该函数时对其进行计算:
iex()> lazy = fn -> :os.list_env_vars() end
#Function<45.79398840/0 in :erl_eval.expr/5>
iex()> lazy.()