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
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