Language Reference/Basic Concepts/Scoping and Visibility

From wiki.visual-prolog.com

Name Categories

All names (identifiers) in Visual Prolog are syntactically divided into two major groups:

  • Constant names (starting with a lowercase letter)
  • Variable names (starting with an uppercase letter or an underscore)

Constant names (identifiers) are divided into the following categories:

  • Type names (i.e., domains and interfaces)
  • Domain carriers (i.e., classes and interfaces)
  • Names without parentheses (i.e., constants, fact variables of non-function type, and nullary-functors)
  • Value-returning names of arity N (i.e., functions, functors, and fact variables of function type)
  • Non-value-returning names of arity N (i.e., predicates, facts, and fact variables of predicate type)

Visual Prolog requires that names do not conflict at the point of declaration; otherwise, conflicts cannot be resolved at the point of use. Declarations can only conflict if they are in the same scope, because scope qualification can resolve conflicts. A name in one category can never conflict with a name in another category, but a single declaration can place a name in several categories.

Packages

Packages are the basic units of code organization in Visual Prolog. They group related interfaces and classes.

Each declaration or implementation of an interface or class in a package is placed in a separate file. Each filename matches the interface or class that it declares or implements. All package files are stored in the package directory; subpackages are stored in subdirectories of that directory.

Packages can act as class libraries. You can include packages in your program instead of placing all used interfaces and classes directly in the program.

How packages are structured and included in projects is described in the IDE documentation (see Creating a Package in Creating New Project Items).

Visibility, Shadowing, and Qualification

Most scoping rules were introduced above; this section completes the picture.

An interface definition, a class declaration, and a class implementation are scopes (scopes cannot be nested). An implementation (privately) extends the scope of the corresponding class declaration. Visibility is the same everywhere in a scope; i.e., no matter where something is declared in the scope, it is visible in the whole scope.

Public names from supported interfaces and super-classes are directly (i.e., without qualification) available inside a scope when their origin is unambiguous. It is illegal to use a name whose origin is ambiguous. Ambiguities in predicate calls can be removed by qualifying the predicate name with the class name (e.g., cc::p).

This qualification is also used to qualify calls to object member predicates of super-classes on the current object.

Visual Prolog has the following shadowing hierarchy:

  • Local
  • Opened scopes and super-classes

Opened scopes have the same status as super-classes. Local declarations shadow declarations in opened scopes. If two or more opened scopes contain conflicting declarations, you can only access them by using qualification.

Example Assume the interface ixx and the classes aa and bb:
interface ixx
 
predicates
    p1 : ().
    p2 : ().
    p3 : ().
 
end interface ixx
 
%========================
 
class aa : ixx
end class aa
 
%========================
 
class bb
 
predicates
    p3 : ().
    p4 : ().
    p5 : ().
 
end class bb

The class aa creates objects of type ixx, whereas the class bb does not create objects at all.

In this context consider the implementation of a class cc:

implement cc inherits aa
    open bb
 
clauses
    p2(). % reimplementation of ixx::p2
 
predicates
    p5 : ().
clauses
    p5().
 
clauses
    new() :-
        p1(), % aa::p1
        p2(), % cc::p2 (shadows aa::p2)
        aa::p2(), % aa::p2
        p3(), % Illegal ambiguous call: aa::p3 or bb::p3
        aa::p3(), % aa::p3
        bb::p3(), % bb::p3
        p4(), % bb::p4
        p5(). % cc::p5 (shadows bb::p5)
 
end implement cc
Since cc inherits aa, all predicates in the interface ixx are visible in cc. Likewise, the open bb directive makes all predicates in bb visible in cc.