Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:94534 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 5655 invoked from network); 17 Jul 2016 18:53:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Jul 2016 18:53:16 -0000 Authentication-Results: pb1.pair.com header.from=nikita.ppv@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=nikita.ppv@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.161.179 as permitted sender) X-PHP-List-Original-Sender: nikita.ppv@gmail.com X-Host-Fingerprint: 209.85.161.179 mail-yw0-f179.google.com Received: from [209.85.161.179] ([209.85.161.179:34991] helo=mail-yw0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 61/D9-31884-B14DB875 for ; Sun, 17 Jul 2016 14:53:16 -0400 Received: by mail-yw0-f179.google.com with SMTP id l125so143545604ywb.2 for ; Sun, 17 Jul 2016 11:53:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=aNIkMaXrngw559F++3LiTKMJbPEDg2lSThMG6qiVDTw=; b=rhjMJqHpsKwEEE7crwzZr/ca+SAv0iRJrJCfoI9ovL3MLaWAE5Gcgm1F42nvzekXRy iFj1fMuQokl/X7EMABjMPQpiDQVfRJZQHLQxxysvmMh16aZOV9jJFtbDq86dz3hs9XV0 07CMJNMQAugSP9CaDa0Ml4xdbMuK2r1381E7Gf3CYLDrt0pXWud00zYIoDHPYP+9iSN+ gAAFRfWHIMX+wkAsbRcJIFOeR4uFO8qpp73OvbcirxmNwZxFBdOiw4GHv1xdyZh2nOEi l+N8i4/RhASiwYgg6tziVNw6fk4z2L3h6KNRy7Qv6M84O9o6gHU+u8j1f+0jQUa1qVVB CxSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=aNIkMaXrngw559F++3LiTKMJbPEDg2lSThMG6qiVDTw=; b=SrrOxWUgZmfsFLNba37QnEEmOV/r/0r6hmPdSHXTwts2J+iPDVOA8jF7d26ZgoQX8q s6TVz4lY9sTYjaBspEA/e11oWXYVQtJBVkiKaWApIMzJM67fWkocI4Qqn4ufXqIdrCVm VtZNBKPTrhBXqo4AMCElg99RPthjkttAg4E0sWqlVyBr9vsf8IbbsHDWlEg7m1GJCgx3 gfEeS1N0GlILwtexpeaeNzwMCJjSGHDlN2o4znovt9/4AQ9xffmMgeX+qHEARSdTs15R ps7vggOWb3j5OD9PkU7TO9p7F5mbSfyG9LEhRYiGf8sMTiHN9KLt19D5WFaUsWGC4lqV CfoQ== X-Gm-Message-State: ALyK8tKycD69ilNJGtr5wiveudZqdFcO0cqNoU55hLRsbGPBD/aVMtzIurzzRCKXn7cPSwVNjzgtVGuA4DDZIg== X-Received: by 10.129.61.13 with SMTP id k13mr17051515ywa.56.1468781593003; Sun, 17 Jul 2016 11:53:13 -0700 (PDT) MIME-Version: 1.0 Received: by 10.129.131.129 with HTTP; Sun, 17 Jul 2016 11:53:12 -0700 (PDT) In-Reply-To: References: Date: Sun, 17 Jul 2016 20:53:12 +0200 Message-ID: To: Rowan Collins Cc: PHP Internals Content-Type: multipart/alternative; boundary=001a114281141a8d670537d95dc7 Subject: Re: [PHP-DEV] Idea: Function autoloading using dummy namespaces From: nikita.ppv@gmail.com (Nikita Popov) --001a114281141a8d670537d95dc7 Content-Type: text/plain; charset=UTF-8 On Sun, Jul 17, 2016 at 8:21 PM, Rowan Collins wrote: > Hi All, > > In the discussion of escaping mechanisms, it's once again come up that > functions lack autoloading, and thus are hard to work with in larger code > bases. > > Previous solutions to this, most notably Anthony Ferrara's very thorough > RFC [1], have looked at adding new modes for the existing autoload > functions, or new functions alongside, to specify the type being autoloaded. > > A common response is that you can just use a class with static methods, > and thus leverage the existing autoload mechanism. But the introduction of > "static class" or "abstract final class" was rejected [2] in part with the > opposite justification: that you shouldn't need a class to hold static > methods now that we have namespaced functions. > > How about an alternative approach where a function inside a namespace can > be autoloaded using the existing callback, by using a reserved namespace > segment? So to autoload function "foo\bar()", the engine would construct a > string like "__function\foo\bar" or "foo\__function\bar", and pass that to > the registered autoloader stack. > > This shouldn't result in errors or misbehaviour from existing autoloaders, > it just won't find anything to load. An autoloader that knows how can then > use the namespace path to determine what to load, probably something like > "src/foo/functions.php". > > The focus on namespaced functions reflects the fact that > one-file-per-function is rare and somewhat unwieldy, so a call to load > "__function\foo" is unlikely to be that useful in practice. > > Note that, like many previous proposals, this could apply to namespaced > constants, too, using a token such as __constant. > > Any thoughts? Good idea, horrible idea? > I don't like this and strongly prefer handling function autoloading using either separate handler or mode flags, and not magic strings. I don't think this "solution" solves a problem that actually exists. The main problem with function autoloading is not integration, but loading order. Unqualified function calls in PHP have a global namespace fallback, i.e. a call like "foo()" in namespace "Bar" will first check if "Bar\foo()" exists and if it doesn't, try global "foo()" instead. How does function autoloading integrate in this? Option A: foo() in namespace Bar will a) Check if Bar\foo() exists b) Otherwise try to load 'Bar\foo' c) If that fails, check if foo() exists d) Otherwise try to load 'foo' e) If that fails, throw. This has the distinct disadvantage that any unqualified use of a function in a namespace will result in an autoloader call. As practically nobody qualifies all their calls, this would add a huge overhead to each internal function call (those are nowadays the only ones in the global namespace). I don't think this is realistic. As such: Option B: foo() in namespace Bar will a) Check if Bar\foo() exists b) Otherwise check if foo() exists c) Otherwise try to load 'Bar\foo' d) Otherwise try to load 'foo' e) If all fails, throw. This avoids the autoloading overhead when calling functions from the global namespace. However this also means that you cannot autoload a function with the same name as a global function through an unqualified call. In practice, this is probably less problematic than it might sound, because realistically function autoloading would likely operate on the namespace-level rather than the function level, i.e. if one function from a namespace is loaded all of them are, because they are all defined in the same file. In such a setting you would never run into this problem as there would be no unqualified calls to functions that have not been loaded yet. However, it *would* be an issue if you tried to, say, map each function to a separate file. Regards, Nikita --001a114281141a8d670537d95dc7--