[ nice-Bugs-798312 ] local function param namespace
"SourceForge.net" <[email protected]>
| Newsgroups | gmane.comp.lang.nice.devel |
|---|---|
| Message-ID | <[email protected]> |
Bugs item #798312, was opened at 2003-08-31 16:37
Message generated for change (Comment added) made by igouy
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=112788&aid=798312&group_id=12788
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Isaac Gouy (igouy)
Assigned to: Nobody/Anonymous (nobody)
Summary: local function param namespace
Initial Comment:
My guess is that this is a feature request?
These comments refer to the code in
WordfreqIntermediateExample.
I made the formatLine package function a local function
(mainly so I could reuse the StringBuffer) and
discovered that the parameter name 'word' clashed with
the variable name 'word'. Of course, we can rename the
parameter in some arbitrary way like 'wordX' (although
the keyword parameters mean that's not so good and
perhaps we need to go back and rename the local
var...).
void main(String[] args){
var String word;
...
String formatLine(String wordX, Cell count){
...
buffer.append(wordX);
...
}
... formatLine(wordX: e.getKey(), count: e.getValue())
}
----------------------------------------------------------------------
>Comment By: Isaac Gouy (igouy)
Date: 2003-09-01 17:07
Message:
Logged In: YES
user_id=536291
>> Now I've had breakfast
> Funny to hear this when it's 9pm for me :-)
Well it was a late holiday brunch ;-)
> Please detail with sample code
I had such a strong feeling about this, it's probably something
that I originally learned in Pascal eons ago ;-)
(All those Pascal derivatives will probably do the same thing, I
wonder if it's a C - Pascal difference?)
For a while I thought about what a C# or Java example would
look like, but I think the difference we've come across is not
one that can be examined in a such limited OO languages for
a couple of reasons:
- variables would always be inside a class or method
- no local functions within a method or package
Here's some Smalltalk:
| i j f |
j := 100.
i := 22.
f := [:i | | j | j := i + 20 ]. "this is an anonymous function"
Transcript
show: (f value: j) printString; cr;
show: i printString; cr;
show: j printString.
The compiler warns about i & j being 'already defined
(perhaps in an outer scope)', compiles and gives this result:
120
22
100
I suppose you might consider Smalltalk to be a bizarre
language, so once more here's Oberon-2 ;-)
(not a bad language for comparison - they were obsessed
with 'safety')
MODULE MainTest;
IMPORT Out;
VAR i: INTEGER; j: SHORTINT;
PROCEDURE Test (VAR i: SHORTINT): INTEGER;
VAR j: INTEGER;
BEGIN
j := LONG(i) + 20;
RETURN j;
END Test;
BEGIN
j := 100;
i := 22;
Out.Int(Test(j) ,5);
Out.Int(i ,5);
Out.Int(j ,5);
END MainTest.
XDS Oberon-2 v2.40 [x86, v1.50] - build 20.02.2002
Compiling "maintest.ob2"
no errors, no warnings, lines 20, time 0.01
I:\pls\Oberon2\test>maintest
120 22 100
----------------------------------------------------------------------
Comment By: Daniel Bonniot (bonniot)
Date: 2003-09-01 12:28
Message:
Logged In: YES
user_id=88952
> Now I've had breakfast
Funny to hear this when it's 9pm for me :-)
> Seems like I expect 'nested scope'.
Yes, and that's what you get, too, as far as I can see:
void F(String word){}
var String word;
This is valid, since the two versions of word are never
alive in the same scope.
var String word;
void F(String word){}
Here, the outer word (if it has another name) would normally
be visible inside the local function. With the same name, it
would be shadowed. Since that could be an accident and you
might think wrongly to access the outer one, the compiler
reports the problem.
This is exactly the same in Java (and probably in most
structured languages):
{
int foo = 0;
}
int foo = 0;
is valid, while
int foo = 0;
{
int foo = 0;
}
is not.
> It seems that the parameter of functional F doesn't exist
> beyond the scope of F.
That's normal. You cannot access a function parameter
outside the scope of that function.
> So the name clash of main3 is surprising to me.
There is no clash in main3. It uses a variable that was not
declared. Maybe you forgot 'var' ?
>And of course I don't experience that name clash in other
languages
Please detail with sample code if you still think this is
the case. I don't think so.
> Given that the param and var are local to F, I only "expect"
> that they will have name clashes in that local scope.
But the outside variable is visible inside the function.
> Aside from the bad 'surprise', the main consequence is more
> debug/editing when a function is moved, and a 'forced'
> arbitrary naming of vars and params to get around the name
> clash (rather than express intent).
What about when you move some code from the main function to
the local one? It could silently reffer to a different
variable than the one intended.
Isn't it better to be told about the problem? Sure, there
can be some editing needed, but it is guaranteed to be
local, since the inner function is a local feature.
It will always be confusing to have several variables
shadowing each other. At the point where use define the
inner word, the outer has no meaning. I think it would be
cleaner to make a separate function that takes the map, and
prints the results. That would keep the main function
shorter and cleaner.
----------------------------------------------------------------------
Comment By: Isaac Gouy (igouy)
Date: 2003-09-01 11:05
Message:
Logged In: YES
user_id=536291
Now I've had breakfast perhaps I'll make more sense.
Seems like I expect 'nested scope'.
----------------------------------------------------------------------
Comment By: Isaac Gouy (igouy)
Date: 2003-09-01 08:33
Message:
Logged In: YES
user_id=536291
> more important to show different aspects of Nice
I agree! And its important to show a practical style.
> redeclaration of local variables is not allowed
Let me step through what surprises me:
This compiles:
void main1(String[] args){
void F(String word){}
var String word;
}
but this doesn't:
void main2(String[] args){
var String word;
void F(String word){}
}
\test\t.nice: line 3, column 23:
Symbol word is already defined.
Previous definition: \test\t.nice: line 2, column 15
1) I hadn't realized declaration order mattered
void main3(String[] args){
word = "test";
void F(String word){}
}
\test\t.nice: line 2, column 4:
word is not declared
2) It seems that the parameter of functional F doesn't exist
beyond the scope of F. So the name clash of main3 is
surprising to me. (And of course I don't experience that name
clash in other languages.)
void main4(String[] args){
word = "test";
void F(){ var String word; }
}
\test\t.nice: line 2, column 4:
word is not declared
void main5(String[] args){
var String word;
void F(){ var String word; }
}
\test\t.nice: line 3, column 25:
Symbol word is already defined.
Previous definition: \test\t.nice: line 2, column 15
3) Same as #2 but with a variable local to F.
Given that the param and var are local to F, I only "expect"
that they will have name clashes in that local scope.
Aside from the bad 'surprise', the main consequence is more
debug/editing when a function is moved, and a 'forced'
arbitrary naming of vars and params to get around the name
clash (rather than express intent).
Nice compiler version 0.9.2 (build 2003.09.01, 08:24:05 UTC)
----------------------------------------------------------------------
Comment By: Arjan Boeijink (arjanb)
Date: 2003-09-01 05:30
Message:
Logged In: YES
user_id=688815
This is not a bug, redeclaration of local variables is not
allowed because it mostly indicates an error or bad code
practise.
BTW I changed the code in that example because it
contained to much optimization tricks. I know the code comes
form a benchmark but I think it's more important to show
different aspects of Nice than showing how to squeeze out a
few percent more perfomance.
----------------------------------------------------------------------
Comment By: Daniel Bonniot (bonniot)
Date: 2003-09-01 01:27
Message:
Logged In: YES
user_id=88952
Idem, please submit something we can copy paste and compile
(without "..."). It's also good if you can remove irrelevant
parts, so the code is as short as possible.
It's also not clear from your message was is the bug (you
seem to have to identifiers with the same name, isn't a
"clash" expected?), or what feature you request.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=112788&aid=798312&group_id=12788
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf