Why is this stow- and runable?

Hello all,

This program:

DEFINE DATA LOCAL
1 VIEW1 VIEW FILE32
2 TKS
1 VIEW2 VIEW FILE32
2 TKS
END-DEFINE
*
GET VIEW1 171      /* TKS = TRUE
GET VIEW2 2        /* TKS = FALSE
*
WRITE '      TKS'       TKS  /* no NAT0434 here
WRITE 'VIEW1.TKS' VIEW1.TKS
WRITE 'VIEW2.TKS' VIEW2.TKS
*
END

Produces that Output:

      TKS
VIEW1.TKS X
VIEW2.TKS

I would expect a NAT0434…

Matthias

The first WRITE is not unknown to Natural.
It defaults to the physically preceding GET.
Hence the output, and no 434.

Even if they were both READs, with both END-READs after the three WRITEs, there would be no 434. Natural would default to the innermost READ, which would be VIEW2, or FALSE.

However , still working with READs, if you put a non qualified TKS after the second end-read you would get a 434.

I would say: No. Not physically
Please try this:

DEFINE DATA LOCAL
1 VIEW1 VIEW FILE32
2 TKS
1 VIEW2 VIEW FILE32
2 TKS
END-DEFINE
*
GET VIEW1 171      /* TKS = TRUE
perform view2get
*
WRITE '      TKS'       TKS  /* no NAT0434 here
WRITE 'VIEW1.TKS' VIEW1.TKS
WRITE 'VIEW2.TKS' VIEW2.TKS
*
define subroutine view2get
GET VIEW2 2        /* TKS = FALSE
WRITE 'SUB   TKS'       TKS  /* no NAT0434 here
end-subroutine

… so from my Point of view, natural’s behaviour is a bit dangerous, isn’t it?

Sorry, forgot to post the output:

SUB   TKS
      TKS X
VIEW1.TKS X
VIEW2.TKS

Hi Matthias;

Fortunately, even though it is only 7am here, I get up at 5am and hence have had breakfast and three cups of coffee, so my brain was able to unravel what I think is where you may have gone wrong in your reasoning.

I think you have intermixed compile time with execution time in your reasoning. Here is your code:

GET VIEW1 171 /* TKS = TRUE
perform view2get
*
WRITE ’ TKS’ TKS /* no NAT0434 here /* physically preceding GET is VIEW1
WRITE ‘VIEW1.TKS’ VIEW1.TKS
WRITE ‘VIEW2.TKS’ VIEW2.TKS
*
define subroutine view2get
GET VIEW2 2 /* TKS = FALSE
WRITE ‘SUB TKS’ TKS /* no NAT0434 here /* physically preceding GET is VIEW2
end-subroutine

The WRITE after the PERFORM defaults to VIEW1 (physically preceding). At execution time, the preceding GET is indeed VIEW2. BUT, Natural had to decide at compile time which GET dictated the first of the three physically contiguous WRITEs. Hence the selection of VIEW1, not VIEW2.

There are other examples of physical appearance taking precedence over logically executed.

For example, Natural takes its column “layout” from the physically first DISPLAY statement in a program, EVEN IF, that DISPLAY is never executed.

Example:

:::
END-DEFINE
*
IF #A NE #A
DISPLAY NOHDR list of field names eg. #T1 #T2 #T3
END-IF
:::
READ…
IF some condition
WRITE T*#T2 NAME STATE
ELSE
WRITE T*#T3 NAME PROVINCE
END-IF
END-READ

The column layout is controlled by the physically first DISPLAY statement. It (first DISPLAY) serves the same role as a tabset on a typewriter.

OK. “physically preceding GET” sounds to me like from Adabas’ point of view.

So, the behaviour is similar to a reference-less *ISN

But I still think it’s a bit dangerous. Imagine you move a regarding SUBROUTINE from the bottom of the code to the top…

For example of such moves:

define data local
1 view1 view of employees
2 name
1 view2 view of employees
2 name
end-define
*
** if you move subroutine definition here you will get NAT0434
*
get view1 1
write ‘=’ name ‘from view1’
**
** if you move subroutine definition here, you will get name from view1
*
get view2 2
write ‘=’ name ‘from view2’
perform mysub
*
define subroutine mysub
write ‘in mysub, name is’ name /* here you get name from view2
end-subroutine
*
end

So yes, you can alter the logic of the code by merely moving the subroutine. At least moving it to the top produces an error message; moving the subroutine between the two GETs produces different (erroneous?) output.

My mantra has always been “If you can qualify it, you should qualify it.” Even in quick-and-dirty ad hocs.

It’s easier than trying to remember Natural’s rules.