繁体   English   中英

Erlang vs Elixir Macros

[英]Erlang vs Elixir Macros

我遇到了一些Erlang代码,我试图将其转换为Elixir,以帮助我学习这两种语言并理解其中的差异。 宏观和元编程一般是我仍然试图解决的话题,所以希望你能理解我的困惑。

Erlang代码

-define(p2(MAT, REP), 
        p2(W = MAT ++ STM) -> m_rep(0, W, STM, REP))

% where m_rep is a function already defined.

对我来说,似乎在上面的代码中,有两个单独的p2宏定义映射到一个名为m_rep的私有函数。 但是在Elixir中,似乎只能有一个模式匹配定义。 Elixir也有可能有不同的吗?

这些不是两个定义。 第一行是宏,第二行是替换。 令人困惑的是,宏与它生成子句的函数同名。 例如,当像这样使用宏时:

?p2("a", "b");
?p2("c", "d").

以上内容将扩展至:

p2(w = "a" ++ stm) -> m_rep(0, w, stm, "b");
p2(w = "c" ++ stm) -> m_rep(0, w, stm, "d").

您可以使用erlc -P生成.P文件,该文件将向您显示宏扩展对代码的影响。 看看这个稍微简单,可编辑的例子:

-module(macro).
-export([foo/1]).

-define(foo(X),
        foo(X) -> X).

?foo("bar");
?foo("baz");
?foo("qux").

使用erlc -P macro.erl您将获得以下输出到macro.P

-file("macro.erl", 1).

-module(macro).

-export([foo/1]).

foo("bar") ->
    "bar";
foo("baz") ->
    "baz";
foo("qux") ->
    "qux".

在Elixir中,您也可以使用宏定义多个函数子句。 它更冗长,但我认为它也更清晰。 Elixir等价物将是:

defmodule MyMacros do
  defmacro p2(mat, rep) do
    quote do
      def p2(w = unquote(mat) ++ stm) do
        m_rep(0, w, stm, unquote(rep))
      end
    end
  end
end

您可以使用它来定义多个函数子句,就像erlang对应的一样:

defmodule MyModule do
  require MyMacros

  MyMacros.p2('a', 'b')
  MyMacros.p2('c', 'd')
end

我在这里无法自拔。 :-)如果它是你的宏然后使用后LFE(Lisp的香料二郎),为您提供更好的宏观操控比任何二郎或酏剂。 它也兼容两者。

-define(p2(MAT, REP), 
        p2(w = MAT ++ stm) -> m_rep(0, w, stm, REP))

% where m_rep is a function already defined.

上面的代码有很多问题。

在Erlang中没有带有多个子句的宏。 上面的代码没有定义映射到名为m_rep的私有函数的p2宏的两个单独定义 它的作用是定义一个2参数宏,它定义了一个带有一些参数并调用m_repp2函数。 但是,内部p2函数的参数定义不正确:

  • 它尝试使用++ ,第二个参数不是列表
  • 它试图给一个原子赋值(你的意思是一个大写的W ,一个变量,而不是一个小的w ,一个原子吗?)
  • 它在一个不允许赋值的地方尝试赋值 - 在函数头中。

您是否尝试测试相等性( ==而不是= ),而不是进行分配? 如果是这样,你必须使用警卫。

而且,在我看来,你试图使用wstm ,好像它们是变量并将它们传递给m_rep ,但它们不是! Erlang中的变量必须以大写字母开头。 另一方面,Elixir中的变量则没有。 你可能会混淆两种相似但仍然不同的语言的概念。

我的一般建议是选择一种语言并对其进行良好的学习,然后才能用这种知识尝试不同的语言。 如果您对编程完全陌生,请选择Erlang - 它更简单,预先学习的东西较少。 如果您已经了解Ruby,请选择Elixir,或者更多地了解您的技能。

请详细说明您的意图,我也许能够提出表达它的代码。 上面的代码片段太模糊了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM