Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98469 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 89862 invoked from network); 10 Mar 2017 11:41:44 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Mar 2017 11:41:44 -0000 Authentication-Results: pb1.pair.com smtp.mail=narf@devilix.net; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=narf@devilix.net; sender-id=pass Received-SPF: pass (pb1.pair.com: domain devilix.net designates 209.85.218.41 as permitted sender) X-PHP-List-Original-Sender: narf@devilix.net X-Host-Fingerprint: 209.85.218.41 mail-oi0-f41.google.com Received: from [209.85.218.41] ([209.85.218.41:35562] helo=mail-oi0-f41.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 83/C5-31244-6F092C85 for ; Fri, 10 Mar 2017 06:41:43 -0500 Received: by mail-oi0-f41.google.com with SMTP id 62so50182934oih.2 for ; Fri, 10 Mar 2017 03:41:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=devilix.net; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=+fziXMu8ftuOyXH8bTQYxAgsDzkXmtVZrdhypXmaOfA=; b=nOJPfjX524SiDMtXDZpPExoOlxufXoh5rjy60GLMAhrUneuzn+gAhaNxhS7kbNgV1q HJO0Nb4EdZtyf4UA6Rx9cwcCsHRtz6HHe6tYku3yR6ARzYU+iAteFMMIAHIXnz6dLqNT ZHr9O3xVZkhFrxLt+oOTt3GSUwVTpfiJ8ODp4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=+fziXMu8ftuOyXH8bTQYxAgsDzkXmtVZrdhypXmaOfA=; b=lEtispa+GmlQ12m9BGJnOE1sJmfqCtxWlRW7nEhAthEK7X+Sp4P8XL/taYuG6+QVuc 2Kv5GcrCpLDNWXySxw//LOxDIU9mgQWYMibBRWrPtJEEoJ+L7RWTFfOyizfT/0ZlU5K2 l2lPYVXfXFAyYBHONWTPDjoR5tHNKp+s3UnLO13JWsqCGqk67LLQoegWoDgfyre3ryGM NmKMgFiME8BrMjUDoc+VT8J6LLLu3pRc8AzwowNzKpYJ8frAV0/rcOSHemOfkRZ8rC4s 7iBoWGSRfGe/84FrrBEoqx5akuoL8bMatWaXQqSc61iEAFRgr8DKIbBOSph8Xe3zxOLV hYYw== X-Gm-Message-State: AMke39kOKX/tMhoqmeOKBc5VScDvcSoIJ+DWYSQUUYeUeJJZSOwSNqXmk+EsboV0smKT/1sTU15LIwF5m5HTDg== X-Received: by 10.202.79.13 with SMTP id d13mr9793335oib.167.1489146100272; Fri, 10 Mar 2017 03:41:40 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.242.83 with HTTP; Fri, 10 Mar 2017 03:41:39 -0800 (PST) In-Reply-To: References: <24efb0e7-b0e3-68ed-5f42-2d5481f8f291@gmail.com> Date: Fri, 10 Mar 2017 13:41:39 +0200 Message-ID: To: Rowan Collins Cc: "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString() From: narf@devilix.net (Andrey Andreev) Hi Rowan, On Thu, Mar 9, 2017 at 10:09 PM, Rowan Collins wrote: > On 08/03/2017 23:32, Andrey Andreev wrote: >> >> For example, a Cookie object may have the cookie attributes (domain, >> path, etc.) as value objects, but they can easily be created from raw >> strings, while other types would be ambiguous. >> A similar effect could be desirable for HTTP headers. > > > OK, now we have some concrete examples, thanks. I would say that in these > cases, what you actually want is a much tighter contract: not just "can be > converted to string", but "intended to be used in this context". > I know you're trying to help, but I keep reading this as "OK, now I can try to invalidate your use case". There's always an alternative solution. I only ask that our alternatives here include a middle ground between the two extremes of "accept pretty much everything" and "be as strict as possible". > It fits with what I was saying before about "if you can't name it, maybe it > isn't the right abstraction". In this case, you want to accept some > particular value objects but not, say, Exceptions - which are as useless for > your purpose as an integer, even though (string)$foo would work fine on > both. > I can name it; the name is just ridiculously long/impractical because __toString() is a special case unlike anything else in PHP. > So you want objects that have promised to behave appropriately for this > context; that could be as simple as: > > interface HTTPHeaderObject { > public function __toString(); > } > > ...with appropriate documentation that objects declaring that they implement > this interface promise to behave in a specific way when cast to string. This > is much clearer than detecting __toString(), which only promises "I can be > cast to string" - the same promise that is made by all scalar values. > My argument is that while every scalar value may promise that it "can be cast to string", the fact that you need to explicitly declare it means that only __toString() can promise that it "can be useful as a string" (context-dependent of course). > > In order to accept this or a string in a type hint, you need Union Types: > > function setHeaderValue(string|HTTPHeaderObject $value) { ... > I would love union types, but unfortunately: - https://wiki.php.net/rfc/union_types was declined - They only address parameter hints, and I also want runtime checks - Would still leave a gap for me, as I (perhaps stubbornly) want to treat __toString() objects as regular strings Though, I can live with the extra function call if we have union types as that would greatly reduce my needs related to that last point. > > For broader use, we could perhaps have named unions: > > type HTTPHeaderType = union(string, HTTPHeaderObject); > if ( $value instanceOf HTTPHeaderType ) { ... > An excellent idea, indeed - I'd be a huge proponent of that. > > Meanwhile, of course, you can just use a boring old user-defined function: > > function is_valid_http_header_value($value) { > return is_string($value) || $value instanceOf HTTPHeaderObject; > > } > Yes, and I can already wrap is_string($var) || method_exists($var, '__toString') in a function, even "override" the original is_string() with my version, in a namespace. The point was to eliminate that boilerplate code. ---------------- Obviously, I'm getting zero support on the idea and we're running around in circles at this point, so I guess that's it from me here. Cheers, Andrey.