Changing the subject to something more relavant.

Le 16/09/2011 15:36, Andreas Rossberg a écrit :
On 16 September 2011 15:17, David Bruant<david.bru...@labri.fr>  wrote:
Well yes, but that's part of programming. In practice, all resources
are finite. And the difference between finite and infinite space usage
is a correctness criterium.

Consider writing a server. If I cannot rely on tail call optimization
then writing its message loop as a recursive function (e.g. actors
style) would be incorrect. If I cannot rely on GC, then allocating an
object for each received message would be incorrect. If I cannot rely
on weak maps, then, say, mapping every message object to a return IP
would be incorrect.
You are making a connection between program correctness and implementation
consideration of what you use to write these programs. It doesn't sound
right.

"If I cannot rely on tail call optimization then writing its message loop as
a recursive function (e.g. actors style) would be incorrect."
=>  This is not true. If your server ever receives only one message, you
should be fine.
Obviously, I was talking about a server that is expected to get an
unbounded number of messages during its uptime.

The problem is in implementation limitation, not correctness
of your program. It turns out your programming style with nowadays
reasonable use cases (size of input, number of messages...) makes current
implementations fail. I agree that it is annoying, but it doesn't make your
program incorrect.
If we start considering implementation limitations as sources of program
incorrectness, then some ECMAScript programs will always be incorrect.
The difference is, this limitation would be hit for the _normal_  use
case of the server. If my program cannot deal with its expected use
case, then it is incorrect.
What is the definition of normal use? Size of input? When machines will be powerful enough to handle your current normal case without tail call optimization, will the definition of "normal use" change? Once again, program correctness [1] (tell me if you use "incorrect" differently and please define it if so) has nothing to do with implementation considerations of the plaform that run your program. There is no contradiction in having a correct program which fails when implemented because of implementations issues (of the platform, not the program).

I do not think the ECMAScript standard is the the place where implementation considerations should be addressed. For that matters, people have been writing JavaScript programs for years and the spec doesn't say a word on implementations.

Also, why should tail call optimization should be standardized? There is a use case, but aren't there other implementation optimizations that could be considered? Should they all been standardized? Why this one in particular? Really, once again, an appendix named "hints for implementors" or a different document or a page on the wiki would be better than a normative section. Saying that ECMAScript implementations aren't standard because they do not support one programming style sounds like a lot.


Regarding tail call optimization, as far as I'm concerned, an agreement
between implementors sounds like a more reasonable approach. There is no way
in the language to test this feature. In this video [1], David Herman
explains that a test can be written (at 40:40), but the test relies on
implementation limitations rather than the language by itself (unlike all
tests that can currently be found on test262).
That is true, but whether some property can be observed from within
the language itself, or only by its environment, is not relevant.
It is not for people who write programs, it is for implementors because it directly impacts their work. They are not implementing a language anymore (which they still were as of ES5.1), but a language and some implementation constraints. Let imagine for a minute that tomorrow, implementors find another implementation trick which allows to run without crash the use cases that motivated the proper tail calls proposal, why would it be problematic? Why does it have to be this optimization in particular?


There is no test that you can reliably write for a 'print' function.
Still you want to be able to rely on it printing what you gave it.
I (if i was an implementor) would want to test my print function. I can decide to do it from within the language or not since i have more power. You can also test a function from outside a language (which is a more relevant choice for a print function).


Or consider a sleep(secs) function. How would you test it?
Time cannot be formalized. The best we do is a human-acceptable approximation of it. For what it's worth, I recommand reading the ES5.1 spec for Date.now(). I think that test262 does a pretty good job of test coverage for it.


"If I cannot rely on GC, then allocating an object for each received message
would be incorrect."
=>  Can you refine this point? I don't understand the connection between
garbage collection and correctness of your program.
I allocate objects on a daily basis and have never /relied/ on garbage
collection.
I think you implicitly do, all the time. Just try turning off GC and
see whether your programs still work reliably.
With or without GC, there are 2 possible behaviors for a program (assuming conformant platform):
- it works reliably
- it crashes (not reliably most of the time)
GC isn't of any help regarding reliability. It is helpful to make my program running reliably longer, that's all it does. If you disagree, please provide an example proving me wrong.

What I implicitely do is not relying on the GC, it's praying that the implementation (and GC in particular) is good enough to make my program run without crashing long enough.
That's what everyone does, I think.
Does this kind of prayers has a place in the spec?

Same thing for tail calls. We write a program in some style praying that the implementation will run it without crashing. Turns out, recursive tail calls make implementations often crash. Is it a good reason enough to impose something on the spec for that?

Tell me if i'm wrong, but until today, all implementation decisions have been made based on market considerations. JS is fast because of that. New classes of program can be run now while they couldn't before (in the sense that performance did not allow these programs to be efficient). See the video at [2]. I do not think it's the role of a language standard to have a word on implementation considerations. If there is a need for tail call optimization from the programmer side (to run some programs which use to fail without), well, implementations will adapt. If there is no push with that regard, I do not see why the spec should tell implementors what to do. Also, there is a long history in JavaScript of implementations doing what they want regardless of spec. There may not be a need of another such case.

Spec driving features and market driving implementation choices sounds like a good trade-off.

David

[1] http://en.wikipedia.org/wiki/Correctness_%28computer_science%29
[2] http://blogs.intel.com/research/2011/09/pjs.php
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to