[e-lang] scoping rules of when-catch
Toby Murray
toby.murray at dsto.defence.gov.au
Thu May 18 21:58:58 EDT 2006
Hi e-lang,
I'm wondeirng if someone can clarify the behaviour of when-catch,
particularly how its implementation affects the scoping rules. I've been
doing some experimentation thismorning to try to figure out what's going
on with it and am hoping someone can explain the behaviour I'm seeing.
From what I've read in MarcS' "Walnut" and the tutorial on erights.org,
it says that when using nested when-catch statements, one must avoid
doing things like the following, where we re-use the name "done"
def func1 := { .... }
def p1 := func1 <- run()
def p2 := func1 <- run()
when (p1) -> done(v1) :any {
when (p2) -> done(v2) :any {
} catch prob {
}
} catch prob {
}
The reason it gives is that both "done" functions that we are defining
here sit in the same scope, meaning that the second "done" definition
will clash with the first. I understand this to mean that the above code
is defining "done"s like this:
def done(v1) :any {
}
def done(v2) :any {
}
I personally found this totally counter-intuitive -- to my way of
thnking, the programmer can do nothing else but assume that his code is
behaving like this:
def done(v1) :any {
def done(v2) :any {
}
}
which, to me, should be totally fine. Experimenting seems to indicate
that it is infact (in the latest stable version) implemented the second
way. I can write nested "done"s without any problem. Also, the inner
"done" has access to any local variables (sorry, can't think of a better
term) defined by the outer done.
This seems to contradict the statements in "Walnut" and the tutorial,
which if true, obviously isn't good for newcomers to E trying to learn
the language.
Upon further experimentation, it does appear though that the body of the
"catch" clause sits within the body of the "done" clause, in terms of
scoping.
For example, when interpreting the following code, rune complains about
comflicting re-definition of $done__C$done__C
(or something like that, I don't have the output in front of me).
def func() :any {
return 1.0
}
def p1 := func <- run()
when (p1) -> done(v1 :int) :any {
println("done called")
def p2 := func <- run()
when (p2) -> done(v2: int) :any {
println("done-done called")
} catch prob {
println("done-catch called")
}
} catch prob {
println("catch called")
def p2 := func <- run()
when (p2) -> done(v2: int) :any {
println("catch-done called")
} catch prob {
println("catch-catch called")
}
}
Changing the "done" inside the first "catch" to "done2" fixes the
problem. Likewise, chainging both the "done" inside the outermost "done"
to "done2" and also the "done" inside the outermost "catch" to "done2"
keeps the problem, confirming my suspicion that both of these inner
"done"s (done-done and catch-done) are being defined at the same
scoping level.
It appears (to my mind) that the above is behaving like
def done(v1 :int) {
println("done called")
def done(v2: int) {
println("done-done called")
}
def done(v2: int) {
println("done-catch called")
}
}
Strangely enough, through, the following code produces infinite recursion
def func() :any {
return 1.0
}
def p1 := func <- run()
when (p1) -> done(v1: int) {
println("done called")
def p2 := func <- run()
when (p2) -> done(v2: int) {
println("done-done called")
} catch prob {
println("done-catch called")
}
} catch prob {
println("catch called")
done(1.0)
}
We get
catch called
catch called
catch called
...
So "done" wihtin that outermost "catch" is bound to the outermost
"done", which might contradict my previous assertion..
It's all a bit confusing, really :)
Can someone help me out here?
Thanks heaps,
Toby
--
Toby Murray
Advanced Computer Capabilities Group
Information Networks Division
DSTO, Australia
IMPORTANT: This e-mail remains the property of the Australian Defence
Organisation and is subject to the jurisdiction of section 70 of the
Crimes Act 1914. If you have received this e-mail in error, you are
requested to contact the sender and delete the e-mail.
More information about the e-lang
mailing list