It is not possible to have definitions in subsequent scope without allowing shadowing. E.g.:

Int x;
Int x;

The 2nd x shadows the first x and does not give a duplicate definition error. Incorrect in Java, C#, GM, Scala, … . Corresponding NaBL rule:

Decl(t, var):
	defines 
	  Variable var
	    of type t
	  in subsequent scope
Submitted by Vlad Vergu on 2 July 2013 at 19:57

On 2 July 2013 at 20:19 Vlad Vergu tagged !vvergu

On 2 July 2013 at 20:57 Guido Wachsmuth commented:

IMO, this is not really an error and not related to subsequent scopes. You have the same with regular scopes. In Java,

int x;
{
  int x;
}

is also not allowed, because variable hiding is in general forbidden. What we need is a mechanism to specify error messages

VarDec(ty, v):
  defines Variable v of type ty in subsequent scope
  error $[hiding variable [v'] in same or outer scope]
    where v hides Variable v'

On 2 July 2013 at 21:06 Gabriël Konat commented:

The problem is that with

int x;
int x;
x;

the second x shadows the first x, because in subsequent scope generates new scopes after each variable definition. The result of the lookup of x is then one definition instead of two, which is generally wrong since most languages (Java, C#, C, etc) do not allow shadowing within the same scope.

You still want to disallow use before definition, but in this case the second x should not hide the first x so in subseqent scope cannot be used.


On 2 July 2013 at 21:09 Guido Wachsmuth commented:

I don’t understand your explanation. Why would you like to get two definitions and why is it wrong to get just one? In Java it is already wrong to have the second definition, and we should report an error on this. But it is the same as with regular scopes, like in the block. There, you also need an error. Reconsider my above example. Resolving the x inside the block will also give you just one definition. The key is that hiding is forbidden, and we should give an error there. The same holds for variables in subsequent scopes. If hiding is allowed, everything is fine. If it is forbidden, you need to specify an error check.

You can currently implement manual error messages for hiding following this pattern:

type-of(|ctx): VarDecl(_, x) -> <fail>
where
  uri := <nabl-uri> x
; uri' := <...> uri // create uri in parent scope
; task := <...> uri' // create task for lookup x in outer scopes
; <task-create-error-on-success(|ctx, task, "hiding!")> x

On 2 July 2013 at 23:37 Vlad Vergu commented:

This is the actual type-of rule that does it:

 type-of(|ctx): Decl(_, [var], _) -> <fail>
	where
	  uri   := <nabl-uri> var
	; uri'  := <nabl-uri-parent; nabl-uri-parent> uri
	; task* := <nabl-use-subtasks(id, fail|ctx, <nabl-uri-namespace> uri, <nabl-uri-name> uri, [], All())> uri'
	; task  := <new-task(|ctx)> Choice(task*)
	; <task-create-error-on-success(|ctx, task, "hiding!")> var

On 3 July 2013 at 01:59 Gabriël Konat commented:

You’d like to get two definitions for a duplicate definitions error. I guess you can also just use a hiding error instead of duplicate definition.


On 9 July 2013 at 01:43 Vlad Vergu commented:

Feel free to close this issue if you think we’ve reached an acceptable solution from NaBL point of view.


On 9 July 2013 at 02:32 Gabriël Konat closed this issue.

Log in to post comments