A scope in eXPL is a context that encapsulates a namespace, a locale and a properties environment. There is a global scope created at the start of a program and it is this scope which has been employed exclusively up till nou. The global scope has the following characteristics:
- Name - All scopes have a unique name which as a rule must used when refering to an artifact from outside the scope in which it resides. The global scope is an exception to that rule. It's name is "global", and when scope is omitted from an artifact's name, it is assumed to be this name. .
- Locale -The locale for any scope, including the global scope, defaults to the system default. However, the locale can be configured to any of ones supported by the Java runtime and this will be applied when working with number and currency formats.
- Properties - A scope can be assigned any number of key-value pairs, plus 2 properties are reserved to set the locale - "language"
and "region". If you run the ShowLocale application of tutorial12, you will see what these properties
are set to in the global scope of your system. In Australia, you will see:
locale_query(language=en, region=AU).
To prove the global scope exists, change the ShowLocale query from:
to
and run the application. The query should run to completion as normal. Change "global" to something else, and you will get a "scope not found" error.
Scope Format
A scope declaration has a name, statements enclosed in braces {} and optional properties:
scope name [ ( properties ) ]
{
eXPL-statements
}
The properties are specified as a comma-delimited list of name-value pairs eg. (language="de", region="DE") specifies the Germany locale. A "variant" or "script" property can be added if required. The properties are accessed using a built-in axiom term list named "scope".
A scope may not have any enclosed statements, in which case, it just declares a context for artifacts in the global scope to use. Note that, apart from the global scope, a scope may not be nested inside another scope.
Applying Scope to Global Artifacts
A scope is assigned to a global artifact by referring to it using a 2-part name, the first part being the name of the desired scope. A scope can also be applied to a query at the time it is executed, which has the effect of applying that scope to all global artifacts.
The global scope is not normally declared, but this can be done to override the preset properties or add new ones.
Application CalculateSquareMiles3 of tutorial12 demonstrates declaring the global scope to change the "location" property to an actual name of a country. There is a second scope named "australia" which also sets the "location" property. The application displays the surface areas of both Australia and the USA and the units used, square kilometers or square miles depends on the location property. Note how the calculator named "country_area" is referred to as "australia.country_area" in the Australian query.
Axiom Collections in Scopes
There various ways to place an axiom collection within a scope and access it. An axiom collection can be declared in the global scope using a 2-part name. This is a requirement for context lists, but for other purposes it is appropriate to enclose a collection inside the scope to which it belongs. This approach is explored in using 3 queries, each run by one of the 3 SingleCurrency applications of tutorial13. The 3 queries are all contained in a single eXPL single-currency.xpl file which declares a German and French scope, each containing an axiom collection with a single axiom containing a single Euro amount. Each application runs one query in this file and prints the solution showing "Total" for a German-formatted amount and "le total" for a French one. The program may be a little confusing, because the example also shows it is okay to use the same name for artifacts in different scopes. The axiom collection in both cases is named "item".
SingleCurrency - part 1
The following query is declared in the global scope and uses 2-part names for both the axiom collection and the template. Below it is the solution.
Total + gst: 13.580,24 EUR
This approach is useful in that all queries can be declared together, rather than spit amongst the scopes.
SingleCurrency - part 2
The following query is declared in the German scope and pairs the local axiom collection to a template in the French scope.Below it is the solution.
le total + gst: 16 419,74 EUR
This shows that it is okay to cross scopes when pairing axiom collections to templates. In this case, a higher tax rate is applied as well as changing the word for "Total"
SingleCurrency - part 3
The following query is declared back in the global scope. It directly evaluates global template "french_charge_plus_gst".Below it is the solution.
le total + gst: AUD665.00R
We see "le total" and a very different amount because it is derived from the French item containing only 500 Euros.
The French item is refered to using a 2-part name: french.item->amount. This is similar to using a context list,
but because there is just one specific scope, no declaration is required.
Resources in Scopes
External axiom collections are accessed via resources, and these are capable of being slotted into scopes. Application ForeignColors of tutorial13 sequences 2 eXPL programs to firstly create French and German axiom collections which are marshalled to files on disk and then run queries to access these collections as resources.
Reading Resources
The second program declares the "colors" axiom collections as resources using 2-part names:
resource french.colors axiom(aqua, black, blue, white);
These collections are accessed using context lists ie. refering them as colors@scope.
