4 ms·
Am I alone in thinking that the syntax for nullable types is bizarre? "function example(): string? {" vs "function example() : ?string {"
by colept 10y ago
Am I alone in thinking that the syntax for nullable types is bizarre?
"function example(): string? {"
vs
"function example() : ?string {"
- ludwigvan 10y agoRead "?" as nullable, as in "nullable string".
- skissane 10y agoI don't mind it. Think of it this way – ? is a function from types to types. Given type X as input, it returns the union of X and the type of the null value. Once you start thinking of it as function application, putting the symbol which represents the function before the argument seems a perfectly rational thing to do.
- maweki 10y agoThat makes it doubly funny since the real reason is that the parser couldn't handle the other case. Even a blind php dev...
- TazeTSchnitzel 10y agoThere's nothing wrong with the lexer or the parser. Avoiding becoming like C, where lexical analysis can't be done without knowing context, is a good thing. PHP actually once supported this kind of ambiguity (PHP/FI 2.0 ended PHP code with a single > yet also allowed if ($a > $b)), but this wasn't a good idea and resulted from a greatly suboptimal implementation.
- koenigdavidmj 10y agoLast I heard, PHP's lexer and parser do not do well with ambiguity. This is why namespaces use backslash as their separator (since dot and double colon were already taken). Question mark never appeared directly after colon before this, so the second syntax is not ambiguous. The first one would be understood as part of a ternary operator, followed by choking on the start of a block.
- chris_wot 10y agoShould a lexxer and parser "do well" with amiguity ever? I'm not sure I can think of a single one that handles insanely convoluted and ambiguous stuff well at all...
- TazeTSchnitzel 10y agoIn PHP, variables, functions, constants and classes are all completely separate namespaces, and likewise methods, properties and static properties are separate namespaces. Reusing :: for namespaces would complicate this. Is foo::bar a class constant or a namespaced constant? Do we autoload src/foo.php or src/foo/bar.php? If I do `new foobar::qux`, is foobar::qux a class, a class constant containing a class name, or a namespaced constant containing a class name? Do we autoload src/foobar.php or src/foobar/qux.php? It's not like the lexer or parser could magically solve this. The way the language is designed, there is inherent ambiguity here. In some other languages, there is a unified symbol table, so you don't have this problem. But PHP doesn't have that.
- nikic 10y agoCopy-pasting from an answer on reddit (https://www.reddit.com/r/PHP/comments/5eu9pc/whats_new_in_php_710/dafopvm/ https://www.reddit.com/r/PHP/comments/5eu9pc/whats_new_in_ph...): Because the alternative conflicts in case we ever introduce generics. Consider <?php new Foo<Bar?> ?>. This could either be a generic instantiation, or it could be the same as <?php ((new Foo) < Bar) ?> ?> (which is how it is currently interpreted -- this is valid PHP code!) Of course, you could specify how this is to be interpreted and implement the necessary parser hacks to make it happen, but it's best to avoid the issue altogether by using ? as a prefix. I assume that this is also the reason why Hack does the same.
- latimer 10y agoFWIW, this is the same syntax as JSDoc (http://usejsdoc.org/tags-type.html#overview http://usejsdoc.org/tags-type.html#overview).