XML

kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for variable-scope

2004

Question 80 (2004):

Just out of style are there any differences between the two layouts below:

    PROC q6 (CHAN OF BYTE keyboard, screen, error)
      CHAN OF NAME.NUMBER a:
      PAR
        read.data (keyboard, a)
        display (a, screen)

and

    PROC q6 (CHAN OF BYTE keyboard, screen, error,
             CHAN OF NAME.NUMBER a)
      PAR
        read.data (keyboard, a)
        display (a, screen)

i.e. are they both syntactically the same ?

Answer 80:

I think you mean are they semantically the same (i.e. have the same meaning). Syntactically the same would mean they are identical. But no, these two programs express very different things. In fact, the compiler will reject the second due to invalid usage of "a".

In the second code fragment, "CHAN OF NAME.NUMBER a" is a formal parameter of "PROC q6" -- i.e. whatever calls this procedure must pass "a" as a parameter. If you draw diagrams for both these versions of "q6" you will see that there's something wrong in the second -- some channel "a" that connects "read.data" to "display" also connects to the outside (which you can't draw sensibly and which the compiler rejects). The first code fragment has the declaration of "a" entirely within the body of the process, thus it is entirely internal to that process (which you can draw easily). Diagrams (usually scribbled on a handy bit of paper) are most useful when programming in occam :-).

Keywords: variable-scope


Question 74 (2004):

I have nearly finished the first CO516 occam assesment, but I am getting couple of error messages which have bewildered me.

I am getting two types of error. The first one is "incorrect indentation". I am getting this error in reference to the two lines indicated below, but as far as I can see they are ok.

I am also getting an error which states that "a" and "b" (which refer to PROCs) are "not declared" in "PROC q1".

My code follows, I would be very grateful for any pointers.

    PROC q1 (CHAN OF BYTE keyboard, screen, error)
      CHAN OF INT aToB:
      PAR
        a (aToB)                                -- a not declared
        b (aToB, screen)
    :
    
    PROC a (CHAN OF INT aToB)
      INT num:
      SEQ
        num := 0
        WHILE TRUE
          SEQ
            IF
              (num = 0)
                num := 1000
                aToB ! num                      -- indentation error
              (num <> 0)
                num := num - 1
                aToB ! num
    :
    
    PROC b (CHAN OF INT aToB, CHAN OF BYTE screen)
      INT num:
      WHILE TRUE
        SEQ
          aToB ? num
          out.int (aToB, 10, screen)
          out.string ("*n", 0, screen)
    :

Answer 74:

In occam, the scope of PROC declarations follows that of other (e.g. variable) declarations. Specifically that a "name" (as declared by any declaration) may not be used until it has been defined. This applies to PROC and FUNCTION definitions, DATA TYPE and PROTOCOL declarations, and ordinary variable/channel/etc declarations. The "undefined" error you get in "PROC q1" is correct -- "a" and "b" are not defined yet. To correct this, the declarations of "PROC a (...)" and "PROC b (...)" should be moved above the declaration of "PROC q1 (...)". Thus they will be defined when referenced by q1.

Unlike C and Java, the "main" procedure in occam (where the program starts) is not defined by any special name (e.g. "main" in C and Java programs). Instead the last PROC definition in the file is used, and must have the formal parameters:

    PROC q1 (CHAN OF BYTE keyboard, screen, error)

in that order. The name of the PROC and names of the parameters are largely unimportant. The Linux version of KRoC allows some of these parameters to be omitted, but does place restrictions on what the parameters may be called. The standard KRoC top-level process interface (as above) will work perfectly (except for warnings about unused parameters).

The indentation error in your code arises because that line of code is incorrectly indented. It is incorrectly indented because it is incorrectly structured. Whenever you have more than one process in occam (e.g. the assignment and output), you need to explicitly state whether they are to be run in sequence or in parallel. See the other questions relating to incorrect-indentation for examples of correct usage.

Although the code for "PROC a" is largely fine, it could be improved somewhat. Firstly, the brackets around the "IF" conditions are not necessary --- brackets in expressions are only required when there is ambiguity (since occam does not have any operator precedence -- see below). "IF" conditions are just boolean expressions. Secondly, the "num <> 0" condition would probably be better as just "TRUE". This is because "num <> 0" can't possibly be false, but also because "TRUE" is more meaningful as "otherwise do this" than some expression. Finally, you have duplicated code in both branches of the "IF" (the output). It would be better to "pull" these outside the IF" (and this sort of thing applies to any programming language). I'd also query the use of "aToB" as a sensible formal parameter name in "PROC a" here. Using "aToB" strongly implies that channel connects this "A" process to some "B" process. Although this turns out to be the case here, it might not be always, and that could be misleading. Better to pick a name that has relevance for "PROC a", but is completely unrelated to any actual usage in a process network (i.e. where the process is "placed"). For example:

    PROC a (CHAN OF INT out)
      INT num:
      SEQ
        num := 0
        WHILE TRUE
          SEQ
            IF
              num = 0
                num := 1000
              TRUE
                num := num - 1
            out ! num
    :

Aside: the reason occam has no precedences set for its operators is because many of us cannot remember what they are in those languages that do have them. For instance, how does the following parse in Java:

    if ( a > b + 1 << 4 && 3*a + 2 == x) {...}

? Can you remember the relative precedence between all those operators?? Just what does that expression mean?!

In occam, we don't have to remember anything -- but we do have to bracket our expressions explicitly to give the bindings we want. What-you-see-is-what-you-get:

    IF
      (a > (b + (1<<4))) AND (((3*a) + 2) = x)
	...  do something

Keywords: incorrect-indentation , variable-scope , q1


Question 19 (2004):

Could you please clairfy the correct syntax for indentation in occam. When do you indent a line by two spaces relative to the line above it and when do you use a `:' ?

Answer 19:

The best guides for indentation in occam are existing examples and the "occam2 checklist" (that can be found in the course notes, and on raptor in `/usr/local/courses/co516/etc/' -- `checklist.txt' and `checklist.ps').

The `:' (colon) in occam is used to mark the end of a declaration, and the point at which whatever declared comes into scope. Thus you find it on the end of variable/channel declarations and at the end of `PROC' (and other) definitions. The rule for variable scoping in occam is: a variable is in scope for the process following its declaration. And declarations can be made before any process. For example:

    INT x:
    SEQ
      x := 42
      out.int (x, 0, scr!)
      scr ! '*n'

Here, `x' is in scope for the whole of the `SEQ' process. Contrast with a broken version of the above:

    SEQ
      INT x:
      x := 42
      out.int (x, 0, scr!)
      scr ! '*n'

In this, `x' is declared just before the assignment-process (`x := 42'), so is in scope there, but not in the procedure call to `out.int' -- so the compiler will likely report an error (unless there is another `x' in scope).

Keywords: indentation , variable-scope

Referrers: Question 54 (2004)

2003

Question 46 (2003):

I'm having trouble with the `overflow.buffer' process in q5. Here is what I have; there seems to be a problem with `count' such that it doesn't get incremented and nothing ever gets outputted. Thanks.

    [adjusted code]

    PROC overflow.buffer (...)
      VAL INT BUFSIZE IS 10:
      [BUFSIZE] BYTE Buffer:
      INT head, tail, count:
      SEQ
        head:= 0
        tail:= 0
        INT count:
        count := 0
        WHILE TRUE
          ...  do things
    :

Answer 46:

Inside the body of the WHILE loop, `count' is undefined [1]. The assignment `count := 0' is assigning to the `count' declared immediately above it. In occam, the scope of a variable is the process that follows it. Assignment is a process (simple), as are SEQ blocks, etc. (processes that contain sub-processes). Thus, the scope of the first `count' declaration is the entirity of the SEQ body (in effect, all the code in `overflow.buffer'). When `count' is declared again inside the SEQ, it descopes the earlier `count'. The scope of this is, as always, the process that follows it, which is just the single assignment `count := 0', which of course leaves the earlier `count' untouched.

  1. By default, the occam workspace is initialised to 0x80000000 (MOSTNEG INT). Thus, count will likely be this value -- but it should always be considered undefined (with an unknown value). The Linux version of KRoC now has an undefined usage checker which will spot these sorts of error. Pre-releases of KRoC/Linux are better at this sort of thing.

Keywords: q5 , variable-scope


Question 33 (2003):

This is one of the statements under a PRI ALT in my code:

    BYTE y:
    in ? y
      out ! y

When I compile it tells me that `y' is not declare on the second line. However, I have exactly the same piece of code in another PROC with a `z' instead of a `y' and yet it compiles ok. Any ideas ?

Answer 33:

If that's a guard of a PRI ALT, there's nothing wrong with it. Thus, the error must be elsewhere. Errors above that, but possibly still inside the PRI ALT, might be confusing the compiler when it gets to this point. The first error output by the compiler is generally the most relevant -- others may simply be a cascade effect.

Keywords: alternation , variable-scope

2000

Question 42 (2000):

I am creating a PROC but need global variables for it. Where would I declare them?

  PROC rah (CHAN OF INT a, b, c, d)
    WHILE TRUE
      ...  loop body
  :

These variables and their state will need to be used throughout the PROC. Do these need to declared before the WHILE TRUE bit or is there another way?

Answer 42:

By global variables, I assume you mean variables to be used anywhere inside your rah process. These are properly known as local variables of that process. [Properly global variables are declared outside and before the declarations of all the PROCs to which they are global. In general, working with such globals is a bad thing - if you need access to global structures, pass them in through the parameter list. In the particular case of the outermost PROC declarations of a compilation unit, global variables are not allowed and will be rejected by the compiler.]

If you want local variables in rah that are global to your loop, they must be declared and initialised before the loop:

  PROC rah (CHAN OF INT a, b, c, d)
    ...  declare some variables
    SEQ
      ...  initialise those variables
      WHILE TRUE
        ...  loop body
  :

Those variables will retain their values as control flows around the loop.

If the variables are only needed within the loop body (i.e. their values do not need to be retained from one loop cycle to the next), declare them at the start of the loop body:

  PROC rah (CHAN OF INT a, b, c, d)
    WHILE TRUE
      ...  declare some variables
      SEQ
        ...  initialise those variables
        ...  loop body
  :

Keywords: variable-scope


Question 29 (2000):

Help! I am trying to do part three of question 4 (the second assignment) and I can't get the following to compile. The error message is that state is not declared on the line marked:

  WHILE TRUE
    SEQ
      BOOL state:
      state := TRUE  -- start with normal pairs process
      WHILE state    -- <<<< COMPILER COMPLAINS HERE
        ...  loop body

Surely though, it is - just above the line which causes the compiler to fail!

Answer 29:

No it's not!! It's declared two lines before the line complained of by the compiler. Declarations have scope for subsequent declarations and the first executable that follows (which must all be at the same level of indentation). In the above, the first executable following the declaration is the assignment - so state is in scope there, but not for the following executable (the while-loop).

To make the declaration have scope for more than one executable, those executables must be wrapped up in a SEQ (or PAR or WHILE or IF etc.) - that turns them into a single executable. This question has been asked before - see the answer to Question 3 (2000).

Keywords: q4 , variable-scope

Referrers: Question 54 (2004)


Question 3 (2000):

What is the scope of declarations? In my code:

  SEQ
    BOOL running:
    running := TRUE
    WHILE running                -- compiler says running is not declared!
      ...  body of the loop

the compiler says the running variable is not declared on the "WHILE" line - even though it has just been declared and initialised!

Answer 3:

Following a declaration (e.g. of your "running" flag), the item declared has scope in any subsequent declarations (which must all remain at the same level of indentation) and in the executable code that follows it (also at that same level of indentation).

In your case, the executable code following the declaration is only the initial assignment and not the WHILE-loop. It can't be both since two statements, without an enclosing SEQ or PAR, do not make up a legal executable - see Question 1 (2000).

Your declaration is in the wrong place. It should be:

  BOOL running:
  SEQ
    running := TRUE
    WHILE running                -- running is still in scope
      ...  body of the loop

The scope of "running" is the executable following its declaration. This time, that executable is the whole SEQ construct - not just its initial assignment.

Keywords: variable-scope

Referrers: Question 54 (2004) , Question 21 (2003) , Question 29 (2000)

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:34 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.