erlang - Core Erlang 的 `letrec` 是干什么用的?
问题描述
Core Erlang 的letrec
用途是什么?
Richard Carlsson 在“Core Erlang 简介”中写道:
此外
letrec
,表达式允许局部(递归)函数定义,ERLANG 本身没有,但在转换中通常很有用。
letrec 对哪些转换有用?
从 Erlang 翻译时是否erlc
实际生成?letrec
还是letrec
只有在从非 Erlang 源语言翻译时才会生成 s?
解决方案
如今,列表推导式被翻译成 letrecs(在 Core Erlang 中可用),而 letrecs 又被翻译成普通的递归函数。
请注意,“Nowadays”是 2010 年。此外,还有一些在EEP 52 中使用的示例: Allow key and size expressions in map and binary matching:
在 OTP 23 中,段大小表达式中使用的所有变量必须已经绑定在封闭环境中。前面的示例必须使用嵌套案例重写如下:
'foo'/1 = fun (_0) -> case _0 of <#{#<Sz>(16,1,'integer',['unsigned'|['big']]), #<_2>('all',1,'binary',['unsigned'|['big']])}#> when 'true' -> case _2 of <#{#<X>(Sz,1,'integer',['unsigned'|['big']])}#> when 'true' -> X <_3> when 'true' -> %% Raise function_clause exception. . . . end <_4> when 'true' -> %% Raise function_clause exception. . . . end
但是,从示例中可以看出,引发
function_clause
异常的代码已重复。在这个简单的示例中,代码重复没什么大不了的,但它会出现在二进制匹配子句后跟许多其他子句的函数中。为了避免代码重复,我们必须使用letrec
withletrec_goto
注解:'foo'/1 = fun (_0) -> ( letrec 'label^0'/0 = fun () -> case _0 of <_1> when 'true' -> %% Raise function_clause exception. . . . end in case _0 of <#{#<Sz>(16,1,'integer',['unsigned'|['big']]), #<_2>('all',1,'binary',['unsigned'|['big']])}#> when 'true' -> case _2 of <#{#<X>(Sz,1,'integer',['unsigned'|['big']])}#> when 'true' -> X <_3> when 'true' -> apply 'label^0'/0() end <_4> when 'true' -> apply 'label^0'/0() end -| ['letrec_goto'] )
推荐阅读
- python - 如何使用子进程在python中自动执行shotcut命令?
- java - 在 android 上同时使用 Cellular + WiFi(Channel Bonding)
- html - 如何在 IE11 中使用响应式图像修复引导行中的空白?
- python - 为什么同一迭代的不同运行会产生不同的结果?
- ajax - Laravel 搜索功能中的 Ajax 不起作用
- nestjs - 如何将 postgres 或 SQL Server 与 nestjs 一起使用
- routing - Sapper - 受保护的路线(路线守卫)
- javascript - jspdf Devnagari(尼泊尔语/印地语)字体
- typescript - What does angle brackets “<>” mean in function declaration in Typescript?
- python - 如何处理 utf-8 字符串,因为我想用我的文本中的空格替换 - 然后使用 split 函数将每个单词与其他单词分开