Pattern aliases for strings produce bad Erlang
I was delighted to learn that the pattern aliases described here are also supported for strings, however, I ran into this problem when trying to run my code with Erlang as the target. I pared it way down to this minimal example - it's nonsense, but it seems clear where the problem is:
import gleam/io
import gleam/string
fn reproduce_bug(data) {
case data {
"" -> ""
"(" as paren <> rest -> paren <> reproduce_bug(rest)
s -> s <> reproduce_bug(string.drop_left(s, 1))
}
}
pub fn main() {
io.println(reproduce_bug("abcde(fgh)ijkl"))
}
..which produces the following when run with gleam run:
[ bug ]$ gleam run
Downloading packages
Downloaded 2 packages in 0.00s
Compiling gleam_stdlib
Compiling gleeunit
Compiling bug
/home/r/projects/gleam/bug/build/dev/erlang/bug/_gleam_artefacts/bug.erl:12:20: syntax error before: '='
% 12| <<"("/utf8 = Paren, Rest/binary>> ->
% | ^
/home/r/projects/gleam/bug/build/dev/erlang/bug/_gleam_artefacts/bug.erl:6:2: spec for undefined function reproduce_bug/1
% 6| -spec reproduce_bug(binary()) -> binary().
% | ^
/home/r/projects/gleam/bug/build/dev/erlang/bug/_gleam_artefacts/bug.erl:21:22: function reproduce_bug/1 undefined
% 21| gleam@io:println(reproduce_bug(<<"abcde(fgh)ijkl"/utf8>>)).
% | ^
error: Shell command failure
There was a problem when running the shell command `escript`.
It runs as expected with gleam run -t js. My Gleam version is 1.0.0, installed from here. I'll add the generated Erlang for good measure:
-module(bug).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([main/0]).
-spec reproduce_bug(binary()) -> binary().
reproduce_bug(Data) ->
case Data of
<<""/utf8>> ->
<<""/utf8>>;
<<"("/utf8 = Paren, Rest/binary>> ->
<<Paren/binary, (reproduce_bug(Rest))/binary>>;
S ->
<<S/binary, (reproduce_bug(gleam@string:drop_left(S, 1)))/binary>>
end.
-spec main() -> nil.
main() ->
gleam@io:println(reproduce_bug(<<"abcde(fgh)ijkl"/utf8>>)).
Thank you
I looked at the bug a little further, and managed to produce an even smaller minimal example:
case "" {
"" as a <> _ -> Nil
_ -> Nil
}
error (edited for brevity):
bug.erl:30:19: syntax error before: '='
% 30| <<""/utf8 = A, _/binary>> ->
% | ^
generated Erlang:
case <<""/utf8>> of
<<""/utf8 = A, _/binary>> ->
nil;
_ ->
nil
end,
it seems like pattern aliases and string prefixes do not play nicely together. should pattern aliases be available for string prefixes in the first place? their value is a known constant.
Since this got merged https://github.com/gleam-lang/gleam/pull/2782 I think we can close this issue. WDYT @lpil ?
Thank you!