Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:91834 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 64749 invoked from network); 22 Mar 2016 04:09:42 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 22 Mar 2016 04:09:42 -0000 Authentication-Results: pb1.pair.com smtp.mail=morrison.levi@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=morrison.levi@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.192.173 as permitted sender) X-PHP-List-Original-Sender: morrison.levi@gmail.com X-Host-Fingerprint: 209.85.192.173 mail-pf0-f173.google.com Received: from [209.85.192.173] ([209.85.192.173:34049] helo=mail-pf0-f173.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 5F/12-46740-485C0F65 for ; Mon, 21 Mar 2016 23:09:41 -0500 Received: by mail-pf0-f173.google.com with SMTP id x3so291756074pfb.1 for ; Mon, 21 Mar 2016 21:09:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-transfer-encoding; bh=O8lzz9GTsXDvi0BhfUr9tEQeeGDh5JXBqtMima4n7KA=; b=Q7S56bv3BlQroMghxbqBMkRW5JW6/2RKyZG9TJKyX/5yN+dbFi+8twe+HPNGr83Ei6 LBQl7pRXdog5++dYoSgEBSQeXcjSZHt7UjfqfZi+fLKHSmDooP7HWinoNhjPE9VYd+x4 j6c0A5zcYop4CQU+sX58ladTK6lPZi7zXdUiP2/i5VWiBHpCt+iVvWSTMQ9t+yZGuXvl X5ucWvl0P8Qf296U89A3Pj8/r5uZ8Ov5hd0NV7hTzyOn0YKhzPyZnSik1pqrFkattUfX ZxrDfbRf17S2px9Isiasm1p62pfbHRsJBw1KqAeD8FZTtwyVFDgRagBscgxIctcK8c6W g9YQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:in-reply-to:references:date :message-id:subject:from:to:cc:content-transfer-encoding; bh=O8lzz9GTsXDvi0BhfUr9tEQeeGDh5JXBqtMima4n7KA=; b=ls11vGiiTEr/SenyJeQSNPrsiWzZMm8TRImHouuZ+dAkoOSBfSEq8DsfSYcTWxmb3Q WxjKyqy+Mn3O3YY3LTfyepV91IuC+gChaq9s0mL2fA2me+XQz7J5eum0UKQEVcOyjgLT zZGzKvufUfqMk3Xphp6meRAma7LjJqJJXZej3XnHHXgecRsd7pMu7AecAoOVKKUnxsrf 3MB58GN+c4C7f0D8qaCL313uJT4ED/KhgItL5JpDsxmERMwld4nT/D7nzmjZMS3lLPjQ MduCquFPuq+NaQafDKWP/dHdNAxIfjbOJQ4KDRVRhklFLYjWqyA3U8Ir/JAXxrYR4Ixt 7tdA== X-Gm-Message-State: AD7BkJLtOHJx6Ty22AIyE4vmuBaPsIVDf6przgz21icFalMk4JPn3Uk/EIGwIOd59Ik53yrIsDtTSex2by1yQQ== MIME-Version: 1.0 X-Received: by 10.98.67.139 with SMTP id l11mr50562403pfi.112.1458619778215; Mon, 21 Mar 2016 21:09:38 -0700 (PDT) Sender: morrison.levi@gmail.com Received: by 10.66.163.232 with HTTP; Mon, 21 Mar 2016 21:09:38 -0700 (PDT) In-Reply-To: References: Date: Mon, 21 Mar 2016 22:09:38 -0600 X-Google-Sender-Auth: z_4kqkaTkOTYAwCgMJ_XmEbIOyg Message-ID: To: Stephen Coakley Cc: internals Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Re: RFC Proposal: Maybe monad and execution time polymorphic methods From: levim@php.net (Levi Morrison) On Mon, Mar 21, 2016 at 5:03 PM, Stephen Coakley wr= ote: > On 03/21/2016 03:04 PM, Facundo Martinez Correa wrote: >> >> So I want to "return a NULL". I want to express uncertainty, a >> nonexistence. But I want to express that I will return something. And I >> want to have this NULL checking at interpretation time. I want everythin= g, >> and none of the drawbacks. As we say here in Argentina, I want the bread >> and the cake. What can we do to have it? After a bit of thought the Mayb= e >> monad came to me. >> >> My experience in Haskell reminded me of this. To have a structure than >> represents uncertainty, is the best way to take away the responsibility >> from NULL. To express it in no other way. But my experience in Java has >> taught me that Optional of something is not a good way to tackle the >> problem. I still have to check if my Optional isEmpty. I still have to >> check for null. That is because Java has that type erasure after >> compilation time that doesn't allow me to play nice with polymorphism. B= ut >> maybe PHP can. Maybe PHP will give me the polymorphism at execution time >> to >> discern an empty Maybe from the one that is not. So I don't have to chec= k >> for null ever again in my life. So my code can be free of nulls. So I ca= n >> express uncertainty and nonexistance, while I return a User from my >> repository. >> >> I hope someone would like this idea. I'm also open to suggestions. >> Kind regards >> Facundo Mart=C3=ADnez > > > First of all, let me confess that I absolutely love monad (or composite) > types, and I greatly prefer a Maybe over something that may or may not be > null. There's a slight problem however, and something that will not be ea= sy > to get around: a lack of generics. > > This is an issue with wrapper types in general in PHP, where you want to > wrap an object in some other type. You lose type safety on the inner obje= ct, > and so I tend to look for a more type-safe solution in PHP. There is alre= ady > a generics RFC out there (https://wiki.php.net/rfc/generics) but > implementing it won't be trivial. > > Implementing (or defining) a good Maybe type also depends on better > composite/enum types (https://wiki.php.net/rfc/enum is drafted, but doesn= 't > support what we need). The classical definition would be (hypothetical PH= P > syntax): > > enum Maybe > { > Some { > public function __construct(T $value); > public function isSome(): bool { > return true; > } > public function into(): T { > return $this->value; > } > }, > None { > public function isSome(): bool { > return false; > } > public function into(): T { > throw new Error(); > } > } > } > > Such a definition depends on two different things we don't have right now= in > PHP. Maybe there's a simpler way, but hopefully you have a better > alternative? This requires you to query state with `isSome()`. This is hardly any different from a null case, just more code. We can already accurately distinguish between `null` and another value. If we want an option for safer PHP code I think we need a safer construct that requires exhaustive matching (such as Rust's `match`). I'm not sure how to pull that off.