subscribe

Drop 'public' not 'var'!

Bikeshedding time!

A PHP RFC vote has started to deprecate the var keyword in PHP 7.1 and remove it in PHP 8. At the time of writing, there 23 who say it should be removed, and 18 who say it should not.

I suspect that most people in the “no” camp, feel that way about var because

  • There’s not a big maintenance burden or overhead to keep var.
  • They feel that it will break BC, with no strong benefit.

The “yes” camp feel mainly feels that it makes the language a bit cleaner.

I’d like to offer a different opinion: I think people should be using var instead of public. I realize that this is as controversial as tabs vs. spaces (as in: it doesn’t really matter but conjures heated discusssions), but hear me out!

Over the last year I’ve been going through all my open source projects, and I’ve been removing all the public declarations where this was possible.

This means that if my class first looked like this:

<?php

class ImConformist {

    static public $prop1;
    final public $prop2;

    public function __construct() {

    }

    public function getFoo() {

    }

    public function setFoo(Foo $foo) {

    }

    abstract public function implementMe();

    final public function dontTouchMe() {

    }

    static public function iShouldntBeHere() {

    }

}

Now, I write it like this:

<?php

class HateGenerator {

    static $prop1;
    final $prop2;

    function __construct() {

    }

    function getFoo() {

    }

    function setFoo(Foo $foo) {

    }

    abstract function implementMe();

    final function dontTouchMe() {

    }

    static function iShouldntBeHere() {

    }

}

This change has generated interesting responses. A lot of people think it’s ugly. Some think I should just follow PSR-2. I also heard from a whole bunch that weren’t aware that ommitting public actually has no effect on your code!

Yes, public is completely optional. public is the default, so adding it does nothing to your code.

Actually, it does do something. It makes your lines longer! Typically when someone has to read your source and figure out what a class is doing, it will take them slightly longer to read the method signatures.

So there’s a small mental tax for a human to read and intereprete the entire line. It’s generally accepted that shorter lines are better, and when ‘scanning’ a file from top to bottom, it’s better that the important keywords (the name of the function) are closer to the left-edge of the screen.

That’s my main argument for dropping the public keyword where possible. I believe that the people who are against it, generally fall in three camps:

#1: Everyone doing the same thing is good

This is the conformist argument, and the best one. There is definitely a case to be made that if most PHP code-based look similar, it is easier for new maintainers to get a jump start in the project.

I suspect that these people are also the most likely to use PSR-2 when they can.

I think it’s good to be similar, but then, I think it’s also good to sometimes break the mold and do something new. If we always keep doing things the same way, we never progress. Being consistent is good, but it’s also good to be open to change, especially if that change has real benefits.

#2: It’s ugly!

The aesthetics argument! It’s not an invalid one. I care quite a bit about how my source ‘looks’. I’m an “API over Implemenation” guy, and I think the aesthetics of your source influence the ease of how someone can start using it.

The case I want to present to you today though is that you think it’s ugly, because it’s foreign to you. I felt the same way at first, and found out pretty quickly that I got used to the new status quo and as soon as I lost my earlier biases, the new way actually feels a lot more natural now.

Whenever I look at sources that use the public keyword, the feelings it’s giving me is “dense”, “corporate” and “java-esk”.

#3: The public keyword is useful to convey intent

On the surface this argument sounds reasonable, but ultimately I think people who hold this opinion are suffering a form of denial. A new idea was presented to them, they don’t like it, so their brain works overtime to find a possible counter argument that just coincidentally matches their existing biases and world-view.

I believe that the people who feel this way are actually just in camp #2, but lack self awareness.

The truth is that many languages popular scripting languages don’t need the keyword (ruby, javascript), or lack the functionality altogether (python).

Furthermore, did you ever wish you could public in front of your class, interface or namespace, or your regular non-class functions? What about public const? Be honest! Have you really ever missed public there? Really?

Hey I do think it would be great to have private classes and private namespace functions, but I definitely haven’t “missed” being able to tack on the public symbol to a constant. public is already implied.

So given those arguments, why does everyone add public everywhere?

This is a theory: Back in the day when we all made the transition from PHP 4 to 5, everybody was just really really excited.

PHP 5 introduced a new object model that was just so much better than the PHP 4 one. The visibility keywords are just a small aspect of that. The game changer was in how references are dealt with!

The object model was the number 1 selling point for PHP 5. There was some criticism that PHP became too Java-like, but the vast majority of the community was thrilled.

However, it took a bit before people could drop PHP 4 support. Only around PHP 5.2, the 5.x series became really good and people started migrating en-masse.

Using public, protected and private was, aside from the feature, almost worn like a badge of honor. This is PHP 5 code and we love PHP 5. It says loud and clear that PHP 4 is unsupported and behind us.

But since then, the PHP 5 object model became the new normal, and we’ve never gone back and challenge the use of public.

But then, what about var?

The public keyword can be removed from every function and every property declaration, with one exception: A non-static, non-final public class property:

<?php

class Foo {

    public $ew;

    // These are all fine:
    final $yay;
    static $whoo;    

}

It’s the last place you’ll find public in my source. So I’ve been toying with the idea of ditching public there too and just start using var:

<?php

class Foo {

    var $ninetiesThrowback;

}

The arguments for this are a bit weaker, but I think they’re still valid:

  1. If public is not anywhere else, it would be nice if you also don’t need it for properties. If ditching public becomes the status-quo, then needing public for properties might actually become confusing.
  2. I think var is more useful to convey intent than public. It’s a “variable on a class” not “a public” in the same way that the function keyword is useful. I think this is better for newcomers to the language.

However, I haven’t made this change from public to var yet, given the uncertain nature of it’s future. So my plead to the PHP project is: “Keep var and promise to maintain it. There’s no overhead and it’s a nice little keyword. And to everyone else, consider ditching public too!

I’ve written a little fixer for php-cs-fixer that automatically removes it for you. If you are able to recognize your biases and join me, I guarantee that it won’t take you long to be happy you made this change!

Web mentions

Comments

  • MFixPL

    Totally disagree. I even think you should always specify visibility level - even if you write the default - public - you have to consider if it is accurate so the chance for error in the code drops. Also argument about reading speed is not really good. Our sight is scanning first - when we are used to it we skip it so fast that we shouldn't really bother about drop in speed (if any). More we should care how many of us will have to slow down our code reading to get to know it is public (because not stated, we have to think about it). May do more harm than good imho. And for the var - will look ok for public, will be very strange when you will have public and private next to each other.

    • Evert

      Evert

      What you're saying is that there would be an adjustment period, which I fully agree with.

  • technik

    Being honest, I really tend to agree with that proposal.
    But still ... following PSR standards is being taken by almost everyone as principal of "good" coding.
    Which is sometimes frustrating because, a lot of people tend to put names and blindly disagree to whoever propose something new, instead firstly actually think about the proposal and than simply test it.
    As far as I know, in Ruby default visibility is public and you don't declare it, and no one has any problem with it.

    • DFYX

      In Ruby, only methods are public by default. In fact, instance variables can never be public on their own, they're always private*. You can use the attr_accessor helper to generate the some default getters and setters with the same name as the instance variable but apart from some eval trickery there's no way to directly access another object's instance variables.

      * Ruby's private works more like protected in other languages.

  • OOP_guru

    I disagree. I never used 'var' and never miss that. Keep public keyword is ok, but private visibility should be default.

  • Boyd Bueno de Mesquita

    I switch between C# and PHP a lot. I feel that omitting 'public' (and 'private') will take me a split second to remember what the default is. Not strongly against omitting though.
    I actually didn't know about the 'var' keyword in PHP, so I wouldn't miss that.

    • AndrewEddie

      Agree. Because not all languages (and possibly future versions of PHP) share the same "default", it's better to be explicit.

      • Ben Carroll

        If typing

        `$foo = ;`

        Was default to `true`, I sure wouldn't use the syntax.

  • Fahad Hossain

    I disagree as well, if i see the word public I know immediately what the scope/visibility is. Its not so clear when you just say static. and var is almost never used and doesn't provide any extra insight into the scope of said variable. and with JS developers growing, it will just confuse them thinking that's how variables are declared everywhere...

  • Rik Meijer

    I'd rather see private be the default for instance variables and thus want to explicitly use public. Public instance variables blow up encapsulation.

    • Rasmus Schultz

      Best comment on this thread so far :-)

      Of course also completely unrealistic, because of backwards compatibility, but you're still right.

      Of course what this post proposes in the first place is completely unrealistic for the same reason, and the whole discussion is a total waste of time - though I suspect the hidden, rhetorical point the author is really trying to make with this post is not "deprecate public", but more like trying to make the point that you could argue in favor of removing public just as well as for removing var. And he kind of has a point. The difference of course being that almost nobody actually uses var and almost everyone uses public.

  • Fab G

    Btw: Properties can't be defined as final:

    „Note: Properties cannot be declared final, only classes and methods may be declared as final.“
    http://php.net/manual/en/la...

    • Evert

      Evert

      Thanks. Makes no sense looking back :)

  • Olivier Laviale

    "public" has actually a purpose because it can be used to changed the visibility of an inherited method/property. Quick example:

    ```php
    class A
    {
    protected function do_something()
    {
    echo "something";
    }
    }

    class B extends A
    {
    public function do_something()
    {
    parent::do_something();
    }
    }

    $b = new B;
    $b->do_something();
    // "something"
    ```

    • Evert

      Evert

      In your code sample you can omit public, and it will still do the same thing.

  • toughduck

    Best practices change and paradigms are questioned. PHP is, and has been, a very flexible language.

    "If ditching public becomes the status-quo, then needing public for properties might actually become confusing."

    Indeed. And what if you decide to ditch visibility entirely? ;)

    • Evert

      Evert

      I think there are benefits to visibility. Some people even mark their classes consistently as 'final' to prevent overloading. I could definitely live with making the private and protected keywords 'suggestive'-only though.

  • Deric Cain

    Using var would take some getting used to for me. However, I wouldn't mind dropping the public declaration.

  • PHLAK

    This argument makes a lot of sense to me and I agree PHP should remove "public" and keep "var" for the specific case mentioned. The resulting code definitely feels cleaner and more readable.

  • Sander

    When a method has no public in front of it you'll never know if someone forgot to think about the scope or not.

    • Evert

      Evert

      I've never really ran into that situation. I imagine that's only really the case in really sloppy/badly designed code-bases. When do you ever not know what visibility to use?

      • Sander

        I mean that you don't know if someone forgot the scope key word (and the method should not be public) or omitted it on purpose. Of course that's a bad thing but their might be juniors working on the project with less skills.

  • Rasmus Schultz

    I use "public" simply to indicate that I've thought about visibility - so no one has to wonder if I simply forgot to declare the visibility or really intended for something to be public. I also do other double assertions in my code, for example I use an @return void tag to assert that a function isn't intended to return anything - again, it just communicates the fact that I've thought about it, and didn't just forget the return statement. It helps with static analysis in PhpStorm as well.

    Have I ever missed public for things like classes and consts? Of course not. That's completely rhetorical. Classes do not HAVE visibility levels, so the concept of "public" doesn't even apply. Silly.

  • Danne

    We already have an identifer for a variable; $. Why would we need "var"? Also, "public" is there for consistency, for when "protected" and "private" is not used.

  • Alankar More

    May be my suggestion is wrong but if some ask me what I would like to write var or public I will go for the public keyword. The reason behind this is that if we observe the other object oriented languages like Java (Which is pure object oriented language) the visibility is must while declaring the function or the class members.

    If we omit this "public" keyword and when we declare any protected or private function at that time we have to put the visibility keyword before the function name. So for keeping the same structure and not to make code ugly I would go for the public keyword even if "public" is completely optional.

  • Ricardo Sánchez

    The problem is that it is too simple that everybody can have an opinion on this, bikeshedding :)
    All should be public and simple, it is php, not java or c++, all these validations are in runtime, what a failure of design. After all, they can be called from other contexts with the help of a closure and bind method.
    It is sad to see that the php developers waste their energies in this topic instead of inlining functions or defining a less verbose closure definition like hack language does.

  • Micheal Mand

    It looks like the RFC did not pass.

    I agree with several people here that have said private should be the default if no scope was set. It just makes more sense to me that you have to explicitly allow a property or method to be publically accessible.

  • zakius

    Explicitly stating access is really good thing IMO: whenever you switch between languages with different defaults, whenever you had longer break with given language or even whenever you just had enough it makes things clear, it is just like with braces: you can omit them for single liners, but why would you do that?
    But the var is redundant as it serves exactly no purpose (unless you omit the public keyword)

  • Saithis

    If you have omit the public on yout methods methods and also have some with private/protected, then you can't scan that easily from top to bottom over the method names, because the difference where they start is greater. Also it's harder for people, that switch between languages (mostly C#/Java).

    I would rather see the "function" as optional and then drop that in my code.

  • Christian Ramelow

    Omitting the accessor will force your code to be unportable while other languages have another default accessors.

    In a private context you can act how you prefer it. And a small script can be fixed quiet fast. No one but you cares. And it's ok.

    But in a business context this descision is based on currently unknown but maybe upcoming further needs. Big projects will become deadly costly when porting them.

    We had libraries to port into JAVA and every language dependend issue is a matter of time and money then. And a lot of issues can be forced on the one hand or be prevented on the other one.

    It's a decision of beeing disciplined from scratch. That means to decide for restrictions to increase standardized usability, language independend lifetime cycles and cost reduction. So the PHP RFC voting has to focus on standards.

    Kick out var.

    It had its rights to exist but it's a relict. Codes using var are relicts, too. Using these codes is often necessary until now and I accept a reasonable importance. But these codes should be executed in a separated secure environment supporting older versions of PHP. Things cannot be downwards compatibile til the end of time.