Conditional function definitions

O

Olov Johansson

I just found out that JavaScript 1.5 (I tested this with Firefox 1.0.7
and Konqueror 3.5) has support not only for standard function
definitions, function expressions (lambdas) and Function constructors
(these three I knew about), but also conditional function definitions,
as described in [
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Defining_Functions
].

An example:

function fun() {
document.write("global function fun has run.<br>");
}
function outer(hide) {
if(hide) {
function fun() {
document.write("conditional inner function fun has run.<br>");
}
}
return function() {
fun(); //activates global or inner function
fun = function() { //replaces global or inner function
document.write("inner or outer function got replaced by me.<br>");
};
};
}
fun();
outer(true)();
fun();


with output:
global function fun has run.
conditional inner function fun has run.
global function fun has run.


if we replace outer(true) with outer(false), the output is:
global function fun has run.
global function fun has run.
inner or outer function got replaced by me.


I agree with the results, this is what could be expected from the
(brief) description at MDC. But why was this included, for what
reasons? Typically (that's what I believe, at least) in a lexical
scoped language with proper closures, such as Scheme, the semantics are
such that any variable or function-lookup can be done by with lexical
addressing by traversing the scope-chain a fixed number (determined
before the program executes) of times. Conditional function definitions
breaks this as I tried to show in the example, you don't know
beforehand in what place in the scope-chain fun is, so that when fun is
assigned in the function expression it might be either in the global or
local scope. Is this considered a feature?

This also seem to contradict JavaScript's "per-function" variable
scoping instead of "per-block" a bit, although I understand that there
are different rules for variables and functions. Inner functions were
described to be bound just as the outer function has been entered,
making "function o() { i(); function i() { ... } }" work, but with
conditional function definitions this must be delayed until the block
has been entered as well.

I can't think of any practial use for it considering that function
expressions are available.

With function expressions outer could be rewritten as:
function outer(hide) {
var fun2 = fun;
if(hide) {
fun2 = function () { .. }
}
...
}
, if the (optional) local redefinition was intended or:
function outer(hide) {
if(hide) {
fun = function () { .. }
}
...
}
, if a replacement of the global function was intended.


The impact on semantics that conditional function declarations have
seems cumbersome for me, but then perhaps this is maybe just because of
me beeing accustomed to the lexical addressing mode of Scheme. I'd love
to hear how it is supposed to be used and what I may have
misunderstood.


Olov Johansson
 
M

Michael Winter

I just found out that JavaScript 1.5 (I tested this with Firefox 1.0.7
and Konqueror 3.5) has support not only for standard function
definitions, function expressions (lambdas) and Function constructors
(these three I knew about), but also conditional function definitions,
as described in [
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Defining_Functions
].

That article should either be considered wrong, or describing a
proprietary feature. Function declarations are illegal inside block
statements. Though the vast majority of browsers will not throw a syntax
error exception, they handle the construct in different ways. For
example, both Opera and IE treat it as a normal function declaration.

var before = 'Before: ' + typeof test,
after = 'After: ';

if(true) {
function test() {}
}
after += typeof test;

alert(before + '\n' + after);

Before | After
----------+----------
Fx 1.5 undefined | function
IE 6 function | function
Op 8.51 function | function


The correct way to create conditional functions is using function
expressions. If an if statement, or some other construct, prevents
evaluation of the expression, the function object will never exist.

var test1, test2;

if(true) {
test1 = function() {};
}
if(false) {
test2 = function() {};
}

alert(typeof test1 + ' ' /* function */
+ typeof test2); /* undefined */

[snip]
I can't think of any practial use for it considering that function
expressions are available.

There isn't one.

[snip]

If someone has an account at MDC, they might want to edit that article.
If not, I'll register sometime later and change it.

Mike
 
M

Martin Honnen

That article should either be considered wrong, or describing a
proprietary feature.

Well it is the "Core JavaScript" guide on Mozilla's web site so it
describes JavaScript as implemented in/by Mozilla and not ECMAScript or
what other engines implement.

This has been discussed before, see
<http://groups.google.com/group/nets...c.mozilla.jseng&rnum=1&hl=en#db1ac622733b266a>
for instance.

And I think this
<http://groups.google.com/group/nets...c.mozilla.jseng&rnum=2&hl=en#5175f5e12b6f5687>
contains some explanation on when/why this was introduced.
 
M

Michael Winter

Well it is the "Core JavaScript" guide on Mozilla's web site so it
describes JavaScript as implemented in/by Mozilla and not ECMAScript or
what other engines implement.

However, readers may not see the distinction, and may be confused upon
encountering different implementations.

[snip]
And I think this
<http://groups.google.com/group/nets...c.mozilla.jseng&rnum=2&hl=en#5175f5e12b6f5687>

contains some explanation on when/why this was introduced.

I can appreciate why this was implemented as it is, but I question the
way in which it is documented. Function expressions should be used as a
primary example of 'conditional functions'. Conditional function
declarations can then be included as an aside for completeness (and
noted for failing elsewhere), or omitted entirely.

Mike
 
T

Thomas 'PointedEars' Lahn

Michael said:
However, readers may not see the distinction, and may be confused
upon encountering different implementations.

I do not see your point. Readers may also think that ECMAScript and
JavaScript are the same, that JavaScript and JScript are the same or
that cows are violet because they have seen it on TV.

That there are people who have a lot to learn out there does not mean a
guide/reference for an implementation has to emphasize the very fact that
it is describing but a specific (conforming ECMAScript) implementation
which may include unspecified extensions (as it is specified in ECMAScript
ever since) on every possible occasion.


PointedEars
 
M

Michael Winter

Michael said:
On 20/01/2006 17:03, Martin Honnen wrote:
[snip]
Well it is the "Core JavaScript" guide on Mozilla's web site [...]

However, readers may not see the distinction, and may be confused
upon encountering different implementations.

I do not see your point. Readers may also think that ECMAScript and
JavaScript are the same [...]

Indeed they might, but the consequences of that are less harmful.
That there are people who have a lot to learn out there does not mean
a guide/reference for an implementation has to emphasize the very
fact that it is describing but a specific (conforming ECMAScript)
implementation which may include unspecified extensions (as it is
specified in ECMAScript ever since) on every possible occasion.

Has to emphasis implementation-specific features? No, of course not.
Should emphasis them? Probably. Describe those features as the way of
achieving a certain objective without mention of the correct and
compatible alternative? Certainly not!

Read the article again. Function expressions are not described in any
way that indicates the details we know: that they are only create
function objects when evaluated during execution, and as such, can
fulfil the same conditional role. Without this additional knowledge, the
wrong conclusion can be drawn. The article is supposed to be part of a
guide to the implementation, and so it should be informative to a
first-time reader, not misleading.

The Reference documentation does a better job, but it also confuses
matters by stating in one part that the identifier of a function
expression can only be used within the body of the function (which is
correct). However, it later describes these 'conditional function
declarations' as actually being function expressions, but now apparently
the identifier can be accessed from external code. Again, I understand
the reasons for this implementation, but in my opinion a greater status
should be afforded to examples and behaviour that are compatible with
other implementations. The only reason to know about these legacy
features is in order to understand existing code which may depend upon
them. No new code needs to use them under /any/ circumstances, and I
think that should be clearly conveyed.

Mike
 
T

Thomas 'PointedEars' Lahn

Michael said:
Has to emphasis implementation-specific features? No, of course not.
Should emphasis them? Probably. Describe those features as the way of
achieving a certain objective without mention of the correct and
compatible alternative? Certainly not!

There is nothing less correct or less compatible in JavaScript here. Learn
to understand the provisions defined by ECMAScript for its implementations
in section 2. MDC:JavaScript does not claim to provide for an explanation
of proper strictly ECMAScript-compliant programming, it claims to provide
for an explanation of _JavaScript_ programming. You will find many more
examples there that are not strictly ECMAScript compliant, but they work in
_JavaScript_.

You also do not argue that the JScript Reference provides examples that are
JScript-specific even though there would be a "more compatible" way to
achieve it.

However, MDC has the advantage over MSDN Library of being a Wiki, so instead
of complaining here, at the wrong place to the wrong people, you should
move it and change what you do not find appropriate, probably discussing
_there_ what others would think about that before.


PointedEars
 
M

Michael Winter

Michael said:
On 20/01/2006 17:49, Thomas 'PointedEars' Lahn wrote:
[snip]
Has to emphasis implementation-specific features? No, of course
not. Should emphasis them? Probably. Describe those features as the
way of achieving a certain objective without mention of the correct
and compatible alternative? Certainly not!

[...] Learn to understand the provisions defined by ECMAScript for
its implementations in section 2.

The implementation isn't the issue.
MDC:JavaScript does not claim to provide for an explanation of proper
strictly ECMAScript-compliant programming, it claims to provide for
an explanation of _JavaScript_ programming.

So you think it's a good idea for documentation to describe
implementation-specific features in preference to, rather than in
addition to, standardised features that perform the same function?

[snip]
You also do not argue that the JScript Reference provides examples
that are JScript-specific even though there would be a "more
compatible" way to achieve it.

I have in the past, but I haven't here because the JScript documentation
doesn't describe conditional function declarations.

[snip]

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top