Typed Properties in PHP 7.4
stitcher.io
stitcher.io
Anything that improves overall code quality of this language should be welcomed with open arms. Types, especially if they are backward compatible (as these are) will do so.
I'd be interested in what kind of automated or ide support will be available, but I suppose that won't be known until this is released later this year.
Other editors (VSCode for example) can hook into Psalm or Phans Language Server to get type information from these static analyzers.
Typing support in PHP Ides is usually excellent.
I don't know the state of the language server for newer php versions, but intellisense for vscode is too taxing on the CPU for relatively large projects (20k+ lines of code)
Don't they fall under the cheaper individual license?
[0]: https://www.jetbrains.com/phpstorm/buy/#personal?billing=yea...
[1]: https://sales.jetbrains.com/hc/en-gb/articles/206386064-What...
Already Chairs, Desk and Rent for every engineer is more expensive than 200 USD every year. Their salary is many hundred times 200 USD. I pay more for coffee and water that they can get for free every year.
Independent devs without income can get PHPStorm at much lower rates.
Notebooks in Brazil are almost three times as expensive as abroad, internet costs are through the roof here as well as living costs...
I thought this through, I just have a harder reality than you I guess
And if you are an individual, the license is just 89 USD.
If you are an individual contractor, then maybe you quality for a startup discount? This also gives you 50%: https://www.jetbrains.com/phpstorm/buy/#personal?billing=yea...
They also have an Early Access Program that you try out beta releases, and they are free of cost.
Individual license starts at $89, and fall to $71 in the first renewal, then to $53 onwards. So I think it is not that expensive. YMMV.
In my part of the world it is, too. But I don't think that's the case for _every_ engineer worldwide.
First, that $200 rate is for teams; independent devs can pay a significantly lower rate (the catch is, you have to pay it personally, not expense it or be reimbursed by an employer).
And even for teams, $200 a year is nothing. If you can afford to hire devs in a first world country (US/EU/Aus/etc), you can afford tools for them. NO employer you should possibly consider working for is going to quibble over the license fee; not when they're already paying 1000 times that in fully loaded costs in salary/rent/overheads/benefits/etc.
If you can't find $200 for a tool to help you do your job, you're not really a professional. (Again, in a 1st world country.)
The thing I do not agree is that you have to pay for tools in order to be a professional. That is quite elitist. People make careers out of free platforms like Linux so for an IDE is not asking much to have a good tool for free. The community benefits from labor put into developing a free tool.
Absolutely not! You don't have to pay, and there's tons of free tools which are top rate.
What I said is that if you're a professional, you're able to pay for the tools that are worth it. If Phpstorm is worth it (and I think it is, but many devs I respect feel otherwise), $200 is deeply affordable by Western standards.
As a professional, you should have a budget for things like software licenses, books, donations to open source projects you really like, etc., whether that comes out of your funds as a consultant, or team's budget, etc. If your employer is too stingy to cover things like Phpstorm licenses...they're not treating you like a professional.
(Again, in first world/Western countries. Budgets and pay scales are different in some places!)
I am sorry if I misinterpreted you, but that was precisely what you said.
Elaborating, I agree with you, reinvestment is really important to improve work and product quality.
If you have the money to spend on tools, but think Linux or VS Code is best, that's fine.
If OS X would be better for you, but you use Linux because you can't afford the tools you need, that's a problem.
Being able to find the money for something doesn't mean you have to spend the money. At the price point of a few hundred dollars a year or less, my concern is what's best, not what's cheapest. The company I work for will happily buy a Phpstorm license for any dev who wants one, but some are happy with VS Code, and one holdout is still using NetBeans. Nothing wrong with that!
I can't imagine having to justify a subscription to IntelliJ at this workplace. At least I imagine you can bring your own license to Jetbrains on a work computer here, at least that is my understanding and I won't ask anyone lest they say I am wrong!
Just in IT it is now fashionable to feel entitled to earn money without buying tools, then comes dual licenses, closing doors or acquisitions because devs don't pay supermarket with pull requests.
Why pay $ amount per year when there are great open source products available?
The list goes on, but gratis isn't always better just because you don't need to pull out your wallet.
In general choosing open source saves you time with yearly licease management, licease audits and removes the risk of surprise price increases and product shutdown.
Commercial support can be invaluable and can provide more value over community support. Commercial support for a code editor is wasteful in terms of cost/value and wasteful timewise (who is calling spending time about a macro feature not working).
They are paid for by future development and / or increased adoption.
Take the most popular open source editor (vscode). Do you think microsoft is getting value from this open source product? Why didn't they charge a yearly licease fee instead of open sourcing it? They were probably more interested in increased adoption...
Not about corporations doing open source as advertising stunt.
Which is precisely why anything I produce, is either commercial or under GPL.
- The yearly cost is purely for updates. Meaning you could just pay one time, get updates for a year and then continue using whatever version you have. - For small teams they offer a 50% discount (less than 10 people, in business less than 5 years) - If this is perhaps an open source project you can get it for free.
I got sucked into the Jetbrains family because of just how good their PhpStorm is. Especially in regards to refactoring and debugging tools.
I only wish their Javascript tools were anywhere near as good as their Php tools.
I guess this is partially because JavaScript is a much harder language to write good tooling for, but I'm open for other explanations.
You get the version available when you pay, and then you get a year of updates, which you can only continue using if you renew the license.
So you can only use the version available as of the moment you pay for a license.
Most shortcuts are only three keys instead of relying on both hands, files get incrementally compiled on save, just like Netbeans I can use Ant or Maven as the project format, indexing actually stops instead of being done every time application starts, my humble laptop doesn't sound like a propeller plane getting ready for take-off, Javadoc works out of the box without having to dive into settings, no more hunting for problems, easily displayed dynamically without having to trigger manual inspections, ...
Particularly for open source software it's hard to just say "from next version well use 7.4 min" so anything that can be added and fallback gracefully on older versions is handy.
This is a minor release and PHP tends to be almost completely BC even between major release versions so it's unlikely you'll face any issues.
If you want to start writing code that uses these features in an existing library then you can branch a new version that depends on PHP 7.4, and define that as the requirement in composer. That way users with older PHP versions will pull older versions of your library.
Similar to browser docs what you're often interetested in is the latest things and how far back you can use them, and where they will degrade gracefully further back.
Those mostly assume you have old code that you want to make work on new versions, not that you want to write new code that takes advantage of as much new stuff as possible while still working reasonably well on old versions.
It's understandable that they would prefer that everyone just upgrade faster, so it's probably not something they want to encourage (both in documentation and in making features degrade gracefully if that requires any tradeoffs.).
Psalm supports all the same checks on typed properties that it already does for properties with docblock-defined types, and will make sure all your properties are properly initialised in a class's constructor.
I find it hard to trust a language that changes so much between minor versions. If I am wrong please tell me where so I can stop my grief at work and finally upgrade the PHP version we use.
Is that true?
So maybe upgrading PHP itself might not be that bad, something I can't tell you for sure, but in my experience nobody uses vanilla PHP, they all wrap it in frameworks, and those must all be carefully upgraded too.
There are a few edge cases out there of course. Maybe your code base has basically been in stasis since the early days of PHP 5.x, may not even be using composer or namespaces, relies on tons of abandoned or horribly outdated dependencies, doesn't have good test coverage, etc., and then suddenly someone gets a bee in their bonnet about PHP 7.x and wants to upgrade. That's often not going to work out very well, but that's not really a PHP 7.x (or even a PHP thing). :) If you've been maintaining the code, have tests, no ancient vulnerable libraries, using current framework versions, etc, the process is going to be easy. If you're trying a big bang upgrade straight from the medieval period, not so much!
The past years we've seen several static analysers become more and more popular in the PHP community. Tools like phpstan (https://github.com/phpstan/phpstan) and psalm by Vimeo (https://github.com/vimeo/psalm).
Allowing this syntax is a great way to write cleaner code that can be statically analysed, which is far more superior than the runtime type checker.
Using GraphQL in the PHP backend und frontend TS. The schema is exported to TS and thus everything is fully types. A blessing.
All in all in 20 years we'll all be writing ml ?
[0] technological waves diffuse differently across cultures
The reason is that i want to know "on site" what exactly is going on when reading and debugging code, especially outside a "smart" IDE, like when diffing changes via the command line, a web-based VCS frontend or some code review tool - especially since these tend to not show the entire code, meaning i need to switch back and forth. But even with an IDE that can show me the inferred types, it is almost always (while i say "almost always" i really mean "always" since i haven't seen any other, but there might be some IDE i haven't tried) done through some popup under the mouse cursor, meaning it is transient and slow.
For similar reasons i dislike features like operator overloading, placing non-self-initializing logic in constructors (and the equivalent in destructors), properties for anything that involves complex calculations (unless the language uses special syntax for properties that make them stand out when used) especially for getters, i prefer to use names that hint to what the code does (e.g. i'd use something like "get_foo" only if it doesn't do any calculations and give you a precomputed or cached "foo", otherwise i'd use an "action" verb like "calc_foo" or "find_foo" or whatever to hint that there is some calculation going on and isn't just a dumb getter), i avoid exceptions as they create hidden exit points for functions (and if the IDE/editor allows, i use a more visible - like bold red - font for "return" or the language equivalent so that explicit exit points are obvious), etc.
Yeah, these make code more verbose and you need to type more, but IMO the negatives are grossly overwhined against and while the positives way too overlooked.
So you prefer
std::vector<some_template<some_foo>> foo = new std::vector<some_template<some_foo>>();
Rather than replace the first one with var / let / auto / whatever your language does? Why? The type is already there.And even then that this is only in the very specific case you showed, where the type is too long, it is repeated and the constructor parameters - if any - are visually dwarfed by the duplicated type.
In practice these aren't as common as other uses of types like loop iterators for member/obtained collections (where the use of 'auto' makes it impossible to know the collection type unless you check the collection declaration) or local variables you assign to the result of some function (the return type of which again you need to check the function declaration to see) and - at least in C++ - you rarely need to do "very_long_foo* bar = new very_long_foo" as a stack allocated "very_long_foo bar" is enough (so no need to double type the type).
What's more, that's a highly unusual example. Rarely would you need to heap allocate a vector. In the case of stack allocation the syntax would be `vector<T> myVec` which is as succinct as possible.
And the language you use is probably using aliases too in it's stdlib, so why hate on aliases? They are a great way to abstract away the details.
The boundary I prefer is to explicitly type function signatures, and leave everything else (or as much of it as I can) inferred.
Your refactor will contain more lines of code since it'll need to also contain the updated use sites, but i do not see that as a problem at all - and even if it is one, it is only a short term small problem that is certainly not as important as having the code more obvious and readable in the long term (assuming of course you feel the same about readability as i do - after all as i wrote in my message above it is a subjective issue :-P).
I'm talking about statically typed languages also, just ones with inference. Haskell, Rust, Ocaml, F#, Go, etc, and increasingly languages like C# and Java are adding more and more inference.
Your response makes me think you don't really get what type inference is.
The tooling around has also improved so they can do it now.
I like the idea of language to support more type features because there is no one ultimate type of solution for everything and in every situation.
Moreover, these are all safe changes. There is less possibility for developers to abuse these features compared to what they can do with implicit conversion, for instance.
The trade-off between Java 7 and PHP 7.x is that Java has generics, but PHP's treatment of nullable variables is better/safer.
If everything goes well, yes. Everything is moving towards static typing with local inference.
If a static analyzer can detect these mistakes, why even add runtime checks for it? Think TypeScript/Javascript, after the compilation is done, most type checks are removed for performance reasons.
Or perhaps there is something I don't see...
Only when you then add them after the upgrade you should have tests for that or a static analyzer that tells you the changes you make are correct.
Still, static analysis is necessary when you upgrade dependencies and for your own code. For example for seeing whether adding a type to a property breaks code somewhere else. Discovering type errors at runtime is often too late.
Luckily there are good static analyzers for PHP.
I’m not 100% that it is a wonderful behavior, and a lot of people turn it off (which can be done on a per file declaration of strict) but for us it’s genuinely helped eliminate an entire class of error where a runaway type error would result in a really whacky value way down the line, even occasionally ending up with that stored in the database for some calculation.
The kind of thing we still end up with in JavaScript to this day.
https://dev.to/mindplay/php-typed-properties-think-twice-382...
I'm also seeing that with JavaScript and TypeScript.
TS feels very C# like.
Luckily there seem to be counter movements with languages like Reason, ClojureScript and PureScript.
Probably because they were created by the same person!
C is not really moving, but C++ is also converging towards this Java++ language.
Java itself is finally moving.
C# is a bit ahead of the curve, because it can follow the trail blazed by F#.
PHP started moving towards Java back from when PHP5 was introduced.
Javascript is moving towards Typescript which is following C#'s lead.
Python is kind of the only non-Algol mainstream hold out.
Did I miss any of the big enterprise languages? :-?
It's in the Algol family, mostly indirectly through ABC, Modula-2 and 3, C, ...
Per the interview, string slicing actually came directly from Algol-68 (and Icon).
TS was influenced mainly by C# at the start, then from FlowType and currently it's mainly influenced by ECMAScript.
So to me it feels like the other way around.
Here we get a pretty good deal, I guess time matters.
Why in the world are people comparing PHP and Java?
They just ignored the fact that Java is compiled which makes all the layers of abstraction less of an issue whereas PHP is interpreted at runtime* hence why there are few high traffic websites on PHP that don't have at least four layers of caching.
* Yes, I know this is getting better with every version, opcache getting a lot of attention in the last few minor releases and all that, but there is only so much optimization you can do with dozens and dozens of layers of factories and services. My guess is that it does a LOT more for "simple" software like WordPress and less for, say, Symfony based projects.
Usually, statically typed languages is not expressive. There are a lot of abstractions are hard to express in statically typed languages. Even in Haskell. With optional typing, you can express usual ideas with types, and cheat with 'any' when not applicable.
Another thing is the language itself can possibly execute without compile or even type check. Making developing feedback cycle much smoother when running tests or just save and refresh.
If the "Any" type is just a top type but you have to downcast it to use it, like in Kotlin, then it's not considered optional typing, since you still have to talk about types ;).
This adds up to essentially making everything nullable, regardless of if the type is defined as nullable, and adding an entire class of runtime errors that could have been avoided.
A new state was not necessary.
This is going to result in a new series of run-time-only bugs that PHP is famous for. I love the language but it's 2019 and we should be past this. Also, where are the generics?
Urgh. It baffles me that 10 years after their introduction, anonymous functions (closures) remain useless when assigned to instance properties.
class Foo {
public $var;
}
$foo = new Foo();
$foo->bar = function() { echo "Hello World\n"; };
$foo->bar();
Uncaught Error: Call to undefined method Foo::bar()
Callables work perfectly fine when assigned to standalone variables or array members: e.g. $foo[0](); But they become nonfunctional when assigned to instance properties. I understand that using closures as instance properties would make them hard to distinguish from methods, but blurring that distinction is just so damn useful in JavaScript! class Foo {
public $var;
}
$foo = new Foo();
$foo->bar = function() { echo "Hello World\n"; };
$foo->bar->__invoke();
Not pretty but that's how I've always done it.Example:
$c = new stdClass;
$c->test = function() { return 'hello world'; };
echo ($c->test)(); $response = (new Response())->handle ();
So it's not completely alien in PHP.I don't know how these patterns develop - it's very common in JS, but somewhat rare in PHP. Maybe it has to do with the average level of the programmer in each? Or jQuery's noConflict() helped it along with everybody starting with (function($) {})(jQuery), thus integrating IIFE into their active repertoire.
I don't remember (and haven't found in quickly searching) PSR saying anything about that, but that could explain a difference in usage, too.
Anonymous functions and classes are being used more and more, but PHP isn't fundamentally event-driven like JS so there's less need to hand them out like candy and nest them several levels deep. Most of the closures I do use on a daily basis are callback functions to things like array_filter() and preg_replace_callback(), not event handlers like every jQuery code ever written.
<?php trait MetaTrait {
private $methods = array();
public function addMethod($methodName, $methodCallable)
{
if (!is_callable($methodCallable)) {
throw new InvalidArgumentException('Second param must be callable');
}
$this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class());
}
public function __call($methodName, array $args)
{
if (isset($this->methods[$methodName])) {
return call_user_func_array($this->methods[$methodName], $args);
}
throw RunTimeException('There is no method with the given name to call');
}
}
?>test.php <?php require 'MetaTrait.php';
class HackThursday { use MetaTrait;
private $dayOfWeek = 'Thursday';
}$test = new HackThursday(); $test->addMethod('when', function () { return $this->dayOfWeek; });
echo $test->when();
($foo->bar)();
Methods and properties are (perhaps regrettably) separate namespaces in PHP.Prototyping stuff without bothering with types and adding them when your code matures to root out some bugs and make it more futureproof seems to me like the best of both worlds.
Seriously I have noticed that static vs dynammic preference is quite sustainable thing for people. Even if you are have used lot of both most people prefer the one they are used when they 'got it' during their programming learning path.
I don't really understand that CSV example what's the problem but one concrete challenge I have noticed with static types is when you want do mutation which effectively change the type. Instead of setting just new property you have to potentially do dummy copy (including type) or some additional hashmap by id for this additional data.
(btw I am not your down voter)
I'm not sure why other people like dynamic languages but there must be some advantages.
Your chickens will eventually come home to roost, but the short-term productivity gains are quite pleasant.