Re: [RFC] Transform void into an alias for null

From: Date: Mon, 02 Jun 2025 23:46:07 +0000
Subject: Re: [RFC] Transform void into an alias for null
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-127544@lists.php.net to get a copy of this message
Hi Gina

On Mon, Jun 2, 2025 at 6:28 PM Gina P. Banyard <internals@gpb.moe> wrote:
>
> RFC: https://wiki.php.net/rfc/void-as-null

After a read, I think I fundamentally disagree with the proposal. It
says (regarding the status-quo):

> * void is not a subtype of a function with a mixed return type

This is laid out as a downside, but I don't think it is. Consider this
example under the specified behavior:

    interface MapInterface {
        public function set(string $key, mixed $value): void;
    }

    class Map implements MapInterface  {
        public function set(string $key, mixed $value): void {
            // Store the key/value pair _somehow_
        }
    }

Let's assume the return type MapInterface::set() mixed instead,
where the intention is for set() to return the previous value, or
null if there was none. This change will go completely unnoticed by
Map::set(), because void is now just null, which is a subtype
of
mixed. This is a bug that would previously have been caught,
notifying you that you're supposed to return _something_.

Similarly, the code function foo(): void { return null; } is now
proposed to be valid, and I assume the inverse for void/return; is
also true. In this example, we now update Map::set() to the new
return type.

    class Map implements MapInterface  {
        public function set(string $key, mixed $value): mixed {
            $oldValue = /* Fetch old value _somehow_ */;
            // Store the key/value pair _somehow_

            if (!$this->observers) {
                return; // This line was here before.
            }

            $this->observers->notify($key, $oldValue, $value);

            return $oldValue;
        }
    }

Good examples are hard, but imagine Map::set() would allow notifying
a list of observers about changes to the map. Previously, the
return; would have prevented an erroneous call to notify() on
null. However, now it is missing the returning of $oldValue. This
is another bug that would previously have been caught. In fact, even a
missing trailing return $something; would not be caught anymore.

IMO, these checks are useful enough not to be removed.

Please let me know if I'm missing anything.

Ilija


Thread (26 messages)

« previous php.internals (#127544) next »