RFC: autoconst

php.internals

Serhii Smirnov

5 years ago
Hello! This is my first RFC proposal. I have an idea about introducing autoconst keyword. Motivation: reduce duplicated code (copy/pasting constant name as value) reducing potential typo errors in constant values instead of defining constants like: const FOO = 'FOO'; they could be defined like: autoconst FOO; // defines a constant FOO with the value 'FOO' Also, modifiers could be useful: autoconst uppercase foo; // defines a constant foo with value 'FOO' autoconst lowercase FOO; // defines a constant FOO with value 'foo'; and maybe: autoconst camelcase FOO_BAR; // defines a constant FOO_BAR with value 'fooBar' autoconst snakecase fooBar; // defines a constant fooBar with value 'foo_bar' could be listed like: autoconst FOO, BAR, BAZ; autoconst lowercase FOO, BAR, BAZ; What do you think about that? If you like my idea, I would request a karma for creating this RFC in the wiki. Hope you'll like the idea!

Ayesh - PHP.Watch

5 years ago
> > Hello! > > This is my first RFC proposal. I have an idea about introducing autoconst keyword. > Motivation: > reduce duplicated code (copy/pasting constant name as value) > reducing potential typo errors in constant values > > instead of defining constants like: > const FOO = 'FOO'; > > they could be defined like: > autoconst FOO; // defines a constant FOO with the value 'FOO' > > Also, modifiers could be useful: > autoconst uppercase foo; // defines a constant foo with value 'FOO' > autoconst lowercase FOO; // defines a constant FOO with value 'foo'; > > and maybe: > autoconst camelcase FOO_BAR; // defines a constant FOO_BAR with value 'fooBar' > autoconst snakecase fooBar; // defines a constant fooBar with value 'foo_bar' > > could be listed like: > autoconst FOO, BAR, BAZ; > autoconst lowercase FOO, BAR, BAZ; > > What do you think about that? If you like my idea, I would request a karma for creating this RFC in the wiki. Hope you'll like the idea!
Hi Serhii, With Enums supported in PHP 8.1, I think this pattern of using constant names with identical values will see fewer use cases. I also don't think that a proposal to add new common keywords like `uppercase` / `snakecase`, or adding any magic to constant names (because PHP 7 supported case-insensitive constants) will be received well either. Thanks, Ayesh.

Max Semenik

5 years ago
вс, 1 авг. 2021 г., 14:22 Serhii Smirnov <free.smilesrg@gmail.com>:
> instead of defining constants like: > const FOO = 'FOO'; > > they could be defined like: > autoconst FOO; // defines a constant FOO with the value 'FOO'
Sorry, but I'm not a fan of this proposal. Features should not be aiming at minor savings of keystrokes at the expense of readability and maintainability. Remember, we write code once but afterwards it might end up being read hundreds of times. This proposal makes code less readable, and unintuitively works differently from enums where cases without explicit values don't default to anything. Also, modifiers could be useful:
> autoconst uppercase foo; // defines a constant foo with value 'FOO' > autoconst lowercase FOO; // defines a constant FOO with value 'foo'; > > and maybe: > autoconst camelcase FOO_BAR; // defines a constant FOO_BAR with value > 'fooBar' > autoconst snakecase fooBar; // defines a constant fooBar with value > 'foo_bar' >
This one saves even fewer keystrokes and harms maintainability even more: imagine you're debugging your program and you've dumped some value. You see "MyConstant". Now you search the code for the source of that value but find nothing because instead of MyConstant there's only MY_CONSTANT.

Serhii Smirnov

5 years ago
I am surprised that you called this proposal makes code less readable. Which code is more readable: const SOME_LONG_NAMED_CONSTATN_FROM_ENVIRONMENT = 'SOME_LONG_NAMED_COSNTATN_FROM_ENVIRONMENT'; or autoconst SOME_LONG_NAMED_CONSTATN_FROM_ENVIRONMENT; ? Also, could you see a typo error in the classic const definition?

Rowan Collins

5 years ago
On 01/08/2021 12:21, Serhii Smirnov wrote:
> instead of defining constants like: > const FOO = 'FOO'; > > they could be defined like: > autoconst FOO; // defines a constant FOO with the value 'FOO'
While I've certainly seen constants like this in the past, I think they mostly fall into two categories: A) Constants where the value doesn't actually matter, and you just need something to compare input against. As of PHP 8.1, we will have enums, where you can just write "case FOO;" and not assign any value at all, which can probably be used in most of these situations. B) Constants where the value matters, but the constant name isn't actually conveying anything. Given your suggestion of built-in transforms for lower-case etc, these seem like what you're interested in. These often arise from a misunderstanding of the dogma to "avoid magic numbers and hard-coded values", and result in code that looks like it's SHOUTING without conveying any extra information. For instance, people start with this: echo "Hello, " . $name ?? "World"; And think that they can "avoid hard-coding" like this: private const HELLO='Hello, '; private const WORLD='World'; // ... echo self::HELLO . $name ?? self::WORLD; But these constants aren't actually doing anything useful - the code is harder to read not easier, and it would be very odd to later change the value of "const WORLD" without also changing its name. In order to actually be useful, the name of the constant needs to convey something other than its value, like this: private const MESSAGE_GREETING='Hello, '; private const MESSAGE_DEFAULT_NAME='World'; // ... echo self::MESSAGE_GREETING . $name ?? self::MESSAGE_DEFAULT_NAME; I think if you eliminate constants which can now be enums, and fix constants which are badly named, there won't be enough uses left for this new feature to justify its inclusion in the language. Regards,
-- Rowan Tommins [IMSoP]

Serhii Smirnov

5 years ago
> 1 авг. 2021 г., в 17:08, Rowan Tommins <rowan.collins@gmail.com> написал(а): > > On 01/08/2021 12:21, Serhii Smirnov wrote: >> instead of defining constants like: >> const FOO = 'FOO'; >> >> they could be defined like: >> autoconst FOO; // defines a constant FOO with the value 'FOO' > > > While I've certainly seen constants like this in the past, I think they mostly fall into two categories: > > A) Constants where the value doesn't actually matter, and you just need something to compare input against. As of PHP 8.1, we will have enums, where you can just write "case FOO;" and not assign any value at all, which can probably be used in most of these situations. > > B) Constants where the value matters, but the constant name isn't actually conveying anything. Given your suggestion of built-in transforms for lower-case etc, these seem like what you're interested in. > > These often arise from a misunderstanding of the dogma to "avoid magic numbers and hard-coded values", and result in code that looks like it's SHOUTING without conveying any extra information. For instance, people start with this:
I was more interested in autoconst keyword that reduces copy/pasting constant name as it's value. camelcase and snakecase is an addition. A real example why I wanted to use autoconst: on the past project, we had class that holds constants with the feature flag names. Something like: class Features { const FEATURE_FLAG_WITH_SOME_LONG_NAME = 'feature_flag_with_some_long_name'; const FEATURE_SOME_ANOTHER_COOL_FEATURE = 'feature_some_another_cool_feature'; } later, in the code we had to check if certain feature is enabled in the system: if ($featureManager->isEnabled(Features::FEATURE_FLAG_WITH_SOME_LONG_NAME)) { // some feature related code goes here } The class Features could be written as: class Features { autoconst lower FEATURE_FLAG_WITH_SOME_LONG_NAME, FEATURE_SOME_ANOTHER_COOL_FEATURE; }

Rowan Collins

5 years ago
On 01/08/2021 16:59, Serhii Smirnov wrote:
> class Features > { >     const FEATURE_FLAG_WITH_SOME_LONG_NAME = > 'feature_flag_with_some_long_name'; >     const FEATURE_SOME_ANOTHER_COOL_FEATURE = > 'feature_some_another_cool_feature'; > }
That looks like it falls into my first category: the actual value of the constant doesn't matter, you just need to be able to compare against it later. That makes it a perfect use case for PHP 8.1's new "enum" type, where you'll be able to declare this: enum Feature {      case FEATURE_FLAG_WITH_SOME_LONG_NAME;      case FEATURE_SOME_ANOTHER_COOL_FEATURE; } You can then even define the "isEnabled" function so that it only accepts Feature values, not strings (i.e. "public function isEnabled(Feature $feature): bool { ... }" instead of "public function isEnabled(string $feature): bool { ... }"). If you're not familiar with the new enums, the best documentation at the moment is probably the RFC which proposed them: https://wiki.php.net/rfc/enumerations I'm really looking forward to using them :) Regards,
-- Rowan Tommins [IMSoP]

Serhii Smirnov

5 years ago
Thank you! Seems like Enum covers this case. вс, 1 авг. 2021 г., 21:58 Rowan Tommins <rowan.collins@gmail.com>:

Pierre

5 years ago
Le 01/08/2021 à 17:59, Serhii Smirnov a écrit
> I was more interested in autoconst keyword that reduces copy/pasting constant name as it's value. camelcase and snakecase is an addition. A real example why I wanted to use autoconst: on the past project, we had class that holds constants with the feature flag names. Something like: > > class Features > { > const FEATURE_FLAG_WITH_SOME_LONG_NAME = 'feature_flag_with_some_long_name'; > const FEATURE_SOME_ANOTHER_COOL_FEATURE = 'feature_some_another_cool_feature'; > } > > later, in the code we had to check if certain feature is enabled in the system: > > if ($featureManager->isEnabled(Features::FEATURE_FLAG_WITH_SOME_LONG_NAME)) { > // some feature related code goes here > } > > The class Features could be written as: > > class Features > { > autoconst lower FEATURE_FLAG_WITH_SOME_LONG_NAME, FEATURE_SOME_ANOTHER_COOL_FEATURE; > }
Hello, Having an implicit by-convention name reducing algorithm from constant string seems very obfuscated and dangerous, especially for a preference name. This means that if you fix a typo anywhere, it'll implicitly change the underlying acceptable value for anywhere your configuration comes from (env var, database, configuration file, ...). This means that will create a maintenance burden for anyone using such autoconst this way. The right way to handle those situation is not by writing less code, but by writing more, you should explicitly map your preference names over in-code constants, any attempt in doing otherwise will cause you trouble at some point later in time. So I don't think this is a good example, in my opinion this is more an school use-case example of what you should never do ! Regards,
-- Pierre