Inconsistent shadowing of variables in a fun

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Inconsistent shadowing of variables in a fun

Robert Virding
When defining a fun the shadowing of variables occurring in arguments is inconsistent. So with

a(X, N) ->
    fun (<<X,Y:N,_/binary>>) -> {X,Y} end.

the X in the fun arguments shadows the X from before it while the N is imported and used. An example:

1> c(bt).
bt.erl:8: Warning: variable 'X' is unused
bt.erl:9: Warning: variable 'X' shadowed in 'fun'
{ok,bt}
2> f(G),G=bt:a(34,8).
#Fun<bt.1.1070726>
3> G(<<1,2,3,4,5>>).
{1,2}
4> f(G),G=bt:a(34,16).
#Fun<bt.1.1070726>
5> G(<<1,2,3,4,5>>). 
{1,515}


Why the difference? Shouldn't we be consistent in shadowing all variables?

Robert


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inconsistent shadowing of variables in a fun

José Valim-2
From my understanding, the N in this case can never be an unbound variable. If you rename N to M, then it won't compile, so it would not be possible for it to shadow anything.

It is similar to map keys. They are always treated as values, even when inside patterns.


On Sun, Jan 29, 2017 at 23:07 Robert Virding <[hidden email]> wrote:
When defining a fun the shadowing of variables occurring in arguments is inconsistent. So with

a(X, N) ->
    fun (<<X,Y:N,_/binary>>) -> {X,Y} end.

the X in the fun arguments shadows the X from before it while the N is imported and used. An example:

1> c(bt).
bt.erl:8: Warning: variable 'X' is unused
bt.erl:9: Warning: variable 'X' shadowed in 'fun'
{ok,bt}
2> f(G),G=bt:a(34,8).
#Fun<bt.1.1070726>
3> G(<<1,2,3,4,5>>).
{1,2}
4> f(G),G=bt:a(34,16).
#Fun<bt.1.1070726>
5> G(<<1,2,3,4,5>>). 
{1,515}


Why the difference? Shouldn't we be consistent in shadowing all variables?

Robert

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
--


José Valim
Skype: jv.ptec
Founder and Director of R&D

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inconsistent shadowing of variables in a fun

Michel Boaventura
According to Joe's Programming Erlang(page 103): Size must be an expression that evaluates to an integer. In pattern matching, Size must be an integer or a bound variable whose value is an integer.

So the N on the pattern match is not a new variable like X.

Em 29 de jan de 2017 20:42, "José Valim" <[hidden email]> escreveu:
From my understanding, the N in this case can never be an unbound variable. If you rename N to M, then it won't compile, so it would not be possible for it to shadow anything.

It is similar to map keys. They are always treated as values, even when inside patterns.


On Sun, Jan 29, 2017 at 23:07 Robert Virding <[hidden email]> wrote:
When defining a fun the shadowing of variables occurring in arguments is inconsistent. So with

a(X, N) ->
    fun (<<X,Y:N,_/binary>>) -> {X,Y} end.

the X in the fun arguments shadows the X from before it while the N is imported and used. An example:

1> c(bt).
bt.erl:8: Warning: variable 'X' is unused
bt.erl:9: Warning: variable 'X' shadowed in 'fun'
{ok,bt}
2> f(G),G=bt:a(34,8).
#Fun<bt.1.1070726>
3> G(<<1,2,3,4,5>>).
{1,2}
4> f(G),G=bt:a(34,16).
#Fun<bt.1.1070726>
5> G(<<1,2,3,4,5>>). 
{1,515}


Why the difference? Shouldn't we be consistent in shadowing all variables?

Robert

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
--


José Valim
Skype: jv.ptec
Founder and Director of R&D

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inconsistent shadowing of variables in a fun

Richard A. O'Keefe-2
In reply to this post by Robert Virding


On 30/01/17 11:06 AM, Robert Virding wrote:
> When defining a fun the shadowing of variables occurring in arguments is
> inconsistent.
>
> Why the difference? Shouldn't we be consistent in shadowing all variables?

I have always wished that Erlang did no shadowing at all.

a(X) ->
     case X+1 of X -> ooh ; _ -> ahh end.

b(X) ->
     (fun (X) -> ooh ; (_) -> ahh end)(X+1).


2> foo:a(0).
ahh
3> foo:b(0).
ooh

Call *that* consistent?  I don't.


1> c(foo).
foo.erl:8: Warning: this clause cannot match because a previous clause
at line 8 always matches
foo.erl:8: Warning: variable 'X' is unused
foo.erl:8: Warning: variable 'X' shadowed in 'fun'

That warning about 'X' being shadowed?

LOVE IT LOVE IT LOVE IT!

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inconsistent shadowing of variables in a fun

Robert Virding
In reply to this post by Michel Boaventura
Yes, the variable bitsize variable must be bound. BUT it can also be bound if it matched "earlier" from inside the same binary. So

b() -> fun (<<N, X:N, _/bitstring>>) -> {N,X} end.

and

1> c("bt").
{ok,bt}
2> F = bt:b().
#Fun<bt.2.81949596>
3> F(<<8,1,2,3,4>>).
{8,1}
4> F(<<5,1,2,3,4>>).
{5,0}

We see that N doesn't have to be imported. So variables in fun argument patterns aren't imported except for the binary bitsize, which is inconsistent and a bit hacky. Why that type?

Robert


On 30 January 2017 at 00:00, Michel Boaventura <[hidden email]> wrote:
According to Joe's Programming Erlang(page 103): Size must be an expression that evaluates to an integer. In pattern matching, Size must be an integer or a bound variable whose value is an integer.

So the N on the pattern match is not a new variable like X.


Em 29 de jan de 2017 20:42, "José Valim" <[hidden email]> escreveu:
From my understanding, the N in this case can never be an unbound variable. If you rename N to M, then it won't compile, so it would not be possible for it to shadow anything.

It is similar to map keys. They are always treated as values, even when inside patterns.


On Sun, Jan 29, 2017 at 23:07 Robert Virding <[hidden email]> wrote:
When defining a fun the shadowing of variables occurring in arguments is inconsistent. So with

a(X, N) ->
    fun (<<X,Y:N,_/binary>>) -> {X,Y} end.

the X in the fun arguments shadows the X from before it while the N is imported and used. An example:

1> c(bt).
bt.erl:8: Warning: variable 'X' is unused
bt.erl:9: Warning: variable 'X' shadowed in 'fun'
{ok,bt}
2> f(G),G=bt:a(34,8).
#Fun<bt.1.1070726>
3> G(<<1,2,3,4,5>>).
{1,2}
4> f(G),G=bt:a(34,16).
#Fun<bt.1.1070726>
5> G(<<1,2,3,4,5>>). 
{1,515}


Why the difference? Shouldn't we be consistent in shadowing all variables?

Robert

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
--


José Valim
Skype: jv.ptec
Founder and Director of R&D

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions




_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inconsistent shadowing of variables in a fun

Robert Virding
In reply to this post by Richard A. O'Keefe-2
The shadowing warning is there because it is only there and list comprehensions where variable in patterns are shadowed. No, it isn't consistent but it follows how other functional languages do it, IIRC. The problems with an evolving language.

Robert


On 30 January 2017 at 00:17, Richard A. O'Keefe <[hidden email]> wrote:


On 30/01/17 11:06 AM, Robert Virding wrote:
When defining a fun the shadowing of variables occurring in arguments is
inconsistent.

Why the difference? Shouldn't we be consistent in shadowing all variables?

I have always wished that Erlang did no shadowing at all.

a(X) ->
    case X+1 of X -> ooh ; _ -> ahh end.

b(X) ->
    (fun (X) -> ooh ; (_) -> ahh end)(X+1).


2> foo:a(0).
ahh
3> foo:b(0).
ooh

Call *that* consistent?  I don't.


1> c(foo).
foo.erl:8: Warning: this clause cannot match because a previous clause at line 8 always matches
foo.erl:8: Warning: variable 'X' is unused
foo.erl:8: Warning: variable 'X' shadowed in 'fun'

That warning about 'X' being shadowed?

LOVE IT LOVE IT LOVE IT!


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inconsistent shadowing of variables in a fun

Michel Boaventura
In reply to this post by Robert Virding
I understand what you are saying. Probably this is allowed on bit matching so you can use parts of the pattern to help match itself. It makes sense if a piece's length depends on other piece value.

Em 29 de jan de 2017 22:15, "Robert Virding" <[hidden email]> escreveu:
Yes, the variable bitsize variable must be bound. BUT it can also be bound if it matched "earlier" from inside the same binary. So

b() -> fun (<<N, X:N, _/bitstring>>) -> {N,X} end.

and

1> c("bt").
{ok,bt}
2> F = bt:b().
#Fun<bt.2.81949596>
3> F(<<8,1,2,3,4>>).
{8,1}
4> F(<<5,1,2,3,4>>).
{5,0}

We see that N doesn't have to be imported. So variables in fun argument patterns aren't imported except for the binary bitsize, which is inconsistent and a bit hacky. Why that type?

Robert


On 30 January 2017 at 00:00, Michel Boaventura <[hidden email]> wrote:
According to Joe's Programming Erlang(page 103): Size must be an expression that evaluates to an integer. In pattern matching, Size must be an integer or a bound variable whose value is an integer.

So the N on the pattern match is not a new variable like X.


Em 29 de jan de 2017 20:42, "José Valim" <[hidden email]> escreveu:
From my understanding, the N in this case can never be an unbound variable. If you rename N to M, then it won't compile, so it would not be possible for it to shadow anything.

It is similar to map keys. They are always treated as values, even when inside patterns.


On Sun, Jan 29, 2017 at 23:07 Robert Virding <[hidden email]> wrote:
When defining a fun the shadowing of variables occurring in arguments is inconsistent. So with

a(X, N) ->
    fun (<<X,Y:N,_/binary>>) -> {X,Y} end.

the X in the fun arguments shadows the X from before it while the N is imported and used. An example:

1> c(bt).
bt.erl:8: Warning: variable 'X' is unused
bt.erl:9: Warning: variable 'X' shadowed in 'fun'
{ok,bt}
2> f(G),G=bt:a(34,8).
#Fun<bt.1.1070726>
3> G(<<1,2,3,4,5>>).
{1,2}
4> f(G),G=bt:a(34,16).
#Fun<bt.1.1070726>
5> G(<<1,2,3,4,5>>). 
{1,515}


Why the difference? Shouldn't we be consistent in shadowing all variables?

Robert

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
--


José Valim
Skype: jv.ptec
Founder and Director of R&D

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions




_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Loading...