Introduction to Namespaces
Introduction to Namespaces
Fundamentals of Namespaces
Introduction
Like a module, a namespace is a technique of creating a section of code to isolate names that can be uniquely identified even if some of those names are used somewhere else in a program. There are various differences between modules and namespaces. To point out those differences, we will review the features we saw for modules.
Creating a Namespace
To create a namespace, in a document, type the namespace keyword.
The Name of a Namespace
After the namespace keyword, type a name. The name of a namespace follows the rules of names of classes. Here is an example:
namespace Geometry
...
We will come back to issues about the name of a namespace.
Unlike a module, the creation of a namespace doesn't include the = sign.
The Body of a Namespace
After the name of the namespace, press Enter. The section on the the next line after the creation of a namespace is the body of the namespace. As a result, the formula to create a namespace is:
namespace namespace-name
body
The Contents of a Namespace
Introduction
We already know that the first line of an F# code can contain the creation of a module or anything else, such as a function or a variable. Here is an example:
printfn "Welcome to the wonderful world of F#!"; module Exercise = printfn "F# is a functional programming language!!!";
This would produce:
Welcome to the wonderful world of F#! F# is a functional programming language!!! Press any key to continue . . .
In a document that contains the creation of a namespace, that creation must be the first line of code. As a result, the following code will fail:
printfn "Welcome to the wonderful world of F#!";
namespace . . .
A module can contain just about anything, including variables, functions, and classes, etc. Here is an example:
module CarDealer = type Vehicle(tag : string, make : string, model : string, yr : int) = do printfn "Vehicle Information" printfn "-------------------" printfn "Tag #: %s" tag printfn "Make: %s" make printfn "Model: %s" model printfn "Year: %d\n" yr let suv = new Vehicle("183048", "Toyota", "Rav4", 2010)
This would produce:
Vehicle Information ------------------- Tag #: 183048 Make: Toyota Model: Rav4 Year: 2010 Press any key to continue . . .
Unlike a module, a namespace cannot contain variable declaration or direct call to functions. As a result, the following code will produce an error:
namespace CarDealer
type Vehicle(tag : string, make : string, model : string, yr : int) =
do
printfn "Vehicle Information"
printfn "-------------------"
printfn "Tag #: %s" tag
printfn "Make: %s" make
printfn "Model: %s" model
printfn "Year: %d\n" yr
let suv = new Vehicle("183048", "Toyota", "Rav4", 2010)
This means that a namespace is a good place to create and organize classes. In a document, you can create as many namespaces as you want. Unlike modules, the body of a namespace doesn't have to be indented. Here is an example of a document with two namespaces:
namespace CommercialBank type Employee = class end namespace VehicleDealership type Employee = class end type Customer = class end type Vehicle = class end
Nesting in a Namespace
One namespace can be nested in another namespace. Because all namespaces are created from the left side of the document, to indecate that a namespace is nested, you must qualify its name by indicating what its parent namespace(s) is (are). Here is an example:
namespace Mathematics namespace Mathematics.Algebra // The Algebra namespace is nested in the Mathematics namespace namespace Mathematics.Algebra.Elementary // The Elementary namespace is nested in the Algebra namespace that itself is nested in the Mathematics namespace namespace Mathematics.Algebra.Equations // The Equations namespace is nested in the Algebra namespace that itself is nested in the Mathematics namespace namespace Mathematics.Arithmetic // The Arithmetic namespace is nested in the Mathematics namespace
You can then add the members anyway you want. To start, remember that a namespace cannot contain declared variables and functions but it can contain enumerations and classes. Here are examples:
namespace Mathematics type Topics = // The Topics enumeration is defined, or is a member of, the Mathematics namespace | Quantity | Structure | Space | Other namespace Mathematics.Algebra // The Algebra namespace is nested in the Mathematics namespace namespace Mathematics.Algebra.Elementary // The Elementary namespace is nested in the Algebra namespace that itself is nested in the Mathematics namespace type Operator(o) = // The Operator class is a member of the Mathematics.Algebra.Elementary namespace class end namespace Mathematics.Algebra.Equations // The Equations namespace is nested in the Algebra namespace that itself is nested in the Mathematics namespace type Quadratic(a, b, c) = // The Quadratic class is defined, or is a member of, the Mathematics.Algebra.Equations namespace class end namespace Mathematics.Arithmetic // The Arithmetic namespace is nested in the Mathematics namespace type Number() = // The Number class is defined the Mathematics.Arithmetic namespace class end type Addition(a, b) = // The Addition class is defined the Mathematics.Arithmetic namespace class end
Besides classes (and enumerations and some others), a namespace can contain modules. Here are examples:
namespace Mathematics type Topics = // The Topics enumeration is defined, or is a member of, the Mathematics namespace | Quantity | Structure | Space | Other module Geometry = printfn "Geometry is the branch of mathematics that studies shapes, figures, and space." module Polygons = type Square() = member this.Describe() = printfn "A square is a quadrilateral with four equal sides and four equal angles of 90 degrees." type Triangle() = member this.Describe() = printfn "A triangle is a polygon that has three edges and three vertices." module Planes = type Circle(radius) = do printfn "A circle is a shape of all point that are at an equal distance from another point named the center." type Ellipse(largeRadius, smallRadius) = member this.Describe() = printfn "An ellipse is curved plane with two focal points." module Trigonometry = type Triangle() = member this.Describe() = printfn "A triangle is a plane shape from three leveled points." module Summary = printf "Triangular Polygon Definition: " let geo = Geometry.Polygons.Triangle() geo.Describe() printf "Trigonometric Triangle Definition: " let tri = Trigonometry.Triangle() tri.Describe() namespace Mathematics.Algebra // The Algebra namespace is nested in the Mathematics namespace namespace Mathematics.Algebra.Elementary // The Elementary namespace is nested in the Algebra namespace that itself is nested in the Mathematics namespace type Operator(o) = // The Operator class is a member of the Mathematics.Algebra.Elementary namespace class end namespace Mathematics.Algebra.Equations // The Equations namespace is nested in the Algebra namespace that itself is nested in the Mathematics namespace type Quadratic(a, b, c) = // The Quadratic class is defined, or is a member of, the Mathematics.Algebra.Equations namespace class end namespace Mathematics.Arithmetic // The Arithmetic namespace is nested in the Mathematics namespace type Number() = // The Number class is defined the Mathematics.Arithmetic namespace class end type Addition(a, b) = // The Addition class is defined the Mathematics.Arithmetic namespace class end
In fact, because a namespace cannot contain functions and variables, if you want to use them, you should (must) nest a module and create such code in that module.
To access a member of a namespace outside that namespace, you must fully qualify its name. Here are example:
module Geometry = printfn "Geometry is the branch of mathematics that studies shapes, figures, and space." module Polygons = type Square() = member this.Describe() = printfn "A square is a quadrilateral with four equal sides and four equal angles of 90 degrees." type Triangle() = member this.Describe() = printfn "A triangle is a polygon that has three edges and three vertices." module Planes = type Circle(radius) = do printfn "A circle is a shape of all point that are at an equal distance from another point named the center." type Ellipse(largeRadius, smallRadius) = member this.Describe() = printfn "An ellipse is curved plane with two focal points." module Trigonometry = type Triangle() = member this.Describe() = printfn "A triangle is a plane shape from three leveled points." module Summary = printf "Triangular Polygon Definition: " let geo = Geometry.Polygons.Triangle() geo.Describe() printf "Trigonometric Triangle Definition: " let tri = Trigonometry.Triangle() tri.Describe()
This would produce:
Geometry is the branch of mathematics that studies shapes, figures, and space. Triangular Polygon Definition: A triangle is a polygon that has three edges and three vertices. Trigonometric Triangle Definition: A triangle is a plane shape from three leveled points. Press any key to continue . . .
Referring to Members of a Namespace
Outside a namespace, to refer to (one of) its member(s), you must fully qualify the name of that member from its parent(s). From the above example, to access the Quadratic class, you start from the most top namespace followed by each child namespace. This would be:
Mathematics.Algebra.Equations.Quadratic
Here is an example of using a class that is a member of a namespace:
namespace Mathematics
namespace Mathematics.Algebra
namespace Mathematics.Algebra.Equations
type Quadratic(a, b, c) =
let mutable x = ""
let mutable y = ""
let mutable z = ""
do
if a < -1 then
x <- (string a) + "x^2"
elif a = -1 then
x <- "-x^2"
elif a = 0 then
x <- ""
elif a = 1 then
x <- "x^2"
elif a > 1 then
x <- (string a) + "x^2"
else
x <- (string a) + "x^2"
if b < -1 then
y <- "- " + (string (-1 * b)) + "x"
elif b = -1 then
y <- "- x"
elif b = 0 then
y <- ""
elif b = 1 then
y <- "+ x"
elif b > 1 then
y <- "+ " + (string b) + "x"
else
y <- "+ " + (string b) + "x"
if c < -1 then
z <- "- " + (string (-1 * c))
elif c = -1 then
z <- "- " + (string (-1 * c))
elif c = 0 then
z <- ""
else
z <- "+ " + (string (c))
member this.Equation with get() : string = (x + " " + y + " " + z + " = 0")
namespace ElementaryAlgebra
module Exercise =
let quad = Mathematics.Algebra.Equations.Quadratic(5, 1, -1) // (1, -3, 1) // (5, -3, 3) //(1, 2, -2);
printfn "Equation: %s" quad.Equation
This would produce:
quation: 5x^2 + x - 1 = 0 ress any key to continue . . .
The Name of a Namespace . . . Again
As seen so far, when accessing a namespace, you use its whole ancestry. In fact, when creating a namespace, you can specify a lineage that you anticipate would be essential. Here is an example:
namespace Chemistry.Compounds.Reactions
type Atom(a) =
class
end
After creating a namespace like this, you can access its members using the whole qualified name. Here is an example:
namespace Chemistry.Compounds.Reactions
type Atom(a) =
class
end
namespace Studies
module Research =
let t = Chemistry.Compounds.Reactions.Atom("O")
Based on this, you can specify a name of a namespace that includes various parts even if those parts don't exist. To resume, the name of a namespace can be in one word or it can include various parts separated by periods.
If you had created a name of a namespace and made it in different parts, if you want, somewhere else in the file, you can create namespaces that include some parts that were used in the original name. Here is an example:
namespace Chemistry.Compounds.Reactions
type Atom(a) =
class
end
namespace Chemistry.Compounds
type Substance(element1, element2) =
class
end
namespace Studies
module Research =
let t = Chemistry.Compounds.Reactions.Atom("O")
let c = Chemistry.Compounds.Substance("hydrogen", "helium")
|
|||
Previous | Copyright © 2014-2024, FunctionX | Monday 14 February 2022 | Next |
|