Page 1 of 1
Variable scoping
Posted: Wed Jan 01, 2014 4:52 pm
by Chris Walton
What is the scope of variables used in Rel? I have had a (brief) look at DTARM and the Rel grammar and cannot determine this. I assume that any REAL, VIEW, or PUBLIC variable has a database wide scope - ie effectively such variables are all global variables. What about PRIVATE variables? What about variables used within a operator? Or within a block of code? My particular concern is: does the variable scoping permit their use within recursively defined, and recursively called operators?
Alternatively, what is the persistence of variables. Defining a variable as:
Code: Select all
// input and response
VAR i01 CHARACTER INIT ( "" );
Ok.
and then attempting to access it leads to:
Code: Select all
// input and response
i01
ERROR: 'i01' has not been defined.
Re: Variable scoping
Posted: Wed Jan 01, 2014 8:13 pm
by Dave
Variable scope isn't discussed in DTATRM or its predecessors, so I've implemented what I hope are reasonable assumptions and then kept quiet about them.
Yes, any REAL, VIEW or PUBLIC variable has a database-wide scope. All such variables are global.
Relvars declared as PRIVATE have a scope limited to the OPERATOR in which they are declared.
Variables declared anywhere within an operator are local to that operator and available throughout that operator. Variables declared within a block are available outside that block. The following is acceptable:
Code: Select all
operator p() returns integer;
begin;
var x init(2);
begin;
var y init(3);
end;
return x + y;
end;
end operator;
In DBrowser, each execute/evaluate defines its own context. So, local variables declared at the beginning of a given execute/evaluate are available to the rest of it, but are not available to subsequent execute/evaluates. So,
Code: Select all
VAR i01 CHARACTER INIT("");
WRITELN(i01);
will work if executed all at once, but will not work if variable i01 is declared in one execute and WRITELN(i01); is invoked in another.
Re: Variable scoping
Posted: Thu Jan 02, 2014 5:07 pm
by Chris Walton
Thanks for the information. Can I just confirm one of my inferences from what you say:
Given what you say in your code,
Code: Select all
operator p() returns integer;
begin;
var x init(2);
begin;
var y init(3);
end;
return x + y;
end;
end operator;
I infer that variables are not usable within recursive calls ie:
Code: Select all
operator ping (p0, INT) returns integer;
begin;
var x INT;
x := p0;
IF x = 1 THEN return x ELSE x := ping (p0 -1);
end;
end operator;
(This may not be correct syntax or logic, though I hope it is correct enough to be illustrative.) My inference is that this is not valid.
Re: Variable scoping
Posted: Fri Jan 03, 2014 2:18 pm
by Dave
This is valid:
Code: Select all
operator p(x int) returns int;
return if x > 0 then p(x - 1) else x end if;
end operator;
This will give an error:
Code: Select all
var invocations init(0);
operator p(x int) returns int;
begin;
invocations := invocations + 1;
return if x > 0 then p(x - 1) else x end if;
end;
end operator;
It will complain that "
ERROR: In this context, transient global variables like invocations may not be referenced."
However, you can nest operators, so you can do this:
Code: Select all
operator q(z int) returns int;
begin;
var invocations init(0);
operator p(x int) returns int;
begin;
invocations := invocations + 1;
return if x > 0 then p(x - 1) else x end if;
end;
end operator;
var result init(p(z));
writeln("Invocations: " || invocations);
return result;
end;
end operator;
Re: Variable scoping
Posted: Fri Jan 03, 2014 6:36 pm
by Chris Walton
Your responses are very helpful, and enable me to continue making progress with what I am trying to do.
Sorry, if in raising this question, I broke your code of omerta in respect of variable scoping.