Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:44619 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 30178 invoked from network); 2 Jul 2009 02:36:20 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Jul 2009 02:36:20 -0000 Authentication-Results: pb1.pair.com header.from=paul.biggar@gmail.com; sender-id=pass; domainkeys=bad Authentication-Results: pb1.pair.com smtp.mail=paul.biggar@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.219.227 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: paul.biggar@gmail.com X-Host-Fingerprint: 209.85.219.227 mail-ew0-f227.google.com Received: from [209.85.219.227] ([209.85.219.227:45881] helo=mail-ew0-f227.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id F4/21-43450-32D1C4A4 for ; Wed, 01 Jul 2009 22:36:20 -0400 Received: by ewy27 with SMTP id 27so1526182ewy.23 for ; Wed, 01 Jul 2009 19:36:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:from:date:message-id :subject:to:cc:content-type:content-transfer-encoding; bh=SyCQqQ/87BgDfoCwa0Ctw6c/y2QKoGBNnrRbu2itkGg=; b=Qp8ma2Iz4S2N0rVxPIA6M6SHwLSzndIqF6ZbmZYIFfZDcmBw6rCgNH9VjO5Ww56wV0 nMOaMjJYY9ekx4gkbdpUxTGYYYrGDR5TLDvxGslH8zdPZaIcDUMjcg3d50YVycR0Yw88 13MMCO0LihhLrn/TjJx9tSJaQi1vzWm5MzIjc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:cc:content-type :content-transfer-encoding; b=uZqUkO421iNfax7oQwZoL6SQas/sQqDxClJ2jrIXhV9HyElcYcu5aD/V3p/SrA+8AS 4/aI3ifel28wUyuEKNitOiwwU22Olmrldt5y62jJM9fA7DszVNI1O7dLVisEvdzpgxvf AeQGLsmhxAdywEUGD5p4hbDboMr693F1W1H2Y= MIME-Version: 1.0 Received: by 10.210.59.14 with SMTP id h14mr211743eba.99.1246502177185; Wed, 01 Jul 2009 19:36:17 -0700 (PDT) Date: Thu, 2 Jul 2009 03:35:57 +0100 Message-ID: To: PHP Internals Cc: ilia@ilia.ws, Derick Rethans , Stanislav Malyshev , Hannes Magnusson Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: Flexible type hinting From: paul.biggar@gmail.com (Paul Biggar) Hi folks, Thanks to Ilia for getting to ball rolling on scalar type hinting. It seems there are 3 camps: - (C) the type checking camp: "when I say 'int' I mean 'int'". This is what Ilia's patch does. - (H) the type hinting crowd: 'int' is a hint to the user that an int is expected. This gels well with PHP's weakly typed scalars. I think few people are in this crowd, but a lot of the (S) crowd are mistakenly thought to be. - (S) the "sensible" middle: 'int' means an integer of course. The manual is written somewhere between (S) and (H). I believe I have a solution that caters to each crowd, without being too complicated. There are advantages and disadvantage to all of these: - The main disadvantage of each system is that it doesnt provide what the other systems allow. Strong is too strong for many. Weak is too weak for most. - Ilia had a very good point against (H), which is that many functions return NULL or FALSE, and there are lots of errors when these are automatically (and silently) converted to 0 or "". (H) will not catch anything. - A strong argument against (C) is that this currently has no parallel with how scalars are handled in PHP currently. - A (I think weak) argument for (C) is that this is how object type hinting works - An argument for (H)/(S) is that the manual has been written in this style, using this syntax. - A good argument against (C) is that it cannot be used to hint PHP's builtin functions. - The (C) crowd suggested numeric and scalar to the (H) crowd, but I dont think they were impressed. - I dont think there is a strong case for a strongly typed bool. Here is the solution: By default, use (S). The semantics of (S) are roughly provided in a table at the bottom. The idea is that for ints, we take "5", and 5, and fail on "str", FALSE, resource, etc. Allow a very easy way to get (C) and (H) using '+' and '-'. "+int" means fail on anything but an int. This is (C). "-int" means "I expect an int, but I'll take whatever you give me, and cast it to an int". This is (H). (H) is for those times where neither (C) nor (S) are suitable, which occurs in the standard library a lot. I hope that it wouldnt be used much otherwise. With each case, the function author can expect that they if they ask for X, they will get an X. I think numeric isnt required anymore, which is good. Example: function add_user (+string name, string phone_number, int age, +int friend_count, resource photo) { ... } We may bike shed for a while about the choice of +/- vs "strict int" or "weak int", as well as some of the choices in (S). Lets argue about the overall idea first, and get to specifics later. If people like this, I can work on the patch. Thanks, Paul ***** This is a suggested semantics for (S) ******** Each line is in the form: "Run-time type -> type hint = result". You may read "x -> y = z" as "an x passed to a hinted parameter y gives a z". * means all types I didn't mention explicitly. ?? means reasonable people may disagree. I would lean towards FAIL in these cases. array -> array = array * -> array = FAIL numeric string -> int = cast to int real -> int = cast to int int -> int = int * -> int = FAIL int -> numeric = int real -> numeric = real string -> numeric = real/int bool -> numeric = ?? * -> numeric = FAIL int -> bool = bool bool -> bool = bool null -> bool = false real -> bool = bool string -> bool = bool * -> bool = ?? null -> null = null * -> null = FAIL array -> scalar = FAIL int -> scalar = int bool -> scalar = bool null -> scalar = null real -> scalar = real string -> scalar = string resource -> scalar = FAIL object -> scalar = FAIL MyObj -> scalar = FAIL * -> mixed = * int -> real = real real -> real = real numeric string -> real = real * -> real = FAIL array -> string = FAIL int -> string = string bool -> string = FAIL null -> string = FAIL real -> string = string string -> string = string resource -> string = FAIL object -> string = __toString() or FAIL resource -> resource = resource * -> resource = FAIL object -> object = object MyObj -> object = MyObj * -> object = FAIL MyObj -> MyObj = MyObj * -> MyObj = FAIL ***** This is a suggested semantics for (H) ******** Whatever is passed will be cast to whatever you ask for, using existing casting rules, even if thats stupid. ***** This is a suggested semantics for (H) ******** If you ask for X, it must be X, except: object with __toString() -> string = string Anything else is FAIL (which I believe is an E_RECOVERABLE_ERROR). -- Paul Biggar paul.biggar@gmail.com