【问题标题】:What is Core Erlang's `letrec` for?Core Erlang 的 `letrec` 是干什么用的?
【发布时间】:2021-04-30 11:12:42
【问题描述】:

Core Erlang 的letrec 是干什么用的?

Richard Carlsson 在"Introduction to Core Erlang" 中写道:

此外,letrec 表达式允许本地(递归)函数定义,ERLANG 本身没有,但在转换中通常很有用。

letrec 对哪些转换有用?

erlc 在从 Erlang 翻译时实际上会生成 letrec 吗?或者letrecs 只有在从非 Erlang 源语言翻译时才会生成?

【问题讨论】:

    标签: erlang


    【解决方案1】:

    Nowadays, list comprehensions are translated to letrecs (which are available in Core Erlang), and the letrecs are in turn translated to ordinary recursive functions.

    请注意,“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 的代码 异常已重复。这个简单的代码重复没什么大不了的 例如,但它会在一个遵循二进制匹配子句的函数中 通过许多其他条款。为了避免代码重复,我们必须使用letrecletrec_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'] )
    

    【讨论】:

    猜你喜欢
    • 2011-01-04
    • 2010-10-07
    • 1970-01-01
    • 2016-10-30
    • 2017-11-03
    • 2014-12-20
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多