Link-Hack
Link-Hack copied to clipboard
Not valid strict Hack
Hey! I'm an engineer working on Hack at Facebook. Super cool to see folks using it externally!
It looks like you've forgotten to run the typechecker on your code. HHVM doesn't actually enforce the full type system -- it only enforces the bits and pieces that it knows about, and only at runtime. We have a separate static analysis tool that does this enforcement, which must be run separately. It was designed to give instant feedback over all of your codebase -- not just what happens at runtime! So it can catch interesting edge cases that don't come up often in your code.
Our docs has instructions on getting the typechecker up and running. You should take a look! The typechecker is super useful. Furthermore, the behavior of code that doesn't pass the typechecker on HHVM is undefined -- it may happen to work right now, but it may randomly break later, we make no promises about it.
I went ahead and ran the typechecker on your project, and got many errors. Some of them were due to type errors or missing annotations, and some due to incorrect setup with regards to the hhi
files described in the documentation.
Sorry for the confusion on this. Lots of folks haven't realized they need to do this -- I'm working on a way to make this whole thing a lot easier. (I've already nearly removed the need for hhi
files, for example.)
First off awesome, thank you for checking out the project. Was a fun experiment into Hack.
I'm running the nightly build of HHVM from ppa package for Ubuntu 14.04. I just ran the hh_client and have a few questions. I have the hhi files in /usr/share/hhvm/hack/hhi from the package install.
Looking at the source repo for HHVM I'm going to assume the .hhi files are essentially placeholder hack files for standard library functions and hence the unbound name warnings on things eg 'count', 'method_exists', 'preg_replace', 'False'?
Then again I'm getting the same warning for defined generics like Unbound name, Typing: Route
as well.
Also trying to find reference to the declaration of Don't us isset!
but cannot find it in the documentation or Unsupported PHP Features in Hack.
Perhaps it is because it is incompatible with closure variables, or just dangerous because of the way it returns on empty variables?
Regardless I can replace with .contains()
, .get()
Finally on generics:
Link-Hack/src/Link.hh:28:14,16: This type has 2 arguments
type Route = Map<TFunc,?Tvars>;
Link-Hack/src/Link.hh:44:32,34: This one has 1
public static function all( Map<Route> $routes ): void
Do I need to declare a new type to avoid this?
eg:
type Route = Map<TFunc,?Tvars>;
type Routes = Map<Map<TFunc,?Tvars>>
public static function all( Routes $routes ): void
Or am I missing something about the generics and being passed as method variables?
Looking at the source repo for HHVM I'm going to assume the .hhi files are essentially placeholder hack files for standard library functions and hence the unbound name warnings on things eg 'count', 'method_exists', 'preg_replace', 'False'?
Yeah, the hhi files describe to hh_client
what the standard library looks like. count
, method_exists
, and preg_replace
all should exist in the hhi files. False
should be false
-- I thought we had a specific error for that one.
Then again I'm getting the same warning for defined generics like Unbound name, Typing: Route as well.
Some of the errors can cascade in weird ways, particularly in strict mode. That probably means that the file that defines Route
has errors, and so any strict mode files using Route
won't know what it is. We're working on making this cascading better.
Also trying to find reference to the declaration of Don't us isset! but cannot find it in the documentation or Unsupported PHP Features in Hack.
This may be a documentation bug, feel free to file it :) We're also lots more strict on this stuff in strict mode -- both isset
and the "unbound name" stuff above. You may do best to move all your code into partial mode, which will squelch all but some of the most important errors, and move on from there.
Finally on generics:
There are a couple of problems here.
- Your usage of
Map<Route>
is invalid --Map
takes two type parameters, the key and value;Map<Route>
only specifies one. - For your type alias, you haven't bound the generics
TFunc
andTVars
. (I'm surprised you didn't get an error specifically about this.) You should trytype Route<TFunc, Tvars> = Map<TFunc,?Tvars>;
-- at which pointRoute
now requires two type parameters, which you'll have to go through and specify everywhere. (Note that partial mode does allow you to completely leave off the type parameters in some cases and will just assume you know what you are doing, which may help you here with cleaning this up.)
Does that make sense? Let me know what's still unclear!
Thank you for your time and helping me get up to speed with Hack. Love it. SO fast. Keep up the hard work!
Yeah, the hhi files describe to
hh_client
what the standard library looks like.count
,method_exists
, andpreg_replace
all should exist in the hhi files.False
should befalse
-- I thought we had a specific error for that one.
Considering I have them installed, /usr/share/hhvm/hack/hhi and readable to by the run time user, should I still be seeing unbound php stdlib stuff like count, preg_match, isset, etc?
I'm curious if any IDE's currently implement the type checking? If not I may be interested in writing a Komodo IDE extension for it.
You may do best to move all your code into partial mode, which will squelch all but some of the most important errors, and move on from there.
Good advice, and I'll try it but my goal would be to meet 100% strict spec.
- Your usage of
Map<Route>
is invalid --Map
takes two type parameters, the key and value;Map<Route>
only specifies one.
**slaps forehead** Of course... Not enough coffee in this coffee.
For your type alias, you haven't bound the generics
TFunc
andTVars
. (I'm surprised you didn't get an error specifically about this.) You should trytype Route<TFunc, Tvars> = Map<TFunc,?Tvars>;
-- at which pointRoute
now requires two type parameters, which you'll have to go through and specify everywhere.
Makes sense.
For code clarity, I may make secondary generic type, called Routes
as some methods require a single Route
, and the all method requires the full Map of Routes
for iteration.
My next version will include using async
route finding inside the ::all()
method.
Finally, I would love to help the Hack community get off the ground. If you have any suggestions. I'm open ears.
~@
Hey @a904guy -- love the fact that you've built this project, saves me a tonne of hassle! I've been using Hack (and hh_client/server) extensively over the past month or so, and have internalised a lot of what Hack expects type-wise (and some edge cases!). I'd gladly take a look and see if I can't help get it passing under strict mode; this will be an excellent addition to what I'm writing at the moment (a Doctrine-styled DataMapper ORM in strict-mode Hack). Mind if I send you a pull request or two? Keep up the awesome work!
Absolutely.
Sorry to take so long to respond, been a busy week.
Considering I have them installed, /usr/share/hhvm/hack/hhi and readable to by the run time user, should I still be seeing unbound php stdlib stuff like count, preg_match, isset, etc?
Before HHVM 3.2, you need to actually copy them into your project root. As of HHVM 3.2, they will be embedded inside hh_server
and automatically picked up.
I'm curious if any IDE's currently implement the type checking? If not I may be interested in writing a Komodo IDE extension for it.
We have vim and emacs support. Other IDEs are welcome if you want to contribute something!
Finally, I would love to help the Hack community get off the ground. If you have any suggestions. I'm open ears.
Just writing Hack code is awesome! Another easy thing to do is let me know what you're having trouble with, either via opening an issue against HHVM or just by asking questions when you have trouble (in IRC or on StackOverflow). Knowing what's hurting folks the most is how I figure out what I need to fix; the aforementioned hhi
embedding in HHVM 3.2 is a direct result of basically everyone being confused about how hhi
files work and running into trouble.