On Wed, Jul 15, 2020 at 10:43 AM Marco Pivetta <ocram...@gmail.com> wrote:
>
> Hey Larry,
>
> On Wed, Jul 15, 2020 at 5:32 PM Larry Garfield <la...@garfieldtech.com>
> wrote:
>
> > 1) return null, which is a non-type, and thus you need to make the return
> > type ?User or User|null, which means the caller *must* always check it's
> > nullness.
> >
> > Allowing an object to falsify itself is a 4th,  more type-safe option.  It
> > lets you return an object that both fails a boolean check (like null) but
> > also has default values in it for the base case.  A user object likely
> > wouldn't use that, but a value object like an Address very well could.
> >
> > Until we can support for-reals monads (which would require enums and
> > generics to do properly; the former is possible the latter is very hard),
> > it's the best option we have for more type-safe returns.
> >
>
> Adding a "falsey" state for code that expects `is_object($foo) === (bool)
> $foo` seems to be a massive BC break to me, and reduces type safety of
> boolean operators (and checks) by expanding the `object` type and all
> operators and expressions that can interact with it.
>
> In general, `?T` is very much equivalent to `Maybe T`
>
> Where `instance Monad Maybe` is implemented in type-safe langs as (quoting
> https://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe - I
> omitted `return` because the lifting bit is not really used in PHP):
>
>  ```hs
>     (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
>     (>>=) m g = case m of
>                    Nothing -> Nothing
>                    Just x  -> g x
> ```
>
> `?T` is very much the same in PHP (pseudo-code, since nullability is not
> represented the same way in Haskell):
>
> ```hs
>     (>>=) :: ?T -> (T -> Maybe T2) -> ?T2
>     (>>=) m g = case m of
>                    null -> null
>                    x  -> g x
> ```
>
> Let's not confuse Java nullable issues with PHP nullability, which is quite
> healthy :-)
>
> I see adding a "falsey" evaluation to something that has been assumed (for
> a looooooong time) as universally "truthy" is a very major issue.
>
> We need code examples where this is a clear advantage over previous logic:
> as it stands, I don't see why I would ever prefer `(bool) $object` over
> `$object !== null`, or `$object->valid()` (which I believe to be an
> anti-pattern)

In my opinion, it seems reasonable to be able to swap out an array for
an object that implements Traversable, ArrayAccess, Countable, etc in
common situations. However, this is not possible in at least two
common situations:

    if ($array) {
        // ...
        foreach ($array as $key => $value) {
            // ...
        }
        // ...
    }

    if (!empty($array)) {
        // ...
        foreach ($array as $key => $value) {
            // ...
        }
        // ...
    }

You could swap `!empty()` for `count > 0` , but I can imagine objects
where we can know that we aren't empty without knowing the full count.
For example, a database result using a cursor or something; we'll know
on the first response if we have even 1 result, but we won't know the
final count ahead of time.

Of course, there are cases where we can't do this swap because of
`array_*` specific functions anyway, but my point is rather that from
a language perspective it seems like a reasonable goal to pursue.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to