Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I meant that Hack is statically-typed, not PHP. PHP is obviously dynamically-typed.


Hmm. Looks like Hack still includes files based on strings: https://github.com/hhvm/hack-example-site/blob/master/index....

How can a language be statically typed when the instructions telling it what code to use are dynamic?


include "foobar.php", IIRC, is executed at compile-time, and I assume must be in Hack's type checker too.

Also, I don't see how pausing execution and re-invoking the compiler at run-time to load the rest of the code base (which you can do in PHP with a conditional include, don't know about Hack) can't be done with static typing.


Let's say we have the following:

file1.hh:

    <?hh
    $giveMeAnArray = (time() > 1)? function(array $x) {}
                                 : function(stdClass $x) {};
    $anArray = [];
file2.hh:

    <?hh
    $giveMeAnArray($anArray);
file3.hh:

    <?hh
    list($f1, $f2) = (time() > 1)? ['file1.hh', 'file2.hh']
                                 : ['/dev/random', '/dev/random'];
    include $f1;

    if (time() > 1) $anArray = new stdClass;

    include $f2;
As far as I understand it, the following will happen when we run file3.hh:

- HHVM will compile file3.hh. This phase doesn't know what $f1 or $f2 will be, or whether $anArray will become a new stdClass, since they depend on the output of time().

- HHVM finishes compiling file3.hh

- HHVM will execute file3.hh, setting $f1 to 'file1.hh' and $f2 to 'file2.hh'.

- HHVM will compile file1.hh. This phase doesn't know what $giveMeAnArray will be, since it depends on the output of time().

- HHVM will finish compiling file1.hh

- HHVM will run file1.hh, defining $giveMeAnArray = function(array $x) {} and $anArray = []

- HHVM will resume running file3.hh and set $anArray = new stdClass

- HHVM will compile file2.hh, which contains a type error. How does it know?

The most likely answer is that type information is stored in values and checked during usage. That is not static typing, it's 'dynamic typing' (tag-checking).

There is an alternative possibility: the state of the compiler could be preserved between files, so type information from file3.hh and file1.hh is available when compiling file2.hh. However, this information wouldn't include knowledge that "$my_account = new stdClass" has been executed, since that's dynamic run-time information which is only knowable after file3.hh and file1.hh have finished compiling.

There is no way (to my knowledge) that interleaving static type-checking with dynamic execution can produce a type-error when file2.hh is compiled. The type-checking must have access to the execution state of the program, ie. it must be dynamic.

If type-checking happens during/alongside/interleaved-with execution, the compilation phase (which must be done prior to execution) cannot know the types of the code it's compiling. Without this knowledge, the first unit of code it produces is forced to use dynamic types (AKA a unitype). Once that unit is type-checked/executed, the runtime information gained may be used to partially-inform subsequent compilation, somewhat like a JIT, but there would always need to be dynamic fallbacks. Of course, a dynamic fallback defeats the main point of using static types: being informed when there's an error. There may be incidental benefits from doing this though, like faster code.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: