[erlang-questions] Can we change the semantics of match expressions in comprehensions?

Matthew Dempsky <>
Tue Feb 5 00:07:55 CET 2008


On 2/4/08, Matthew Dempsky <> wrote:
> It occurs to me now that I can just rewrite "Pat = Expr" as "Pat <-
> [Expr]" without needing to change semantics at all.

Below is a patch for the Erlang compiler that better optimizes
generator expressions like "Pat <- [Expr]" in list comprehensions.  A
similar patch could probably be built for binary comprehensions.

(I doubt it's worth the added complexity to include, but I thought I'd
share anyways.)

--- v3_core.erl.orig    2008-02-04 14:44:19.000000000 -0800
+++ v3_core.erl 2008-02-04 14:50:09.000000000 -0800
@@ -732,6 +732,34 @@
 %%  code.
 %%  More could be transformed before calling lc_tq.

+lc_tq(Line, E, [{generate,Lg,P,{cons,_,X,{nil,_}}}|Qs0], More, St0) ->
+    %% Fast path for Pat <- [Expr] generators.
+    {Xc,Xps,St1} = novars(X, St0),
+    {Lc,Lps,St2} = lc_tq(Line, E, Qs0, More, St1),
+    {Mc,Mps,St3} = expr(More, St2),
+    {Else,St4} = new_var(St3),
+    LA = lineno_anno(Line, St4),
+    {Cs,St5} = try pattern(P, St4) of
+                   P1 = #c_var{} ->
+                       {[#iclause{anno=#a{anno=LA},
+                                  pats=[P1],guard=[],
+                                  body=Lps ++ [Lc]}],
+                        St4};
+                   P1 ->
+                       {[#iclause{anno=#a{anno=LA},
+                                  pats=[P1],guard=[],
+                                  body=Lps ++ [Lc]},
+                         #iclause{anno=#a{anno=LA},
+                                  pats=[Else],guard=[],
+                                  body=Mps ++ [Mc]}],
+                        St4}
+               catch
+                   throw:Thrown ->
+                       {[], add_warning(Line, Thrown, St4)}
+               end,
+    {Fpat,St6} = new_var(St5),
+    Fc = fail_clause([Fpat], #c_tuple{es=[#c_literal{val=badmatch},Fpat]}),
+    {#icase{anno=#a{anno=LA},args=[Xc],clauses=Cs,fc=Fc},Xps,St6};
 lc_tq(Line, E, [{generate,Lg,P,G}|Qs0], More, St0) ->
     {Gs,Qs1} =  splitwith(fun is_guard_test/1, Qs0),
     {Name,St1} = new_fun_name("lc", St0),



More information about the erlang-questions mailing list