Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98477 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 38535 invoked from network); 11 Mar 2017 06:36:42 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 11 Mar 2017 06:36:42 -0000 Authentication-Results: pb1.pair.com smtp.mail=michael.vostrikov@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=michael.vostrikov@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.161.181 as permitted sender) X-PHP-List-Original-Sender: michael.vostrikov@gmail.com X-Host-Fingerprint: 209.85.161.181 mail-yw0-f181.google.com Received: from [209.85.161.181] ([209.85.161.181:36667] helo=mail-yw0-f181.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 05/00-38004-AFA93C85 for ; Sat, 11 Mar 2017 01:36:42 -0500 Received: by mail-yw0-f181.google.com with SMTP id o4so35907057ywd.3 for ; Fri, 10 Mar 2017 22:36:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=QxWCvx5k08Qwx6ZyYdTZtcdi5sZw87MRXlgaFGrQUsU=; b=VRBknFFPMipdmK5VQBh9MjD8ALfOzxgXlkERViPmKiY/qLjRwjKEEYL1SqznyoRdoz aAjPQFg+tYgH6QRgKdMve8xALlL5ogfgzb9HOPPxAmew0ZohzqVLzCruqR0Sh6P0fp4n ZvfCC57JinEo1PSiPYlwxtgxKH7FSmEKatCiiw88x63DZhkJO21bbjlWj2W2ykYVO3x5 knrRMcuRIsvUhhiMTrUxgqVNSu+TrsL78F/05iZ5mPjaiobIUB3/tC4Mcf5miAj7HMHC Oi1BaI+7rUJmQq2UMT1HSbSC8l8R+qwhdZ4PVHthgHI53lu/9DQ1tQBgrfGMsSih+HFy mg1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=QxWCvx5k08Qwx6ZyYdTZtcdi5sZw87MRXlgaFGrQUsU=; b=l3kTcg3UIQsXgerKBzAJwlEWLPWiWAZX8iD2sXqysU5tvQOBFhQksuxuwWG+9zpRa+ jRJijRzXPyQnz6FTJGuB3lEM+WUB4LgPeWgW2T7b2Ak8B4xRhXS2FPL3KGSyKSZ6w0Ef FCXQwI4gb65Iqs7bfe8bxgJrLxGzGTUIGJWtMsPQUKzg1aoGmWwb3ToAIm7y3wGAI9UL INag4EPbHKQaGrPk4rce4dUFnA9bfK3VF/BVjczEAp82Ei25Yr6EcoUGefI4k/ratx/x 2TNxpMboIZ7djPC7y1F0kgWPYhwjJEH1IUejvh6bCt99B1TzlXhLp7iiK/xI3kmARIDc FIvA== X-Gm-Message-State: AMke39kF/eBq5sRgS64ApVGObFrfJbuLa9jox9ilWJVdBaMlNpxh+JoVygenWNqXKV9Eo3ew73qsjodoXHNRlw== X-Received: by 10.13.225.80 with SMTP id k77mr11348135ywe.83.1489214199301; Fri, 10 Mar 2017 22:36:39 -0800 (PST) MIME-Version: 1.0 Received: by 10.13.224.196 with HTTP; Fri, 10 Mar 2017 22:36:38 -0800 (PST) Date: Sat, 11 Mar 2017 11:36:38 +0500 Message-ID: To: PHP Internals Content-Type: multipart/alternative; boundary=94eb2c071944580d15054a6eb391 Subject: [PHP-DEV] Type variants From: michael.vostrikov@gmail.com (Michael Vostrikov) --94eb2c071944580d15054a6eb391 Content-Type: text/plain; charset=UTF-8 Hello. I have an idea which seems rather useful. I would like to know your opinion, Let's say we have class Rectangle and need to have class Square which will be used in some operations. We don't need any rectangle, this must be only square. What if we could describe a type which is the same as another type but have some restrictions for properties? Something like this: class Rectangle { private $x; private $y; private $width; private $height; public function __construct($x, $y, $width, $height) { $this->x = $x; $this->y = $y; $this->width = $width; $this->height = $height; } } class Square variant of Rectangle { public function __match() { if ($this->width != $this->height) { return ['width' => 'Width and height have to be the same']; } return true; } } function drawSquare(Square $square) { // ... } $rectangle = new Rectagle(0, 0, 10, 10); drawSquare($rectangle); When drawSquare() is called, the check 'instanceof' is performed. It calls magic method __match(). If __match() does not return true, it throws an exception with the data returned: 'Order does not match OrderForCheckout. Reason: ...'. Technically, we don't have method __match() in $rectangle object. So it can be static, or a proxy object can be created here. The second variant can be extended. We may not to inherit implementation of methods, and describe another interface instead, for example new object can be read only. class Square variant of Rectangle { public function ___match() { // ... } public function getWidth() { return parent::getWidth(); } } With some changes in syntax it can be defined in this way: class Square variant of Rectangle { ... getWidth: base::getWidth; } This is like inheritance, but semantically differs a little. Inheritance has vertical direction, type variants have horisontal one. Also type variants have an access for all methods and properties of base class, even for private. Another example. Let's say we have an order checkout process which is splitted into 3 steps - cart for products, date page, delivery address page. This is not an input validation, this is a validation in business logic. class Order { public $products; public $date; public $address; } class OrderForCheckout variant of Order { public function __match() { $errors = []; if (empty($this->products)) { $errors['products'] = 'Product list is empty'; } if ($this->date === null) { $errors['date'] = 'Date is not selected'; } if (empty($this->products)) { $errors['address'] = 'Address is not selected'; } return (empty($errors) ? true : $errors); } } public function checkout(OrderForCheckout $order) { ... } $order = findCurrentOrder(); checkout($order); // if $order does not match requirements, the exception will be thrown --94eb2c071944580d15054a6eb391--