Home

Introduction

 

Fundamentals

 

Introduction

 

 

     
 
 

 

   
   
 

Previous Copyright © 2015 FunctionX Next

Home

F# Project Management: Moduless

   

Fundamentals of Modules

 

Introduction

Like a namespace, a module is a technique of creating a particular section of code, for any reason. This allows you to have different sections in the program. The goal of using modules is to create sections of code to use names that can be duplicated in different modules in the same program without danger for a name conflict.

There are various differences between modules and namespaces. To point out those differences, we will review the features we saw for namespaces.

Creating a Module

A module is primarily a section of code in a regular F# file. The formula to create a module is:

module module-name =
    [ begin ]
	body
    [ end ]

You start with the module keyword followed by a name. The name of the module follows the rules of names in F# but it should start with an uppercase letter. The name is followed by the = operator. Unlike a module, the creation of a namespace doesn't include the = sign.

The line of code after the name of the module is the body of the module. In it, you can put any of the types of code we have used so far.

Unlike namespaces, the body of a module must be indented. Here is an example:

open System
open System.Windows.Forms

module PercentageDecimal =
    let percentageConversions = new Form(Width = 340, Height = 140, Text = "Percentage Conversions")
    percentageConversions.Controls.Add(new Label(Left = 22, Top = 18, Width = 198, Height = 13,
                                                 Text = "Converting a Percentage to Decimal:"))
    percentageConversions.Controls.Add(new Label(Left = 23, Top = 47, Width = 37, Text = "Value:"))
    let txtValue1 = new TextBox(Left = 66, Top = 44, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtValue1
    percentageConversions.Controls.Add(new Label(Left = 122, Top = 47, Width = 27, Text = "% of"))
    let txtPercent = new TextBox(Left = 159, Top = 44, Width = 46, Text = "0")
    percentageConversions.Controls.Add txtPercent
    let btnPercentageToDecimal = new Button(Left = 211, Top = 42, Width = 35, Text = "=")
    percentageConversions.Controls.Add btnPercentageToDecimal
    let txtDecimalToPercentage = new TextBox(Left = 252, Top = 45, Width = 55)
    percentageConversions.Controls.Add txtDecimalToPercentage

    let btnPercentageToDecimalClick e =
        let value = float txtValue1.Text
        let percent = float txtPercent.Text

        let result = percent * value / 100.00
        let strResult = sprintf "%0.02f" result

        txtDecimalToPercentage.Text <- strResult
    btnPercentageToDecimal.Click.Add btnPercentageToDecimalClick

    let btnClose = new Button(Left = 232, Top = 75, Text = "Close")
    let btnCloseClick e = percentageConversions.Close()
    btnClose.Click.Add btnCloseClick
    percentageConversions.Controls.Add btnClose

    Application.Run percentageConversions

Here is an example of executing the program:

Creating a Module

Unlike a namespace, 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:

open System
open System.Windows.Forms

let convert a b = a * b / 100.00

module PercentageDecimal =
    let percentageConversions = new Form(Width = 340, Height = 140, Text = "Percentage Conversions")
    percentageConversions.Controls.Add(new Label(Left = 22, Top = 18, Width = 198, Height = 13,
                                                 Text = "Converting a Percentage to Decimal:"))
    percentageConversions.Controls.Add(new Label(Left = 23, Top = 47, Width = 37, Text = "Value:"))
    let txtValue = new TextBox(Left = 66, Top = 44, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtValue
    percentageConversions.Controls.Add(new Label(Left = 122, Top = 47, Width = 27, Text = "% of"))
    let txtPercent = new TextBox(Left = 159, Top = 44, Width = 46, Text = "0")
    percentageConversions.Controls.Add txtPercent
    let btnPercentageToDecimal = new Button(Left = 211, Top = 42, Width = 35, Text = "=")
    percentageConversions.Controls.Add btnPercentageToDecimal
    let txtDecimalToPercentage = new TextBox(Left = 252, Top = 45, Width = 55)
    percentageConversions.Controls.Add txtDecimalToPercentage

    let btnPercentageToDecimalClick e =
        let value = float txtValue.Text
        let percent = float txtPercent.Text

        let result = convert percent value
        let strResult = sprintf "%0.02f" result

        txtDecimalToPercentage.Text <- strResult
    btnPercentageToDecimal.Click.Add btnPercentageToDecimalClick

    let btnClose = new Button(Left = 232, Top = 75, Text = "Close")
    let btnCloseClick e = percentageConversions.Close()
    btnClose.Click.Add btnCloseClick
    percentageConversions.Controls.Add btnClose

    do Application.Run percentageConversions

The body of the module can start with the begin keyword in which case it must end with the end keyword. If you decide to include the body of the module between a beginning and ending lines, the begin and the end keywords must be indented from the level of the module keyword. Then the body section must be indented from the begin and end level. If you decide to omit the begin and end keywords, then the module's body must be indented from the level of the module keyword.

The Top-Level Module

There are two categories of modules. If you want the whole document of a file to belong to one and the same module, on the first line of code (without a comment), simply create the module and continue your code on the next line. This type is called a top-level module. Normally, when you create a file and type code in it, the compiler internally creates a default module and considers that all the code in the document belongs to that default module.

Creating Many Modules

Most of the time, you want a module if you need to create different sections of code in the same document. Therefore, inside the document, you can create as many modules as you want. Here is an example:

open System
open System.Windows.Forms

let percentageConversions = new Form(Width = 340, Height = 190, Text = "Percentage Conversions")

module PercentageDecimal =
    percentageConversions.Controls.Add(new Label(Left = 22, Top = 18, Width = 198, Height = 13, Text = "Converting a Percentage to Decimal:"))
    percentageConversions.Controls.Add(new Label(Left = 23, Top = 47, Width = 37, Text = "Value:"))
    let txtValue = new TextBox(Left = 66, Top = 44, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtValue
    percentageConversions.Controls.Add(new Label(Left = 122, Top = 47, Width = 27, Text = "% of"))
    let txtPercent = new TextBox(Left = 159, Top = 44, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtPercent
    let btnCalculate = new Button(Left = 211, Top = 42, Width = 35, Text = "=")
    percentageConversions.Controls.Add btnCalculate
    let txtResult = new TextBox(Left = 252, Top = 45, Width = 55, Text = "0.00")
    percentageConversions.Controls.Add txtResult
    percentageConversions.Controls.Add(new Label(Left = 3, Top = 72, Width = 322, Text = "---------------------------------------------------------------------------------"))

module DecimalPercentage =
    percentageConversions.Controls.Add(new Label(Left = 22, Top = 95, Width = 198, Height = 13, Text = "Converting a Decimal to Percentage:"))
    percentageConversions.Controls.Add(new Label(Left = 23, Top = 125, Width = 37, Text = "Value:"))
    let txtValue = new TextBox(Left = 66, Top = 122, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtValue
    percentageConversions.Controls.Add(new Label(Left = 122, Top = 45, Width = 27, Text = "% of"))
    let txtPercent = new TextBox(Left = 159, Top = 122, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtPercent
    let btnCalculate = new Button(Left = 118, Top = 120, Width = 35, Text = "=")
    percentageConversions.Controls.Add btnCalculate
    percentageConversions.Controls.Add(new Label(Left = 210, Top = 125, Width = 17, Text = "%"))

Notice that the modules have variables with the same names: txtValue, txtPercent, and btnCalculate. Because they belong to different sections, the modules make sure there is no name conflict.

Modules and a Multiple-File Project

As you may know already, a new project in Microsoft Visual Studio creates a default file named Program.cs. After the first file, you can add as many source files as you want. As mentioned for the namespace, every source file in the project must start with either a module or a namespace, except for the last file, which is usually the file that contains the Application.Run() method or the entry point of the application. Therefore:

Using Modules

 

Referring to Members of a Module

You can refer to a member of one module inside another module. In this case, you must qualify the name of the member from its parent module. To do this where needed, type the name of the module, followed by a period, and followed by the name of the member. Here are examples:

open System
open System.Windows.Forms

let convert a b = a * b / 100.00
let multiplyBy100 a = a * 100.00
let percentageConversions = new Form(Width = 340, Height = 190, Text = "Percentage Conversions")

module PercentageDecimal =    
    percentageConversions.Controls.Add(new Label(Left = 22, Top = 18, Width = 198, Height = 13, Text = "Converting a Percentage to Decimal:"))
    percentageConversions.Controls.Add(new Label(Left = 23, Top = 47, Width = 37, Text = "Value:"))
    let txtValue = new TextBox(Left = 66, Top = 44, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtValue
    percentageConversions.Controls.Add(new Label(Left = 122, Top = 47, Width = 27, Text = "% of"))
    let txtPercent = new TextBox(Left = 159, Top = 44, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtPercent
    let btnCalculate = new Button(Left = 211, Top = 42, Width = 35, Text = "=")
    percentageConversions.Controls.Add btnCalculate
    let txtResult = new TextBox(Left = 252, Top = 45, Width = 55, Text = "0.00")
    percentageConversions.Controls.Add txtResult

    percentageConversions.Controls.Add(new Label(Left = 3, Top = 72, Width = 322, Text = "---------------------------------------------------------------------------------"))

module DecimalPercentage =
    percentageConversions.Controls.Add(new Label(Left = 22, Top = 95, Width = 198, Height = 13, Text = "Converting a Decimal to Percentage:"))
    percentageConversions.Controls.Add(new Label(Left = 23, Top = 125, Width = 37, Text = "Value:"))
    let txtValue = new TextBox(Left = 66, Top = 122, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtValue
    percentageConversions.Controls.Add(new Label(Left = 122, Top = 45, Width = 27, Text = "% of"))
    let txtPercent = new TextBox(Left = 159, Top = 122, Width = 46, Text = "0.00")
    percentageConversions.Controls.Add txtPercent
    let btnCalculate = new Button(Left = 118, Top = 120, Width = 35, Text = "=")
    percentageConversions.Controls.Add btnCalculate
    percentageConversions.Controls.Add(new Label(Left = 210, Top = 125, Width = 17, Text = "%"))

let btnCalculateClicked e =
    let value = float PercentageDecimal.txtValue.Text
    let percent = float PercentageDecimal.txtPercent.Text

    let result = convert percent value
    let strResult = sprintf "%0.02f" result

    PercentageDecimal.txtResult.Text <- strResult
PercentageDecimal.btnCalculate.Click.Add btnCalculateClicked

let btnCalculateClicking e =
    let value = float DecimalPercentage.txtValue.Text

    let result = multiplyBy100 value
    let strResult = sprintf "%0.02f" result

    DecimalPercentage.txtPercent.Text <- strResult
DecimalPercentage.btnCalculate.Click.Add btnCalculateClicking

let btnClose = new Button(Left = 232, Top = 121, Text = "Close")
let btnCloseClick e = percentageConversions.Close()
btnClose.Click.Add btnCloseClick
percentageConversions.Controls.Add btnClose

do Application.Run percentageConversions

Here is an example of executing the program:

Using a Module

Nesting a Module

One module can be created in the body of another module. This is referred to as nesting a module. Here is an example:

module Geometry =

    let message = "Geometry is the branch of mathematics that studies shapes, figures, and space."

    module Polygons =
        type Square() =
            member this.Description =
                "A square is a quadrilateral with four equal sides and four equal angles of 90 degrees."

The outside module that contains the second module is referred to as nesting. The module inside of another is referred to as nested. Any of those modules can contain any type of member. In the same way, any module can contain its own modules.

To access a member of a module outside its parent, you must fully qualify its name. Here are example:

open System
open System.Windows.Forms

let percentageConversions = new Form(Width = 340, Height = 100, Text = "Triangular Polygon Definition")

module Geometry =
    let message = "Geometry is the branch of mathematics that studies shapes, figures, and space."
    
    module Polygons =
        type Square() =
            member this.Description = "A square is a quadrilateral with four equal sides and four equal angles of 90 degrees."
        type Triangle() =
            member this.Description = "A triangle is a polygon that has three edges and three vertices."
    module Planes =
        type Circle(radius) =
            member this.Description = "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.Description = "An ellipse is curved plane with two focal points."
module Trigonometry =
    type Triangle() =
        member this.Description = "A triangle is a plane shape from three leveled points."

module Summary =
    let geo = Geometry.Polygons.Triangle()
    percentageConversions.Controls.Add(new Label(Left = 12, Top = 18, Width = 400, Text = geo.Description))
    
    let tri = Trigonometry.Triangle()
    percentageConversions.Controls.Add(new Label(Left = 12, Top = 38, Width = 400, Text = tri.Description))

do Application.Run percentageConversions

This would produce:

Nesting a Module

Besides classes (and enumerations and some others), a namespace can contain modules. Here are examples:

namespace Mathematics

open System
open System.Windows.Forms

type Topics =
    | Quantity
    | Structure
    | Space
    | Other

type Exercise() =
    member this.Description = new Form(Width = 340, Height = 100, Text = "Triangular Polygon Definition")

module Geometry =
    let message = "Geometry is the branch of mathematics that studies shapes, figures, and space."
    
    module Polygons =
        type Square() =
            member this.Description = "A square is a quadrilateral with four equal sides and four equal angles of 90 degrees."
        type Triangle() =
            member this.Description = "A triangle is a polygon that has three edges and three vertices."
    module Planes =
        type Circle(radius) =
            member this.Description = "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.Description = "An ellipse is curved plane with two focal points."
module Trigonometry =
    type Triangle() =
        member this.Description = "A triangle is a plane shape from three leveled points."

module Summary =
    let exo = new Exercise()
    let geo = Geometry.Polygons.Triangle()
    exo.Description.Controls.Add(new Label(Left = 12, Top = 18, Width = 400, Text = geo.Description))
    
    let tri = Trigonometry.Triangle()
    exo.Description.Controls.Add(new Label(Left = 12, Top = 38, Width = 400, Text = tri.Description))
    
namespace Mathematics.Algebra
namespace Mathematics.Algebra.Elementary
    type Operator(o) =
        class
        end
namespace Mathematics.Algebra.Equations
    type Quadratic(a, b, c) =
        class
        end
namespace Mathematics.Arithmetic
    type Number() =
        class
        end
    type Addition(a, b) =
        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.

Fundamentals of Libraries

 

Introduction

A library is one or a collection of functions, one or a collection of classes, or combinations of functions and classes, that can be directly used in an application to ease up the developer job who would not have to create a sought behavior from scratch. The primary library used in Microsoft Windows is called Win32. It can be difficult or restrictive to use because you must know the C and/or C++ languages.

To make it easier to create application in Microsoft Windows, at one time the company created (or rather developed) a language named Visual Basic (from BASIC) and developed a huge library of functions for it. To make it possible to use other languages to create applications, Microsoft created another library called the .NET Framework. Like Win32, the .NET Framework is a collection of internal sub-libraries so that, at one time, you can pick the library you want to use, based on your needs.

The libraries in the .NET Framework (and in Microsoft Windows) are files with the .DLL extension. Those libraries contain namespaces that contain functions and classes.

In order to use an external library, you must import or load it. Since a library may contain many namespaces, you should know what particular namespace contains the functionality you want to use. Once you know that namespace, to indicate it in your code file, you use the open keyword. The formula to follow is:

open namespace-name;

If the namespace is the top, simply type its name. The semi-colon is optional. If you are using a namespace that is included in another namespace, type the full path of the namespace.

The (or most) languages used in the .NET Framework are meant to collaborate. This means that if a certain language, such as Visual Basic, includes some functions (and/or classes) in one of its own libraries, other .NET languages should be able to use those functions (and/or classes) and benefit from them.

External Libraries

Besides Win32 and the .NET Framework, there are other libraries on the market and some languages have their own libraries. Probably the most expanded of the .NET languages is Visual Basic. It includes an impressive library of functions. In addition to, or instead of, F# built-in functions, you can borrow functions from Visual Basic and use them as you see fit.

To use the functions of the Visual Basic language in an F# application, you must reference its library. Most (if not all) of the functions of Visual Basic are created in the Microsoft.VisualBasic.dll assembly but they might be in different namespaces.  To start, you can add its reference in your application. To do that, on the main menu of Microsoft Visual Studio, click project -> Add Reference, or in the Solution Explorer, right-click the name of the project and click Add -> References, or right-click References -> Add References:

Reference Manager

After doing this, you can call the desired Visual Basic function. The functions in the Visual Basic library are organized in classes. Since the functions exist as members of classes, they are treated as method. You must know the name of the class that contains the method you want to use.

To call a Visual Basic function, type Microsoft.VisualBasic. followed by the name of the class, followed by the name of the method, and use it appropriately. For example, there is a method used to display a message box, and it is called MsgBox. That method exists in a class named Interaction. The method returns a value (named MsgBoxResult) that you can use or ignore. Here is an example of calling the method:

open System
open System.Windows.Forms
open Microsoft.VisualBasic

let exercise = new Form(Text = "Exercise")

let btnDisplay = new Button(Left = 24, Top = 24, Text = "Close")
let btnDisplayClick e =
    Microsoft.VisualBasic.Interaction.MsgBox("Welcome to the wonderful world of F# programming",
                                             MsgBoxStyle.OkOnly ||| MsgBoxStyle.Information,
                                             "F# Application Programming") |> ignore

exercise.Controls.Add btnDisplay
btnDisplay.Click.Add btnDisplayClick

do Application.Run exercise

F# Custom Libraries

   

Introduction

As we have seen and we will see in other lessons, the F# language provides various libraries with many functions. If those functions are not enough, you can create your own library with the desired functions and/or classes.

To create a custom library, display the New Project dialog box of Microsoft Visual Studio. In the left list , select Visual F#. In the middle list, click Library. Give a name to the new project:

Reference Manager

Once you are ready, click OK. A new file with a default name as Library1.fs is created for you. You can keep that name or you can change it. If you want to change it, in the Solution Explorer, right-click the name of the file and click Rename. Give the desired name with the .fs extension and press Enter.

If you had started from another type of project or you selected something other than Library in the New Project dialog box but you want to create a library, open the properties of the project (Project -> Project-Name Properties)... In the Output Type combo box, select Class Library:

Properties

In the file, create the functionality you want. For example, you can create classes or functions. Here is an example:

namespace Arithmetic

type Calculation(x : double, y : double) =
    member this.Addition()       : double = x + y
    member this.Subtraction()    : double = x - y
    member this.Multiplication() : double = x * y
    member this.Division()       : double = if y <> 0.00 then x / y else 0.00

To actually create the library, on the main menu, click Build -> Build Solution. This would create a file that has the name of the F# file you created and the .dll extension:

Properties

To use the library, start a project. To add a reference to your library, on the main menu, click Project -> Add Reference... or in the Solution Explorer, right-click References and click Add Reference... In the Reference Manager, click the Browse button. Locate the folder of the project that has the DLL file:

Properties

Click the DLL file and click Add. On the Reference Manager dialog box, click OK. In your file, add a reference to the namespace that contains the code of the library. In your code, access the class from the library and us it as you see fit. Here is an example:

open System
open Arithmetic
open System.Windows.Forms

let exercise = new Form(Text = "Arithmentic", Height = 255, Width = 215)

let lblOperand1 = new Label(Left = 22, Top = 21, Width = 65, Text = "Operand 1:")
exercise.Controls.Add lblOperand1

let txtOperand1 = new TextBox(Left = 108, Top = 16, Text = "0.00", Width = 75)
exercise.Controls.Add txtOperand1

let lblOperand2 = new Label(Left = 22, Top = 45, Width = 65, Text = "Operand 2:")
exercise.Controls.Add lblOperand2

let txtOperand2 = new TextBox(Left = 108, Top = 42, Text = "0.00", Width = 75)
exercise.Controls.Add txtOperand2

let btnOperate = new Button(Left = 108, Top = 70, Text = "Operate", Width = 75)
exercise.Controls.Add btnOperate

let lblAddition = new Label(Left = 22, Top = 105, Width = 65, Text = "Addition:")
exercise.Controls.Add lblAddition

let txtAddition = new TextBox(Left = 108, Top = 103, Text = "0.00", Width = 75)
exercise.Controls.Add txtAddition

let lblSubtraction = new Label(Left = 22, Top = 134, Width = 75, Text = "Subtraction:")
exercise.Controls.Add lblSubtraction

let txtSubtraction = new TextBox(Left = 108, Top = 131, Text = "0.00", Width = 75)
exercise.Controls.Add txtSubtraction

let lblMultiplication = new Label(Left = 22, Top = 160, Width = 75, Text = "Multiplication:")
exercise.Controls.Add lblMultiplication

let txtMultiplication = new TextBox(Left = 108, Top = 159, Text = "0.00", Width = 75)
exercise.Controls.Add txtMultiplication

let lblDivision = new Label(Left = 22, Top = 190, Width = 65, Text = "Division:")
exercise.Controls.Add lblDivision

let txtDivision = new TextBox(Left = 108, Top = 187, Text = "0.00", Width = 75)
exercise.Controls.Add txtDivision

let btnOperateClick e =
    let operand1 = float txtOperand1.Text
    let operand2 = float txtOperand2.Text

    let operation      = new Calculation(operand1, operand2)
    let addition       = operation.Addition()
    let subtraction    = operation.Subtraction()
    let multiplication = operation.Multiplication()
    let division       = operation.Division()

    txtAddition.Text       <- sprintf "%0.02f" addition
    txtSubtraction.Text    <- sprintf "%0.02f" subtraction
    txtMultiplication.Text <- sprintf "%0.07f" multiplication
    txtDivision.Text       <- sprintf "%0.07f" division
btnOperate.Click.Add btnOperateClick
do Application.Run exercise

Here are examples of running the program:

Creating an F# Custom Library Creating an F# Custom Library

Overview of the .NET Framework

The .NET Framework is a huge library of classes. As mentioned already, each library, also called an assembly, has the extension .DLL and includes one or more namespaces. The top level namespace is called System. Whenever you want to use it, include it on top of your file. Here are examples:

open System

The System namespace is very huge with its hundreds of classes.


Home Copyright © 2014-2015 FunctionX Home