p5h / p5summit-2019

Perl 5 Summit
0 stars 0 forks source link

Stop syntax ambiguity #12

Open toddr opened 4 years ago

toddr commented 4 years ago

It bugs @xsawyerx

leonerd commented 4 years ago

A particularly hairy example is what does barename->foo mean? It's a method call, right?

Sure, but on what invocant?

# It could be a method call on a named package
Class->new  # invokes Class::new("Class")

# It could be a method call on a barename filehandle
open OUTPUT, ">", "out.json";
OUTPUT->autoflush  # Invokes IO::Handle::autoflush(\*OUTPUT)

# It could be a method call on a package or instance returned by a constant sub
sub Two::value { return 2 }
use constant ONE => "Two";
say ONE->value  # invokes Two::value("Two")
leonerd commented 4 years ago

To mitigate this inside our (proposed) new shiney class/module scopes where it would be good if static analysis were possible, it is necessary to remove two of these cases. Clearly the topmost case is by far the most common and useful, so get rid of the other two.

If the no bareword::filehandles pragma is in effect (or more likely, reïmplemented in core perl) then that removes the middle of the three cases. That leaves six special cases STDIN, STDOUT, STDERR, ARGV, ARGVOUT and DATA, which between them account for the vast majority of use-cases here. A static analyser can easily be taught those six special cases, so it's no major problem to keep the common pattern of STDOUT->autoflush.

I don't have a good answer for the third part though. While ideas such as const (#26) can encourage creating better solutions for these constants, the fact remains that older ones still exist and there isn't much we can do about that.

class IO::Socket {
    use Socket qw( PF_UNIX PF_INET PF_INET6 );
    # PF_INET->foo   is now a method lookup on the value of the `PF_INET` constant
}