Standard ML - SML

A general purpose, modular, function programming language

Created by Susan Lunn / github

What is functional?

A matter of state.

State

The manipulation of memory and the storage of data

 
public class Person {   
    private String firstName;
    private String lastName;
    private String address;   
    private String username; 
    public Person(String personFirstname, String personLastName, String personAddress, String personUsername) { 
        firstName = personFirstName;
        lastName = personLastName;
        address = personAddress;     
        username = personUsername;  
    }    
    // A method to display the state of the object to the screen   
    public void displayPersonDetails() {
        System.out.println("Name: " + firstName + " " + lastName);
        System.out.println("Address: " + address);
        System.out.println("Username: " + username);  
    } 
} 

Computation in ML

Focus is on evaluation of expressions instead of execution of commands
This is how functional differs from imperative.

“The idea of computation is as a generalization of your experience from high school algebra in which you are given a polynomial in a variable x and are asked to calculate its value at a given value of x. ”

Euclidean Algorithm aka GCD

Euclidean's algorithm is definied as such:

gcd(0,n) = n
gcd(m, n)= gcd(n mod m, m)          m > 0
                
Implemented in ML it reads as:

fun gcd (0,n) = n 
    | gcd (m,n) = gcd (n mod m, m) 
                

Imperative implementation


public static int gcd(int n, int m) //valid for positive integers.
{
    while(n > 0)
    {
        int z = n % m;
        n = m;
        m = z;
    }
    return a;
}
                

More about ML

ML is typesafe

ML is statically typed

ML supports polymorphic type inference AKA Principle Typing Property of ML

“A value is polymorphic if there is more than one type it can have. ”

    fn s:string => s ˆ "\n"
                

    fn s => s ˆ "\n"
                

Let's break down a function


val rec factorial : int->int =
    fn 0 => 1 | n:int => n * factorial (n-1)
                

Function expression


val rec factorial : int->int =
                
Why do you need to recursively define it? Is there syntatic sugar for this? Yes!

fun factorial 0 = 1
  | factorial (n:int) = n * factorial (n-1)
                

Function body


fn 0 => 1 | n:int => n * factorial (n-1)
                

How is ML different from Haskell?

Interaction with IO

  • Non-monadic
  • 
    print "Enter a string: ";
    let val str = valOf (TextIO.inputLine TextIO.stdIn) in (* note: this keeps the trailing newline *)
      print "Enter an integer: ";
      let val num = valOf (TextIO.scanStream (Int.scan StringCvt.DEC) TextIO.stdIn) in
        print (str ^ Int.toString num ^ "\n")
      end
    end 
                    

    Non-lazy evaluation by default

    Functions in ML are bound by value. Some people call ML an eager language for this reason. It evaluates expressions regardless of whether or not they are used.
    You can get around this, however! Bind values by name rather than expression.
    
                   Compiler.Control.lazysml := true;
                   open Lazy;
                    

    THE END