Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:82161 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 29201 invoked from network); 8 Feb 2015 19:25:10 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Feb 2015 19:25:10 -0000 Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.169 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.169 mail-we0-f169.google.com Received: from [74.125.82.169] ([74.125.82.169:39523] helo=mail-we0-f169.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8D/50-26926-518B7D45 for ; Sun, 08 Feb 2015 14:25:09 -0500 Received: by mail-we0-f169.google.com with SMTP id k48so2018954wev.0 for ; Sun, 08 Feb 2015 11:25:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=EXXM1ow2b8wF3lR7nxx7jux0EMa3AfpwDjOrpDvkqGs=; b=pAlEGQrYrEmQIHhq6FBxyir0VKiqqGUOBNuKCvF4OF0aelDibMTQsNuVQL7AMqj33C zGZeC/ZRnIaE/szDcFYIJdXTvdhgh6eRjWejiVC543LzeDwfvhmzaxQycM0AQJcOtHOx 0hCJSI4KxvrcqQk50fWUyIxHz2Xm5Kru9M1MauIF8VavH2OBb2MbSerzWpWv+lJOPVoa rUVeO5Mn2BhPqkwraX7zL5TMF4f+nHUnqyxj7JHKvRMktM6H/XiQuPUYyYw3j5exqpO5 wLLeM4tLF7161z5s5kyjQujkTBoiCfY+3H8DD7u3LZ4qWyFrRkbDnn8Mvz7skwcUde/F GKQA== X-Received: by 10.194.143.109 with SMTP id sd13mr33390851wjb.70.1423423504898; Sun, 08 Feb 2015 11:25:04 -0800 (PST) Received: from [192.168.0.2] (cpc68956-brig15-2-0-cust215.3-3.cable.virginm.net. [82.6.24.216]) by mx.google.com with ESMTPSA id k6sm11223551wia.6.2015.02.08.11.25.04 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Feb 2015 11:25:04 -0800 (PST) Message-ID: <54D7B80F.2060504@gmail.com> Date: Sun, 08 Feb 2015 19:25:03 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: internals@lists.php.net References: In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] I declare declare to be useful... potentially... From: rowan.collins@gmail.com (Rowan Collins) On 08/02/2015 09:20, Patrick Schaaf wrote: > Am 08.02.2015 03:39 schrieb "Rasmus Lerdorf" : >> Basically declare() does not respect function scope, but it doesn't let >> you know that. There is a reason we haven't used declare() for anything >> real. > That is absolutely awful. But it's a fault with declare. Can't that be > fixed once and for all by fixing declare parsing - when used that way > inside a function, make its scope end with the end of the function, as we > would all have expected it to be, and as it would be when used in the > declare-with-a-block-form? > > I chose a different subject, as it's an issue separate from the strict > typing thing itself. > > declare is, to me, a very useful construct. Somebody recently wrote that it > is "just" a localized version of ini settings. That's right - it's the way > language (interpretation) settings SHOULD BE: give the power LOCALLY to the > coder, with effects LOCALLY in the file and/or scope where it is used, and > for the selective purpose given in the declare conditions. This is the ONLY > sane way to make such switches. It does not magically make code fail when > nonlocal stuff (ini settings) is changed, and it is more-locally > reversible, in its block form, when needed. > > It is all about giving power to the calling code, which is a good thing > with the potential to resolve several of the long standing discussions on > this list. I applaud Andrea for having seen this, and followed through with > it, regarding strict type checks. Other issues that may be solved in a > similar way, using declare as a local behaviour switch, are: > > * scoped, stacked modifications to error handling: > * overriding, for a while, the current global error handler > * autoconversion of errors to exceptions > * autoconversion of exceptions to errors > * suppression of error output (without affecting handling itself) > > * assertions/pre/postconditions, as recently discussed in the DbC thread > > * an in-PHP alternative to #ifdeffery, for leaving out code fragments based > on the presence or values of already defined constants. Something I'd love > to have.... This would provide a nicer way for BC and FC handling code, and > if declare could be made to pretty much ignore the detailled content of its > block (except for curly brace matching), would even work out for reserved > keyword issues. > > * a generic way to change ini settings with automatic resetting at the end > of the declare block/scope. > > * a hook for extensions to introduce new declare conditions, with the > extension getting, in AST form, the condition value, and a way to > selectively operate on the declare block or rest-of-file AST. > > > So there you have it, my vision of what poor mistreated declare could be. > Do with it what you like. > But I had to write it down... I agree with pretty much everything in this post. While it is messy to have a language with too many runtime behaviours, it's much more useful to have them explicitly and lexically scoped than to have them either global or dnyamically toggled at runtime, which are the options ini settings have now. The problem, I guess, is in how you implement it - does the declare directive have to cause the compiler to emit different opcodes for this file, or does it require extra code to run on every entry and exit. For instance, this would be really useful to wrap around legacy code that is being phased out rather than improved: declare(error_handling=E_WARNING|E_ERROR) { function foo() { ... } function bar() { ... } } The only way I can think to implement that is to add opcodes to the beginning and end of each function to push and pop the setting each time the code is called - the low-level equivalent of "$old_eh = error_reporting(E_WARNING|E_ERROR); ... error_reporting($old_eh);" I don't know how much overhead that would incur in practice; presumably unlike @ it wouldn't defeat optimisations, since the start of a function definition is always a boundary to that kind of thing anyway? > Apart from fixing the declare function scoping thing, a second modification > might be needed in general, to go forward and backward with it afterwards: > _ignore_ unknown declare conditions, with a safe semantic meaning of > leaving out the block (or rest of file, in the nonblock form, a la > __halt_compiler!) altogether. I think it's a shame that declare() itself wasn't always implemented with forwards-compatibility in mind. In some cases (probably including strict types) the declaration itself could be completely ignored, rather than causing the file to be parsed as empty (which is probably no more useful than it emitting a parse error). I wonder if it's feasible to write extensions for *old* versions of PHP which add new declare() directives? Regards, -- Rowan Collins [IMSoP]