[Nickle]Scoping rules for declarations
Barton C Massey
nickle@keithp.com
Wed, 30 Jan 2002 12:44:55 -0800
Thanks for your excellent summary. Only comments I would
have are that
1) AFAIK bar_expression cannot even refer to bar as things
are currently implemented. This is arguably just a
bug, and should be fixed.
2) `function' declarations aren't quite just sugar,
because unlike case 1 above, you can refer to the name
of a `function' in the function body. This argues even
more strongly that case 1 above is just a bug.
3) Yes, you may mix definitions freely with other code.
In fact, since definitions are expressions, you can
write things like
(int x = 3), (string y = "z");
where that comma is, strangely, a comma operator.
The principal use of this, of course, is to be able
to write things like
for(int i = 0; i < 10; i++)
which work the same way as in (modern) C++.
4) As discussed earlier, you have to be a little bit
syntactically careful when doing "forward-declaration"
style recursion. I'd write your last example as
int function is_odd(int n);
int function is_even(int n) { return n == 0 || is_odd(n-1); }
is_odd = (int func(int n) { return n > 0 && is_even(n-1); });
as per Keith's earlier suggestion.
Clearly, there are ugly warts here. I'll kick around the
`function' syntax with Keith and we'll see what we can
figure out.
Bart
In message <005b01c1a9b4$c20f6200$6501a8c0@meurglysvii> you wrote:
> Thanks for your answers. Let me summarize what I was
> able to guess/figure out so far:
>
> Local declarations are self-recursive and nested (as in C):
> { /* some local scope */
> mytype_t foo = <foo_expression>;
> /* <foo_expression> can refer to (but not use value of) foo
> because it is in scope but not yet initialized;
> it cannot refer to bar below because it is not in scope yet
> (any reference to bar would refer to "outside" bar if any) */
> anothertype_t bar = <bar_expression>;
> /* <bar_expression> can refer to (but not use value of) bar;
> it can refer to and use value of foo: it is in scope and initialized
> */
> <code> /* can use both foo and bar freely */
> }
>
> Comma-separated declarations are nested also:
> {...
> mytype_t foo = <foo_expression>, bar = <bar_expression>;
> ...
> }
> is equivalent to:
> {...
> mytype_t foo = <foo_expression>;
> mytype_t bar = <bar_expression>;
> ...
> }
>
> Function declarations are sugared versions of variable declarations:
> {...
> mytype_t foo(<args>) {<body>}
> ...
> }
> is equivalent to:
> {...
> mytype_t(<arg-types>) foo = (mytype_t func(<args>){<body>});
> ...
> }
>
> Is this a correct picture of nickle local declaration rules? Is
> it possible to "mix" declarations and statements inside blocks
> (as in C99 and C++) or all declarations should come before the
> first statement of the block (as in K&R C)?
>
> What are the rules for file-level declarations? Can I make C-style
> "forward" declarations if I am writing mutually recursive functions:
>
> bool is_odd(int);
> bool is_even(int n) { return n == 0 || is_odd(n-1); }
> bool is_odd(int n) { return n > 0 && is_even(n-1); }
>
> Regards,
> Sergei
>
>
>
>
> _______________________________________________
> Nickle mailing list
> Nickle@keithp.com
> http://keithp.com/mailman/listinfo/nickle