New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use ++/2 in a pattern #176

Closed
yurrriq opened this Issue Dec 28, 2015 · 1 comment

Comments

Projects
None yet
1 participant
@yurrriq
Contributor

yurrriq commented Dec 28, 2015

In Erlang, I can do this:

> F = fun("prefix" ++ Suffix) -> Suffix end.
% #Fun<erl_eval.6.54118792>
> F("prefixsuffix").
"suffix"

but in LFE, I get a function_clause error:

> (defun f ([(++ "prefix" suffix)] suffix))
f
> (f "prefixsuffix")
exception error: function_clause

Per discussion on IRC, the plan is to add a ++* that uses:

[[N|Ns]|Es] when is_number(N) -> [cons,N,['++*',Ns|Es]];

and bottoms out to a call to erlang:++ after a specific number of characters.

@yurrriq

This comment has been minimized.

Show comment
Hide comment
@yurrriq

yurrriq Dec 28, 2015

Contributor
diff --git a/src/lfe_macro.erl b/src/lfe_macro.erl
index f422c7b..cf4d3c0 100644
--- a/src/lfe_macro.erl
+++ b/src/lfe_macro.erl
@@ -654,0 +655,3 @@ exp_predef(['++'|Abody], _, St) ->
+exp_predef(['++*'|Abody], _, St) ->
+    Exp = exp_prefix(Abody),
+    {yes,Exp,St};
@@ -938,0 +942,12 @@ exp_append(Args) ->
+%% exp_prefix(Args) -> Expansion.
+%%  Expand ++* in such a way as to allow its use in patterns.
+%%  Handle lists of numbers (strings) explicitly, otherwise
+%%  default to exp_append/1.
+
+exp_prefix(Args) ->
+    case Args of
+        %% Cases with lists of numbers (strings).
+        [[N|Ns]|Es] when is_number(N) -> [cons,N,['++*',Ns|Es]];
+        _ -> exp_append(Args)
+    end.
+
(defun f
  ([(++* "This is a rather large prefix and makes for a slightly impractical test, but I'm doing it anyway, for science. " suffix)]
    suffix))
> (f "This is a rather large prefix and makes for a slightly impractical test, but I'm doing it anyway, for science. We did it!")
"We did it!"
Contributor

yurrriq commented Dec 28, 2015

diff --git a/src/lfe_macro.erl b/src/lfe_macro.erl
index f422c7b..cf4d3c0 100644
--- a/src/lfe_macro.erl
+++ b/src/lfe_macro.erl
@@ -654,0 +655,3 @@ exp_predef(['++'|Abody], _, St) ->
+exp_predef(['++*'|Abody], _, St) ->
+    Exp = exp_prefix(Abody),
+    {yes,Exp,St};
@@ -938,0 +942,12 @@ exp_append(Args) ->
+%% exp_prefix(Args) -> Expansion.
+%%  Expand ++* in such a way as to allow its use in patterns.
+%%  Handle lists of numbers (strings) explicitly, otherwise
+%%  default to exp_append/1.
+
+exp_prefix(Args) ->
+    case Args of
+        %% Cases with lists of numbers (strings).
+        [[N|Ns]|Es] when is_number(N) -> [cons,N,['++*',Ns|Es]];
+        _ -> exp_append(Args)
+    end.
+
(defun f
  ([(++* "This is a rather large prefix and makes for a slightly impractical test, but I'm doing it anyway, for science. " suffix)]
    suffix))
> (f "This is a rather large prefix and makes for a slightly impractical test, but I'm doing it anyway, for science. We did it!")
"We did it!"

@yurrriq yurrriq changed the title from Can't use ++/2 in a guard to Can't use ++/2 in a pattern Dec 28, 2015

@rvirding rvirding closed this in #177 Dec 28, 2015

oubiwann added a commit to oubiwann/lfe that referenced this issue Dec 28, 2015

Add expansion of ++*/2 in patterns
See rvirding/lfe#176

Before:

    (defun f ([(++ "prefix" suffix)] suffix))

    (f "prefixsuffix") ;; function_clause error

After:

    (defun f ([(++* "prefix" suffix)] suffix))

    (f "prefixsuffix") ;; "suffix"

Since there are only two cases, use function clauses rather than
`case Args of ...`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment