Ending PHP Support, and the Future of Hack
hhvm.com
hhvm.com
Are people really that unfamiliar with the history of computer science? There's no hype, there's no comeback; both static and dynamic languages have existed for over six decades. Both styles have been around as long as computer science has been a thing and will continue to exist as long as programming is a thing.
For a long time however, if you wanted a mainstream (well supported, large ecosystem) language with static typing, you pretty much had to deal with languages like Java or C++, with their pretty limited type systems and other unrelated design choices that may not appeal to you. It was either that, or going full dynamic. Or some niche language with poor library support.
These days there are plenty of popular languages where you can get all the benefits of static typing with far fewer compromises (Kotlin, Swift, Rust, Scala, TypeScript, etc.) AND a more expressive type system. So the field has definitely changed.
I'm not familiar enough with the others, but I have A LOT of doubts. Only Scala's type system is clearly more powerful/expressive than Java.
Also, through templating, C++ type system is made quite expressive.
As for the others, check out for example TypeScript's mapped types (https://www.typescriptlang.org/docs/handbook/advanced-types....), or Swift's extensions (https://docs.swift.org/swift-book/LanguageGuide/Extensions.h...).
Considering that Java or C++ don't even have sum types, it's not exactly a high bar to cross.
The syntax for functions and inlining are not part of the type system. Inlining especially, is a useful language feature, and has to be checked at compile-type, but is unrelated with types.
Sum types, really you can have that with just inheritance (base class with package private constructor + final sub-classes). What Java lacks is a nice way to pattern-match/switch over types (which Kotlin does nicely with flow typing), but again that isn't really the type system (although it does make the type system nicer to use, certainly).
It also wasn't available in a practically usable form until relatively recently (when talking about history), so my very first point about the timeline of languages still stands. Plus it adds even more verbosity to an already very verbose language.
>The syntax for functions
I meant function types, e.g. the variable `val a = {}` has a type `() -> Unit`, which is a real type in Kotlin.
Of course you can achieve a similar thing in Java with SAM interfaces (including all the weirdly named ones in `java.util.function`), so I'd call that the same level of expressiveness.
I don't see why `inline` wouldn't be a part of the type system, when you can have a function argument (that is itself a function) that either
- can be passed into anything that expects a function as an argument - as long as the rest of the type matches of course (a non-inline argument)
- can only be invoked or passed into another inline function (an inline argument)
Conceptually, this has some parallels to C++'s const-correctness ("any matching pointer can go here" vs. "only a non-const pointer can go here", "this function cannot be called via this pointer" etc.), which is generally considered a part of its type system.
It's just a matter of definition really.
>Sum types, really you can have that with just inheritance (base class with package private constructor + final sub-classes).
The person that uses those classes (I'll call them consumer), e.g. writes a function that takes the base class as an argument, then has to be aware of the internal implementation - the compiler won't help you there. If someone else who maintains that part of code adds a new subclass, you'll have an unaccounted for possibility and there is no way to safeguard against that (unless you redesign the whole part of the codebase using crutches like the visitor pattern).
There is no good way to express "this value can be one of these types, but no other" in Java's type system from the consumer's point of view (only from the producer's). I may not be using the correct terms here but hopefully you get what I mean. As far as the Java compiler knows, you are not really expressing a sum type, and that comes with the mentioned negative consequences.
Dynamic languages get statically compiled. Static languages have dynamic features. The line is far from clear.
If there's any greater cycle it's that in the end all the good ideas get shared and successful strategies get cross-pollinated.
Unless Facebook's prepared to invest a lot in community-building, Hack and similar FB projects will go the way of VBScript and Silverlight.
What is the disadvantage then? Well, it is not a product, meaning the external users are not the main target of the project.
The project owners have no incentive to implement anything they don't need themselves, or to fix any bugs that don't impact their own developers. It works fine if your own needs happen to be as close as possible to the ones of the project owner, if you patch stuff you need yourself, and if you don't expect anything from the owner in general.
Especially when I compare Flow and TypeScript (I use the first quite heavily, the second occasionally, filed lots of bug reports for both) the difference between them is quite substantial. For TS Anders Hejlsberg himself answers bug reports, and they listen to what the community wants. In the Flow issues you'll find Facebook employees - but not the actual owners (or if there is one they remain hidden). If the Flow team implements something Github users ask for it's almost always only because the need for it happened to also developed inside Facebook.
I have learned the hard way that "open source" is not sufficient, it should actually also be a product (meaning the owner cares a lot about external opinions). That's most important for things like core libraries and tools like those add-on Javascript type systems, not so important for "leaf node" dependencies in your project, like a library that does something specialized.
There are open source projects that succeed because, aside from being good enough, they also have big corps behind them: TypeScript, Dart, Go, Flow, Kotlin, etc.
But there are also open source (often free software) projects that succeed because they're great and are community-focused and community-supported: Python, Haxe, Julia, etc.
I talked about just that, no? About two of that list specifically, even.
1. wait, there are more axes than just license and productization, and
2. there are other values on those axes that can lead to success (not just open source + productized)
Here are some separate axes I see:
* open source (Apache2, BSD, MIT) vs free software (copyleft (GPL, LGPL))
* corp-backed vs not-corp-backed
* community-driven vs closed-style-development
* core devs have a very solid vision of project direction, vs being more open to change and/or direction taken from contributors
* amount of productization: are the main target users the core devs themselves or external users
* overall quality of the language
Some armchair comments:
+ you risk lock-in by going with corp-backed languages
+ you may see more community involvement with free software projects, whereas more corp involvement with open source
+ high productization often means a very low contributor to user ratio
+ although quality doesn't necessarily win, it sure is nice.
I actually like this about FBOS. I’ve found that I appreciate their vision and direction on the projects I use (React particularly, I love their stewardship there, but also Relay, where yeah issues and suggestions are ignored but that’s fine because I like what the team does and the slow pace). I appreciate that they’re not pulled this way and that way by the community and its whims. That’s why I don’t dig Apollo for example, which seems to be one of these community projects that almost exists more for the community than for the product and tries to be everything to everyone and in the end is not something I appreciate technically or even as a community. Of course Relay docs suck but hey it’s open source! I’d rather use a really strong product like Relay than a weaker product like Apollo, even if it means having to learn some internals.
I think the core document is the Runtime Architecture[0]. After that, it really helps to know ES7 Observables, which I learned by studying the little implementation that's included in Relay[1], but apparently is also at the core of Angular. Then you can either use the runtime architecture directly, or the pre-built React components that are included in Relay. If you use the pre-built components, you need to understand the division of labor between the QueryRenderer[2], which fetches data from your server and puts it in the store, and FragmentContainer[3] which lets you render data from the store with React.
[0] https://facebook.github.io/relay/docs/en/runtime-architectur...
[1] https://github.com/facebook/relay/blob/master/packages/relay...
[2] https://facebook.github.io/relay/docs/en/query-renderer.html
[3] https://facebook.github.io/relay/docs/en/fragment-container....
If you're thinking of companies that are still making shit-tons of money productizing programming languages/environments today, Microsoft is the major player, but it's a battle even they are losing. They just open-sourced .NET, their programming bread and butter.
So it will either die off quickly or be extremely popular and stick around for 20+ years?
VBScript is just as old as PHP and was the primary scripting language on Microsoft products for a solid decade. It was in everything from Office to IIS and still ships with every copy of Windows.
Silverlight is just a framework and was only in active development for 5 or 6 years before being killed off.
You can write a single piece of code that's valid C, C++, C#, and Java but that doesn't make them the same language or subsets of one another.
VBScript started out using the same conventions as VB and a subset of the syntax but it was never really related to it beyond that. There are different flavors of VBScript as well. CScript is a console variant, WScript for window environments, and ASP for IIS Web Development. They're mostly compatible but not entirely. When classes were introduced, they weren't immediately available across all the variations and still aren't IIRC.
It's all very confusing though ultimately I don't think that it contributed to the negative connotations about it. Being associated with VB was ultimately what tainted it.
I imagine, at that scale, that opensourcing is a big win because you can have a proprietary stack, but still hire people that already know it, or won't be reluctant to invest a few years of their life into working on it. You also don't have to pay as much for educating new hires as you would for a totally closed proprietary stack, and new people faster become productive. Hiring contractors that work with that stack on a short notice also becomes easier. For a large co, these kinds of benefits might be more than enough to justify cleaning up the code enough to opensource it.
Creating and maintaining a community around an open source project is a lot of work, and it's understandable if Facebook doesn't want to pour many resources into this particular project, even if they keep it open source.
Because they sometimes get lucky, and people use it. Apple would probably have been just fine with everyone shrugging their shoulders at clang and continuing to use gcc, but clang adoption by others has been of benefit to them anyway, say.
And worst case, there's no major downside to open sourcing language tools.
Worst case is you didn't protect your IP and people get fired because the competition makes the money.
Slack came out with a blog post a few month ago, writing that they use the Hack features on top of HHVM. That is the only one besides Facebook that I know of (there are probably more)
Edit: Source for Etsy using PHP 7 now https://speakerdeck.com/wcgallego/hitting-the-turbo-button-u...
"MediaWiki 1.31 requires PHP 7.0.0 or later. Although HHVM 3.18.5 or later is supported, it is generally advised to use PHP 7.0.0 or later for long term support. "
But MS really did earn a lot of bad will from their dev community who had been pushed to learn yet another framework which ended up dead.
I rarely even use my PC anymore. I basically then it on once a month to download the gigs of updates. It's interesting that Silverlight still listed at the top of optional updates.
There must be a few businesses and schools who bought into the hype and built their internal app on SL.
It's interesting how apparently sometimes you just need to step aside to break old conventions and demonstrate new capabilities, but eventually, you'll need the support of the community to pull it through: Plus, it's always a gamble. Python barely made it over to v3 after 10 years. I'm not sure if Perl will ever cross the gap or if Perl 6 fragmented the community for good.
Just some random thoughts though on the dynamics of open source, I'm glad for the experience of PHP at the beginning of my career, but I wouldn't touch it or any derivatives any time again having free choice. Too much Heinz™ design: Grown, not made.
It's a similar model to larger corporations allowing innovation to occur in startups and then buying them out once the model or technology is proven to a degree.
Of course, there are (former) Perl 5 programmers who still think Perl 6 is the sole reason for Perl's demise. These are fortunately very few, but alas also very vocal.
I think support for 7.0 is ending soon too.
I would love love love for all these to be in PHP.
Which is great for me :).
Performance and type checking were the only benefits over PHP5 and with those (mostly) gone, you were just left with all the downsides like all the good tooling for PHP being incompatible with Hack and, and general compiler/interpreter errors that were never getting fixes.
Q: Do you imagine a future where Hack will merge back into PHP (like PHP 7), in the same style that Beryl & Compiz then rejoined? Or does the team intend for the two to always be adjacent-yet-separate?
A: HHVM developer & PHP runtime developer here. I've got hands in both runtimes and all even I can say is: Maybe. I think the most likely outcome is that PHP will adopt some of HHVM's additional features, but remain a separate project. IMO that's a great outcome, since we'll both likely drive the other to be better.
EDIT: Source, https://news.ycombinator.com/item?id=7436557
Facebook was initially implemented using PHP, and you can read this process as continued iteration based on this very early decision. From the outside, Facebook seems to have always taken what they had, taken the problems they currently had, and made the most incremental change they could to fix whatever problem they had. From PHP to HHVM to Hack to dropping PHP support, they continued iterating on what code base and development chain they currently had.
If you take a step back though, Facebook is gradually moving to a different programming environment, from a dynamic language with very loose semantics to a statically typed system with (from code I've seen in e.g. phabricator) a very different programming style than run of the mill PHP. While iterating incrementally, they still ended up forking PHP and moving to a different language.
The approach is quite different from e.g. Twitter though, who started off using Ruby on Rails, and then moved everything to an entirely different tool chain (Scala) when they found Rails couldn't hold up with their problem set.
This difference in approaches isn't quite the same as the good old "rewrite vs refactor" dichotomy. Twitter's change was certainly incremental too, moving individual services to Scala bit by bit, setting them live incrementally instead of a "big bang" rewrite where everything moves to Scala one day.
I think the main difference is planning horizon: do you opportunistically fix whatever is broken right now, or do you make a long term plan on what you want your future platform to be, and then set out to get there?
Opportunistic fixing has the advantage that you can be pretty certain you're fixing the right problem, and don't invest in YAGNI features. On the other hand, you risk ending up in local optima. Pouring a lot of effort into PHP makes sense if you plan to continue using it - but if you end up forking the language anyway, you loose a lot of the advantages of a shared ecosystem (and arguably damage the existing ecosystem in the process through fragmentation).
You could equally well imagine Facebook picking a different future tech stack five years ago, be it Rust or Go or whatever, and add the features they miss from PHP to it. I think it's an interesting thought experiment where that'd have taken them. I have no idea if taking that path would have been better for any of {Facebook, PHP, target language X, world}.
This would only be a risk if the difference between the local optimum and the global optimum is large, but there is no evidence to suggest that is the case (and a lack of evidence for a big effect is usually evidence against it). To be more precise, no one has been able to find a drastic productivity boost among apparently reasonable alternatives, so either there's a plateau or no one has found the global optimum. Either way, as things stand, there is no such risk.
A risk that does exist is failing to create a viable development environment or simply not having the resources to even attempt it. As others noted, this is a big risk (or an almost guaranteed failure) for small organizations, but hardly one for a very big one.
The large difference between a local maximum and a goal is clear. The question is whether the cost to get there is acceptable.
Agreed, it's been elusive for the software engineering community to objectively assess and quantify productivity effects of software tool chains, in particular in comparable stacks.
Comparison of programming languages or stacks is not what I was (trying to) talk about though. I have no idea whether hack compares well to $RANDOM other toolchain. I am curious as to whether a continued incremental investment in PHP made sense, compared to choosing a whole stack and propping that up to meet your requirements. Even assuming your final PHP-based stack is identical to whatever else you'd have chosen, the paths do have differences in effort.
The local optimum in that context is that it's locally optimal to just add that one feature to your existing solution vs investing in a different solution that in the long term will cost you less to build and maintain.
I don't have an answer to that question though, as I'm not familiar with the effort required or comparisons made. I think it's a genuinely hard call to make. Even post hoc and with all the knowledge it'd be hard to judge, as you need to discount effort by the relative risk factors.
I wonder what would be the optimal lifecycle for long projects. Obviously, "start with dynamic language X until you reach 10^n lines of code, then fork X and add types to it" doesn't work for smaller companies :-(
Funnily enough, strongly statically typed languages are not bad at all for the early prototyping stage. In fact, I would argue that they are much better, but you have to switch your approach from slapping some functions out, to instead slapping out some ADTs, that form the basis of your app.
A lot of good advice for Haskell is given in this thread https://www.reddit.com/r/haskell/comments/7sr8k7/fast_protot....
One important thing to note though, is that I honestly don’t think this will work well, unless the language has at least type inference and support for ADTs, newtypes (or, tagged types) and pattern matching at the minimum. Less than that, and you end up fighting the type system, instead of letting it be your help and guide.
Maybe because they weren't startups anymore?
Honestly I don't understand the deal with type errors in simple web apps : every input is a string which is parsed into the correct type. After this, with good naming and conventions operations should be obvious, e.g. why would you try to do a mathematical operation between a customer's name and it's account balance?
To me it looks like these days the hype is copying whatever big names are doing regarding maintainability without having nearly the same constraints (static typing, huge frameworks, ...).
that's a straw man to js typing, and never a problem in practice. What's more often happening, is that you change the structure of some object in your store somewhere, that's passed around a lot. And you forget to update the usage one of those places and stuff break runtime.
This is the big reason I tend to even prototype a system with a statically typed language, if it's going to take more than about a week. Dynamically typed languages have the characteristic where they seize up after a week or so of development, it becomes impossible to fit the full graph of who is calling who in your head anymore, and from that point on, you tend very strongly to do defensive code changes rather than good ones, e.g. "this function used to take a string, but now it takes a dict with three parameters, but I'll still keep the code for if it gets passed a string because maybe something is still doing that". Then when the time finally comes to do a big refactor, you're often darned near rewriting from scratch.
I've lost track of the number of times I've refactored something successfully in a static code base of several months age by just continually running the compiler until it's done complaining, and how often I start a refactoring that seems to be going really well until the compiler points me at some bit of code and I realize that what I'm doing right now is actually fundamentally flawed in some way I'd forgotten about. In a dynamic language you tend to just power through those and put in sub-optimal solutions.
Plus, at least in my experience, if you do this consistently, it often is practical, feasible, and correct to just "ship the prototype", because whereas with dynamic code I would have a messy prototype with half the methods taking an unclear combination of values, with the static type-based process I've written something quite production-ready, with cleanly-defined interfaces.
That goes irrespective of if those type errors are caught at compile time or runtime - if those errors aren't caught by your test suite, odds are you have a problem that static typing will not fix but writing more tests will. In either case my response to type errors these days is to consider it a bug in the test coverage.
(I'm sure some will argue that typing in languages like Haskell avoids this more than others, and that might be true, but languages like Haskell are too hard to work with for most people to ever get mainstream traction; I'd love to see more experimentation in making more advanced type systems more accessible, though)
It can't be repeated enough: Types are universal quantifiers, tests are existential quantifiers, you'll realistically never get even close to the guarantees of a type system with tests alone.
If your unit tests are on a level with your static type system, you have basically rebuilt the static type system in your unit tests.
(And pitting unit tests against a static type system is a false dichotomy, it's good to have both.)
Let's say foo() internally calls bar(). If I pass a given valid input to foo() it passes the wrong type to bar(). If I pass another valid input to foo() it passes the wrong value but of the right type to bar().
If you ensure full test coverage of foo() you will catch both. Type checking in your compiler will only cover the first case, so you still need the same test coverage anyway to have confidence in the code.
A good type system is much more thourough and let's your tests focus on behavior.
And you don't need full coverage. Aiming for full coverage is a folly - you aim to cover the API surfaces you're actually using. If you still get lots of runtime errors something is very wrong with how you test your code.
> A good type system is much more thourough and let's your tests focus on behavior.
The problem is no languages I'd be willing to use have a good type system that actually covers much.
This is basically down to opinion, and I can't argue with it. I've collaborated on Ruby projects for about 10 years, I love the language, but my experience says a large code base, with test coverage, regularly breaks on things that most type systems wouldn't allow.
Dependencies often cause subtle breaks like this, even in big, common ones.
On top of that, this requires paranoia to avoid breaking callers. With a good type system, you can largely discard that paranoia.
Types like `int`, `float` and `string` are rather impoverished. Much more common mistakes are:
- One the numerical side, trying to perform arithmetic with different units of measure ( https://en.wikipedia.org/wiki/Mars_Climate_Orbiter ) or with different representation sizes ( https://en.wikipedia.org/wiki/Cluster_(spacecraft)#Launch_fa... ). These sorts of errors are trivial for machines to identify, if we let them (e.g. https://docs.microsoft.com/en-us/dotnet/fsharp/language-refe... )
- On the textual side, type errors are widespread and cause a large proportion of security vulnerabilities ( https://www.owasp.org/index.php/Top_10_2007-Injection_Flaws ). Again, they're trivial for machines to identify, if we let them (e.g. http://blog.moertel.com/posts/2006-10-18-a-type-based-soluti... )
Why on earth rely on people for this when you have a machine available for you, that can automate all this? A good type system is invaluable for both on-boarding of new people, refactoring code, and maintaining a codebase.
Why would you not want to make sure you could never call the wrong REST endpoint[0] for example? Etc, etc...
I think this is spot on. That was my journey as well. I started using Python in around 2000 because I didn't had to write type of every local variable and declare every little structure. (For example, you want to return multiple values in a tuple? Better declare it as structure or object.) For a long time, Python was my favorite language.
Eventually, I came to Haskell and it became a new favorite. I think the "hype" of the dynamic languages subsided largely because of the two important developments you mentioned (which are now in some form a standard in any new language that is being developed).
as simple and easy as python feels without static typing, a handful of files of python is my tolerance level before i start to hate it
In stark contrast, I’ve been playing around with Unity/C#/Visual Studio and my productivity with this tool stack is through the roof. There, it is rare that I create code which doesn’t fill its intended purpose the first time around. It’s all so easy, and InteliSense makes the quite verbose typing not felt. The tooling and safety is magnificent.
High line count projects almost always gravitate towards languages with such safeguards built in because otherwise the accumulation of subtle errors leads to too many runtime issues, and typing takes care of whole classes of bugs.
IMO any mechanism that shifts that time of bug catching to development rather than operations should be preferred, ditto for any mechanism that forces a program to end when an undefined situation is detected, the closer to the root cause the better.
I disagree. I work(ed) at two of the more famous Python shops: Yelp and Reddit. These companies have many millions lines of Python code combined. Also FB was mostly a PHP shop until they started Hack in 2014, 2 years after they IPO'ed.
Testing and monitoring can be used to combat type errors. Runtime type errors still happen occasionally, but honestly these are some of the easiest bugs to squash.
I think you might be conflating static typing with strong typing when you infer that Python has "lack of typing." Python has a dynamic, but strong type system.
I've coded professionally in many other languages (C, Java, Rust). I think C and Java have the worst ROI when it comes to type systems. In my opinion if you're going to use a type system on a new project today, then use something that provides stronger guarantees like Rust or TypeScript (and lowers the burden by inferring or deducting many types).
Python isn't perfect, but it's still the first tool I reach for anything web, ops or data science related.
Yelp and Reddit also have above average resources to throw at the problems they try to solve.
Python is the first tool of choice for quick solutions to immediate problems for me as well, but that does not make me blind to its obvious shortcomings.
Look, I've built I don't know how many websites in PHP, and my company still earns a lot of money with a tool I threw together in a day or two in it so I have nothing but admiration for what it can do. But you'll be the last person to hear me argue that there aren't better tools for the majority of the jobs at hand. We are all looking forward to the day that it can be retired, but in the meantime we will definitely keep using it and we will continue to pray to the PHP gods. It is a very productive little language that has a ton of warts and some serious issues, but it does have a niche and it is useful.
Tests and types are not direct substitutes. My view these days is that types become more valuable as a codebase grows. I have worked on Ruby on Rails codebases where, quite frankly, I found myself wishing it out loud was Java on Spring Boot. (Many of my peers in Labs are flatly enthusiastic about Kotlin on Spring Boot, FWIW)
In the same genus as the "just use tests" argument is "business logic only belongs in the app, not the database". Yeah, well, it turns out that no amount of testing is a substitute for constraints and transactions.
Hard to move code around, comment out code, prototyping, create samples of data structures etc.
What is important on a large project is enforcing contracts, if it is on function calls, HTTP calls, database calls etc.
With function calls you have type hinting in many dynamic languages, with that you can catch most type errors & avoid writing some tests.
How the types work within the function body is quite irrelevant.
And statically typed languages have recognized this by adding var, auto & what not.
With some IDE skill, this is easy in Java, but then developers get used to this way of developing caused in no small part because of the language and think that features of the language (like static types) enable and entail the IDE features (auto-refactoring, intellisense, code generation), rather than the IDE features being developed partly in response to the limitations of the language.
Dynamic languages often have a tooling problem, at least from the perspective of Java developers, but often you don't even need those heavy IDE features to get equivalent or better work done and so tooling suffers or isn't evangelized much. A coworker complained he can't just find callers of a JS function (unless within the same JS file) with eclipse; I pointed out that vim trivially does this after generating ctags and demoed it... Still, in lots of code bases that aren't in Java, I find myself needing to know "who calls this" not as often. Besides, old school find | xargs grep or ag work to find that info usually too. Even better, if it's a Web Service name, a string-based tool will find the usages on both the client in JS and on the server in not-JS.
Meanwhile there have been dynamic languages like Common Lisp that have IDE features like debugging built-in to the standard language itself, there are strong types that implementations can and do use to produce optimized machine code (not just correctness -- and you can verify an optimization with 'DISASSEMBLE, another standard function), modern implementations like SBCL have at-compile-time warnings for type issues or typos or whatever, and ancient tooling (slime) has things to tell you who-called-what, etc.
I agree, though IMO this is another upper-bound. You can only test and monitor so much before resources and performance start becoming a bigger issue.
I think companies can definitely go without types if they have solid documentation and a good review system to both prevent bugs and help with onboarding.
Dynamic typing solves things you have in C, not so much in C#.
Now, there's a continuum here.
When designing the main data store for a project, you want to iterate on that and get it just right.
Or if you're working on a library to be used by lots of people, it's definitely nice to be able to specify things that lets the compiler help people get their code right.
On the other hand, in almost all the applications I've worked on, there's also a much larger fraction of absolutely necessary and often complex code where each little module is working on some details. There the data structure doesn't really matter so what JSON provides (untyped arrays + simple objects/dictionaries) results in much less cognitive overhead than a fully specified and typed thing. A few black-box tests both documents and checks functionality, and also ensures that the thing keeps working after a refactor.
Of course, YMMV.
For a long while you were comparing languages line Python to something like Java, and it was pretty much a no brainer - the argument was right. But nowadays if you compare something like Javascript to Typescript, it's not near so clear. Type inference is really biting into the size advantage line dynamic typing had over static typing.
The other thing is the claim 1 line of statically typed code of takes as long to write as 1 line of dynamically typed code. It's true as stated, but change it to "correct line of code" and it's not true. You don't have to write tests for type declarations, and statically typed code has less bugs after it's accepted by the compiler / interpreter, so while the writing takes the same amount of time the testing and fixing takes less for statically typed languages.
The final advantage of dynamically typed languages is statically typed languages just need more head space - just ask someone who has used Rust. Granted Rust with it's explosion of types caused by lifetimes is a bit of an extreme case, but it's still true for most languages. But it's not so true for the Typescript vs Javascript comparison, and I suspect really careful standard library design might make this mostly go away too.
That's an opinion, not a fact.
> IMO any mechanism that shifts that time of bug catching to development rather than operations should be preferred
That's probably true of an existing product, but that's not the only concern in product development.
The funny thing is, with microservices it shouldn't really matter what language each service is written in as long as the services can talk to each other, but most companies end up using the same language for everything because it's easier to hire people who know the same language and can work on multiple projects.
- our service infrastructure is really language-agnostic.
- our design discussions are on an abstraction level above the language level. (of course there are language-specific implementation strategy discussions, too.)
- while it is a bit harder to find suitable developers, I think we attract a very valuable subset: people who are not tied to their favourite language, and don't shy away from learning new things.
I met a few PHP devs who were hating on JS, because PHP was mature now and had static typing, etc.
I'm really glad that Python is making good progress on this front.
The trend seems in any case for people to have tools in their pipeline that transpile and verify code. E.g. most javascript code gets shipped in minified form. If you are doing that, you might as well run a transpiler, some sanity checks like linters, code analyzers and type checkers. Many people do exactly that. Those type of tools benefit a lot from having more typing information available. Hence the popularity of things like typescript and recent additions to ecmascript of things like classes.
Once you have that, the step to a full fledged statically typed languages is the logical next step. It seems the hack people have reached that point.
Recent xkcd visualization: https://xkcd.com/2044/
From the sysadmin perspective, it's a dream app to deploy: just unpack (or git clone) the latest release in a directory, point Apache (or Nginx) at it, and continue in the guided setup process (which involves creating a database, typically MySQL).
Updates are also painless: there's a php maintenance script which updates the schema. I've kept MW instances for ~10 years without running into any problems.
Things get a little more interesting if your add a ton of extensions, or badly maintained ones.
I wish I could say the same of Django and Rails apps! <trollface>
- Handle numeric boundary cases in a more intuitive way.
- Is Typed.
- Replace reference parameters in favor of a new keyword, "inout".
- Change package management and testing framework to be less annoying and more streamlined. This will be yarn (from npm, as in the one written in Javascript), and their own custom flavor of testing framework, hh-test, to replace PHPUnit.
I wonder how many existing open-source PHP projects will remain compatible with HHVM? The post seems to indicate compatibility will not be a priority and that it's a fully breaking change. If this is true, it seems the "empty cocktail room" effect will be a major challenge and problem.
Jane:
"Hey, you can do this project in PHP or Hack."
Alice:
"Okay, I'll go with PHP because there's
already a shitton of good libraries that might
be useful to me or that I already know."
I.e. Why would you use a language with few open source libraries over a very similar language with exponentially more?When I want types, I can already use Go, Java, or even Typescript, just to name a few terrific options. These days it seems like a no-brainer to me.
The effort seems like a lot of trouble to go to just to shave off some annoyances / "rogue hairs".
Curious if there's an angle I'm missing.
One argument for making it an open-source language / project and trying to eventually grow it could be so FB can more easily hire folks who are already know the Hack language.
Marke:
"I'll do it in Hack because my only dream is
to work at Facebook!"
May not be that many Marke's out there.As far as I know once PHP 7 came out HHVM fell much further behind (as far as the PHP language goes, no idea how Hack is doing).
Most of the library we used to start our projects (symfony, mongodb to name the biggest) dropped the HHVM compatibility in the middle of development, I can tell you this was a good lesson for me: never take a technology where big vendors drop compatibility.
Having to debug a production error with an HHVM library (which support was dropped), find a fix and then seing it was fixed in the official PHP library 6 months ago hurt a lot...
Another point not in favor of HHVM, it's maintained by them, the roadmap is only known to them and the number of HHVM alternatives to big libraries is near 0.
We are gradually moving away from HHVM (and PHP in general) in favor of NodeJS and TypeScript.
Fewer unvetted libraries from a security and code quality angle.
Not saying it's good from a general engineering angle, but in an environment like Facebook which can afford to over-engineer, the third party dependency risk mitigation is a good side effect.
But my argument here is a pretty polarizing one as it implies security-through-obscurity. I promise I'm not; I'm just pragmatic about how many abandoned or poorly maintained open source libraries end up being relied-upon regardless of how that challenge is solved-for in CI/CD.
You raise a valid concern, and also this issue cuts both ways.
The FB libs have a good chance of being well-maintained. This will be true for PHP and Hack, alike.
The rate of library neglect will be approximately equal between the two languages.
The real question is: What does the data say about project / library neglect? I'd guess neglect rates may correspond inversely with language popularity.
Languages with fewer people writing code in them will have more opportunity for abandonment and neglect.
Who wrote and is relying on the library seems like a better candidate for predictor of proper future maintenance compared to language flavor.
This would be true in the public space.
I don't know if it holds when the language is internal to the company and people are incentivized effectively to keep them up to date.
Bob:
"I'll do it in Hack because I long
Time ago swore off PHP, and Hack
sounds like an interesting language."I still don't see myself using it, but it seems like a reasonable path forward for someone who wants to modernize a large PHP codebase and would like features like type safety.
PHP is open source. Instead of building a way to compile PHP and then a VM, and making all the adjustments necessary for Hack, why didn't FB just spend that energy submitting a patch to make PHP faster?
Now I also don't know if I buy that MAX_INT + 1 and pass-by-reference is a pressing enough use case to break compatibility. I'd be open to hearing why, but I'd be starting from a position of skepticism.
In an ideal world of perfect cooperation, perhaps all these projects would have been enhancements to PHP, but a chain of independent rational decisions produced very different results.
Several reasons. First, it's not that easy. It took years of work by some very smart people to get the jump from PHP 5 to PHP 7, and Facebook needed the performance much earlier that this way could deliver (and it wasn't at all certain that it would deliver at all). Second, Facebook needed their own language anyway to be able to add stuff they - with their particular use case, which is dissimilar to the use case of the vast majority of PHP users - need and for the model they use to run servers and operations. So for Facebook having something that both delivers performance that they need and is under their total control and can be made to do exactly what they need it to do makes a lot of sense.
> Now I also don't know if I buy that MAX_INT + 1 and pass-by-reference is a pressing enough use case to break compatibility.
It's not about that, that part is small change. The point is they don't want to be restrained by what PHP does, but want to have their own way with HHVM. Which is very understandable, they have their needs and they found a way to support them. Of course, for the open source community might be better if Facebook continued to support PHP - but if for Facebook it makes more sense to do their own thing without worrying about being compatible with PHP, then that's what they should do.
by making hhvm, it allowed them to move at break-neck speeds with absolutely no reason to ask for permission.
The social aspect of it probably turned them off at a corporate level, if that makes sense. Where as throwing more hackers at the problem was totally in their wheel house. IMO.
The maintainers wouldn't have to accept it, and there are plenty of devs in the community that would have issues with Facebook code making it's way in to the core of a language. If the patch wasn't accepted then Facebook would have to have forked PHP anyway. Rather than bother with the politics and PR downside of their code being rejected, they went straight to creating a fork. It may have been the less optimal technical solution, but like so many technical decisions it was really a business decision in disguise.
HHVM also adds a lot of syntax to make Hack. And moreover I don't doubt Facebook wanted the option to remove backwards compatibility in the future. Issues like MAX_INT and pass-by-reference don't seem pressing enough if you're using the language, but if you're building a compiler or VM small language quirks will be the one exception that break whole potential optimizations and/or ways of architecting things.
Facebook is not concerned with backwards compatibility because they can just change their source code, but PHP is, in order to remain relevant to the community. I honestly think trying to work on the same VM would've caused more issues in the long-run.
PHP. Can freely being in any improvements that fit their model, but the goals of the two projects are no longer compatible.
This is an example of a change that will be made, not a rationale for the decision.
PHP 7 along with laravel can get you some insane development speed. And I argue Hack, and PHP7 is actually want made PHP's downfall stabilise. The community saw their ecosystem has a way going forward and more improvements to come. Rewriting your app in different languages and frameworks is hard, no sane person wants to do it.
> As we expect the language to evolve rapidly, we strongly recommend using the regular releases instead of the LTS releases for large projects; while this does mean you need to upgrade more often, both us and our users have found that it is generally easier to catch up on 2 months worth of changes 3 times as often than 6 months of changes in one go. We will also be re-evaluating the length of our release cycle; one possibility is that we will move to releases every 4 weeks, with these releases being supported for 6-8 weeks.
That cycle will work for FB where they are constantly iterating and also have early insight as to where the language is going before they get there but for anyone on the outside or for slower moving projects, that cadence seems fairly punishing.
Is that a big change from how they release now?
If you're running on 200,000 servers, a 5% increase is 10,000 servers. That means opening a new building in your data-center, making sure your recruiting team has resources to hire enough staff for it, then hiring that staff, negotiating contracts with the power company, the component suppliers, building permits, hopefully you have enough network capacity otherwise you'll have to expand that too, etc.
It's many months of work and a lot more expensive than hiring a handful of engineers to tackle performance and maybe build some libraries in-house.
- More developer familiarity with type systems that aren't Java and C++. Type inference.
- Better languages in general, which give more flexibility and power without writing a bunch of hard-to-type code.
- Moore's law is dead, so the poor performance of your dynamically typed language actually hurts. Not to mention how atrocious many dynamically typed languages are at threading in a multicore world.
- Projects are much more complicated, so it's even more important that things glue together well.
With type hinting on function parameters like in PHP you can get the best of two worlds, flexibility & enforcing contracts.
Nope. Dynamic types have nothing to do with scripting vs programming. What a nonsense!
Sorry I had to:).
> It's technically scripting, not programming, but can you imagine if Bash files were type hinted?
I was clarifying that writing Bash files was scripting and not programming.
I understand it's historically been called 'scripting' instead, but 'technically' it's as much of a programming language as Python is, don't you think?
https://stackoverflow.com/questions/17253545/scripting-langu...
Honestly when it's all said and done, static typing is very low on my list of worries. Type hinting and contracts and all that stuff is nice, but the main problems in most real-world, large-scale projects are:
* mutability
* object-oriented business logic (rather than functional/declarative)
* friction
* build systems
* async
* drowning in inconsistencies
Some languages like Ruby have conceptual errors - for example its try/catch mechanism (rescue) defaults to using StandardError instead of the base Exception class. Which means that even though it implemented one-liners like:
load 'my_file.txt' rescue puts 'file not found!'
In practice these are rarely used because they may throw LoadError (which is lower in the class hierarchy than StandardError so is not caught by rescue, and we can't say rescue Exception puts 'file not found!') so the script crashes. Each time I look deeper into Ruby, I find more and more of these idiosyncrasies that don't build from first principles, so I can't tell what problems they're trying to solve (some of its errata seems to have been inherited from Perl). So I would advise against using Ruby for new development until it has a sister language like Hack that attempts to solve these longstanding inconsistencies and move Ruby forward.In contrast, PHP has implementation errors where some methods in its standard libraries are camel case and some are snake case, or they decided to use backslash when declaring namespaces. Since these decisions have no bearing on business logic, I can largely overlook them. When people say that PHP is a fractal of bad design, I tend to agree, but do NOT agree that it's a fractal of bad engineering. In fact PHP is by far the most productive language I've ever used (at least an order of magnitude more than the next closes contender, say Javascript in Node). The only language that comes close is MATLAB, which comes from a completely different paradigm of matrix operations so simply provides more leverage per line of code.
Static typing mainly becomes important when you're working with other developers, or have large/legacy codebases. If we're strictly talking about our ability to write business logic as effortlessly as possible, then the conceptual problems I've illustrated above (which pop up repeatedly across frameworks/languages) have much higher priority IMHO.
Also on a personal note, I find that dynamic types tend towards rapid application development (RAD) because I often work at a high/abstract level. I find that the friction of assigning types steals brainpower from the task at hand - generally composing logical units that pass around hierarchical data like JSON or tabular data like CSV. If we stick to RAD, then building out strictly-typed/over-architected class hierarchies is generally a waste of time and expensive to maintain.
I'm all for the ability to type variables and functions, as long as I'm still allowed to be exactly as precise as I feel like.
Many would call that static typing, since there are types in the code that the compiler consumes. But my own attempts [0] at building such languages tell me that the result is still more dynamic than most.
Not sure why fb even made it public. First baiting everyone by switching and now having full control.
Not sure who would risk that dependency.
I remember that around the year 2002 it was almost the only choice (besides Perl) on shared hosting, but on this days its just a nasty language and with so many beautiful languages like Python GoLang and Ruby why would anyone use PHP for a new development?
By breaking compatibility with PHP, Hack is going to be able to adapt more quickly and create a stronger language. Hopefully, Facebook will have the wherewithal to promote Hack to PHP (and other) developers, and grow the ecosystem as it can.
PHP is one of the most widely used languages on the web. Their backward compatibility is absolutely part of that reason, too. Refusal to break compatibility may be holding it back in some technical areas, but it's certainly not hurting the language in popularity and use.
Breaking their code on a PHP upgrade is a great way to strand them on old unsupported versions of PHP. Not everyone has resources to change things that used to work because of some "array function" change that doesn't really make any difference.
(please don't abbreviate when it's unclear. You saving some typing means lots of people have to pause to parse your TLAs...)
But in either case it means every single reader has to pause and make extra mental effort to save you about one second extra of typing. :)
Weren't they THE big player that kept PHP alive in the last years?
Facebook was always an anomaly in supporting/using PHP at that scale. PHP was never a major player in very large companies...until facebook. I think this is a return to the mean, rather than a seismic shift in a new direction.
That's not to say PHP isn't fading...it is. But, I don't think this is a huge hit to PHP.
But, sure, if you go to a PHP conference or web dev conference you could meet PHP devs working in almost any industry. It's interesting how insular some dev communities are that one could get the impression that PHP is just...like...gone. As much as we may turn our nose up at it as a language, as a platform it's been a huge success, especially for small developers and web designers that do a little development.
Last time I used it was 8 years ago and I had the impression it would have been gone by now if it wasn't for Facebook pouring money in it.
Likewise, millions of people still work in Java, C, C++, Ruby, and many others, despite there being newer languages with more momentum behind them. PHP will be around for years, even if there were never a new PHP project started from this day forward (but there will be new PHP projects started after today). So, sure, it's dying, but it's not dead yet and likely won't be for decades.
Facebook was/is irrelevant to PHP adoption. Their only effect was to increase the speed of PHP.
PHP is widely used because it's really great language for web development. It's better than the other choices because of ease and rapidity of development, and because it was designed for the web, not as a regular language with web things bolted on (Python and JAVA are examples of that).
It is not fading at all. Some developers think it's too easy of a language, so they discount it as for beginners only. That's about it. It's a kind of snobbery, which I'm glad to see seems to be vanishing with the release of PHP7.
Good lord, who thinks that? PHP is a terrifyingly complex and difficult language. I'm not saying it's bad, it's been very successful for its intended purpose. But, it is definitely not an easy language.
It's got thousands of standard functions in the global name space (admittedly, it has been recognized that this was a mistake, but it's all still in there), quite a lot of syntax, and some weird syntax that's unlike any other language, a high level of verbosity in many places (due, in part, to that whole thousands of functions in the global namespace thing, but also due to an apparent admiration for Java during a critical period in PHP development), a variety of quirks and inconsistencies, etc. PHP is a very big, very complex, language, that takes years to master. I can't see how it can be called "easy". Many other languages are much better teaching/learning languages. PHP is popular and widely discussed, which helps with learning it. PHP is also very easy to deploy, because it is the "standard" web language...you just upload your files to the right directory on most hosting platforms and you're done. That's great, but doesn't really make the language easy.
There is exactly 0 difference between prefixing a function, and putting it in a different namespace. All those functions have prefixes and are very easy to locate and understand.
It's literally the difference between \foo\bar and foo_bar. It makes no difference for understanding the function.
The only advantage of a formal namespace is you can "own" it, and other code can't put things in there. Not having it does not making the core language harder to understand.
> quite a lot of syntax
It's basically the syntax of C. The most complicated parts are lambda functions and references. And that's nothing. Where are you getting "quite a lot of syntax" from?
Classes have a bit of syntax, but it's hardly "quite a lot", and the nice this is you don't have to learn any of it to get started.
> a high level of verbosity in many places
Where? PHP is not especially verbose. Examples?
> a variety of quirks and inconsistencies, etc.
There's basically just two: Comparing an empty string and the mistake with precedence on the ternary operator. Everything else confusing is the difference between arrays and Key/Value structures, and it's not really not that hard to figure out.
> PHP is a very big, very complex, language, that takes years to master.
It is not very big. The core language can be learned in a week. It's not very complex either - it's among the easiest languages out there.
> Many other languages are much better teaching/learning languages.
Not because they are easier - because they are harder!! They are more structured and you have to understand more - that makes them good to teach concepts. PHP was never intended as a teaching language.
That doesn't make sense.
I think we'll just have to agree to disagree. I believe there are many languages, including some often used for web development, that are easier (and better teaching/learning languages) than PHP in several regards. Python is the most obvious but Ruby also fits the bill.
Google App Engine: has PHP runtimes
Heroku: supports PHP
Azure App Service: supports PHP. Experimental support in Azure Functions available.
AWS: I think the only language-specific thing they have is Lambda, which doesn't directly support PHP, but it can be run on it with workarounds if you really want to.
Everything exposing VMs or containers of course can run it. API client libraries/SDKs are widely available. FaaS support is limited.
It is not so. Facebook doesn't really interact with the PHP community, except for when they published HHVM, and even that was limited.
PHP is still working on a JIT implementation but I honestly don't think it's that important for now.
Because no other language is as easy to deploy. With PHP you edit the PHP file, and that's it. It's deployed. No clearing cache, no compiling, packaging, nothing.
It's one of the major factors in how good of a language it is.
If it's needs this optimization as a result of that, it's completely worth it, and other languages should copy that.
Nah, it's because PHP isn't an actively running process.
The overhead of starting a process isn't what it used to be in shared web infra world before. It's cheap to spin up a small VM now. And there are other similar constructs, e.g. FaaS