Constans in namesapces

php.internals

Dmitry Stogov

19 years ago
Hi, The proposed patch implements namespace support for constants. It allows to declare constants in namespaces in the same way as in classes. And these constants may be used in the same may as namespaces' functions. <?php namespace Foo; const BAR = 5; var_dump(BAR); ?> <?php include "foo.php"; var_dump(Foo::BAR); ?> I am going to commit this patch on Friday. Any objections? Thanks. Dmitry.

Dmitry Stogov

19 years ago
Sorry, The patch was removed. Resending it. Dmitry.

Johannes Schlueter

19 years ago
Hi Dmitry, On Wed, 2007-08-22 at 13:02 +0400, Dmitry Stogov wrote:
> Hi, > > The proposed patch implements namespace support for constants. > It allows to declare constants in namespaces in the same way as in classes. > And these constants may be used in the same may as namespaces' functions.
I like the idea. Am I right with the assumption, from scrolling over the patch, that "const" outside any namespace would work, too, meaning we could get compile-time constants even outside a namespace? johannes

Dmitry Stogov

19 years ago
You can have "const" outside namespaces but they are not real compile-time constants. They are set during execution in the same way as define() does. <?php const DIR = dirname(__FILE__); echo DIR; ?> Thanks. Dmitry.

Pierre Joye

19 years ago
On 8/22/07, Dmitry Stogov <dmitry@zend.com> wrote:
> You can have "const" outside namespaces but they are not real compile-time > constants. > They are set during execution in the same way as define() does. > > <?php > const DIR = dirname(__FILE__); > echo DIR; > ?>
Off topic but this const makes me think about hidef (see pecl/hidef). It would be nice if we can have them resolved at compile time. At least when no instructions are involved in the definition (numbers or single quote strings). Cheers, --Pierre

Dmitry Stogov

19 years ago
We never resolved constants in compile time, because constants' values may be unknown in compile time. Thanks. Dmitry.

Pierre Joye

19 years ago
On 8/22/07, Dmitry Stogov <dmitry@zend.com> wrote:
> We never resolved constants in compile time,
I know that, hence my "see pecl hidef" comment.
> because constants' values may > be unknown in compile time.
The idea behind that was to get constants like internal constants. If it is a integer, a float or a single quote string, it can be known at compile time, just like class constants (no expression, function or double quotes string). --Pierre

Antony Dovgal

19 years ago
On 22.08.2007 17:03, Dmitry Stogov wrote:
> You can have "const" outside namespaces but they are not real compile-time > constants. > They are set during execution in the same way as define() does. > > <?php > const DIR = dirname(__FILE__); > echo DIR; > ?>
Don't you think it's bad idea to use the same 'const' syntax, but different behavior? I believe it would be really confusing for users, as class constants are set in compile time, thus 'const DIR = dirname(__FILE__);' is not possible.
-- Wbr, Antony Dovgal

David Zülke

19 years ago
yes. keep it consistent. if that means sacrificing features, so be it. David Am 22.08.2007 um 15:20 schrieb Antony Dovgal:

Dmitry Stogov

19 years ago
Good point. We'll need to discuss this. Thanks. Dmitry.

Stanislav Malyshev

19 years ago
> Don't you think it's bad idea to use the same 'const' syntax, but > different behavior? > I believe it would be really confusing for users, as class constants are > set in compile time, thus 'const DIR = dirname(__FILE__);' is not possible.
That's a good point. However, "constant constants" - i.e., ones not allowing expressions - would be much less useful, since many uses of the constants - as used by define() - imply runtime evaluation - such as pathes, configuration-derived variables, etc. On the other hand, const in classes indeed doesn't allow us to define runtime expressions. This is, however, offset by the fact that we have per-class variables, where we can store expressions. In namespaces we don't have (and probably don't want) per-namespace variables, so if you need to keep something like dirname(__FILE__) somewhere inside namespace, you have no option. We could try to solve this by changing const to some other keyword. The downside would be that we'd have further complicated the syntax. We could modify define() or add ns_define() which would automagically add namespace prefix. More options? If anybody has any good idea of how to solve this, suggestions are welcome. The summary of the problem is as follows: 1. We need some syntax to define per-namespace values. 2. For these values are to be useful they should allow runtime definition 3. const syntax looks like class constants which allow only compile-time definition
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Antony Dovgal

19 years ago
On 22.08.2007 21:08, Stanislav Malyshev wrote:
>> Don't you think it's bad idea to use the same 'const' syntax, but >> different behavior? >> I believe it would be really confusing for users, as class constants are >> set in compile time, thus 'const DIR = dirname(__FILE__);' is not possible. > > That's a good point. However, "constant constants" - i.e., ones not > allowing expressions - would be much less useful, since many uses of the > constants - as used by define() - imply runtime evaluation - such as > pathes, configuration-derived variables, etc.
Which basically means class constants are useless in their current state, right?
> On the other hand, const in classes indeed doesn't allow us to define > runtime expressions. This is, however, offset by the fact that we have > per-class variables, where we can store expressions. In namespaces we > don't have (and probably don't want) per-namespace variables, so if you > need to keep something like dirname(__FILE__) somewhere inside > namespace, you have no option. > We could try to solve this by changing const to some other keyword. The > downside would be that we'd have further complicated the syntax. We > could modify define() or add ns_define() which would automagically add > namespace prefix. More options? > > If anybody has any good idea of how to solve this, suggestions are > welcome. The summary of the problem is as follows: > 1. We need some syntax to define per-namespace values. > 2. For these values are to be useful they should allow runtime definition
I don't think it's _required_ for the constants to be useful. It would be good to have, but not required. I prefer consistent behavior vs inconsistency with more features.
> 3. const syntax looks like class constants which allow only compile-time > definition
-- Wbr, Antony Dovgal

Stanislav Malyshev

19 years ago
> Which basically means class constants are useless in their current > state, right?
No, they are useful for some things (pre-defined values) and useless for others (expressions). The problem is that in classes we can do these other things - with variables. And in global space, with define(). In namespaces, we can't.
> I don't think it's _required_ for the constants to be useful.
Well, depends on how you define requirements. Having out-of-class constants is not required either - Java does fine without it :) However, thinking about how people would use namespaces, I think it would be very useful. And btw we have some precedent of reusing syntax - "static" means different things as "static function" and "static variable", and very well might to acquire yet another meaning as static:: IIRC. I don't say it's necessarily good thing, but it's not without precedent.
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Antony Dovgal

19 years ago
On 22.08.2007 21:50, Stanislav Malyshev wrote:
>> I don't think it's _required_ for the constants to be useful. > > Well, depends on how you define requirements. Having out-of-class > constants is not required either - Java does fine without it :) However, > thinking about how people would use namespaces, I think it would be > very useful.
I believe useful things should not bring confusion, which is clearly the case. We do have runtime constants created with define(), so the critical need in runtime namespace constants is quite questionable to me.
> And btw we have some precedent of reusing syntax - "static" > means different things as "static function" and "static variable", and > very well might to acquire yet another meaning as static:: IIRC. I don't > say it's necessarily good thing, but it's not without precedent.
Inconsistencies and mistakes done in the past cannot be a reason to create more of them, so I don't understand why you even mentioned 'static'.
-- Wbr, Antony Dovgal

Stanislav Malyshev

19 years ago
> We do have runtime constants created with define(), so the critical need > in runtime namespace constants is quite questionable to me.
"Critical need" is a matter of definition. You can do define(__NAMESPACE__.'::foo', 'bar') but frankly, it sucks. const foo = 'bar' looks so much better. That said, you are welcome to propose non-confusing syntax achieving the same :)
-- Stanislav Malyshev, Zend Software Architect stas@zend.com http://www.zend.com/ (408)253-8829 MSN: stas@zend.com

Antony Dovgal

19 years ago
On 22.08.2007 22:25, Stanislav Malyshev wrote:
>> We do have runtime constants created with define(), so the critical need >> in runtime namespace constants is quite questionable to me. > > "Critical need" is a matter of definition. You can do > define(__NAMESPACE__.'::foo', 'bar') but frankly, it sucks. const foo = > 'bar' looks so much better. That said, you are welcome to propose > non-confusing syntax achieving the same :)
I propose to define these constants in compile time or change class constants to be defined in runtime. Either ways are ok to me.
-- Wbr, Antony Dovgal

Richard Lynch

19 years ago
On Wed, August 22, 2007 8:03 am, Dmitry Stogov wrote:
> You can have "const" outside namespaces but they are not real > compile-time > constants. > They are set during execution in the same way as define() does. > > <?php > const DIR = dirname(__FILE__); > echo DIR; > ?>
You do realize this is going to engender a few zillion threads on PHP-General benchmarking the two and endless arguments about which is faster/better... <?php const DIR = dirname(__FILE__); define(DIR, dirname(__FILE__); ?> I personally find it kinda silly to have TWO syntaxes for defining constants in the global space, one of which looks like a declarative statement in C, which will lead to a whole new swath of arguments about what is "better" Why is 'define' any different than 'class' or 'function'? Seems to me that if you want these namespace thingies that badly, then 'define' should follow the same rules as any other declarative keyword. If you 'define' something in the namespace, it's in the namespace. If you want global scope, 'define' it outside a namespace and be done with it. Seems to me you're just complicating things with no real-world need here... What are your real-world "I need this because..." code samples?
-- Some people have a "gift" link here. Know what I want? I want you to buy a CD from some indie artist. http://cdbaby.com/browse/from/lynch Yeah, I get a buck. So?

Dmitry Stogov

19 years ago
We already have class constant that use declarative syntax and of course define() inside of class doesn't declare class constant. The same was done for namespaces. Thanks. Dmitry.

Dmitry Stogov

19 years ago
Hi Richard, "const" is usefull to declare "compile-time" constants in current scope (class or namespace). The syntax is the same. It is not allowed to use functions and variables in such declarations (this ability was proposed but then it was removed before commit). define() is a runtime function that allows declaring constant at run-time. Of course this function defines constants in global scope. Thanks. Dmitry.