Skip to content

Latest commit

 

History

History
170 lines (116 loc) · 6.21 KB

Records, Pattern Matching, Functions.md

File metadata and controls

170 lines (116 loc) · 6.21 KB

Accessing Records with Pattern Matching

Note

the separation is with “ ; ” and not “, ” comma

type person = {given:string; sur:string ; age:int}
let paul = {given="Paul",sur="Meier",age=24}
let {given=x;sur = y; age = z} = paul

Output will be val x : string = “Paul” val y : string = “Meier” val z : int = 24

When We Are not Interested in All Fields:

let {given = x ; _ } = paul

Pattern Matching on Lists

match l 
with [] -> -1
| x::xs -> x;;
(* -: int = 1 *)```


#### **Mutually Recursive** Functions

When functions call each other, they are known as mutually recursive. OCaml supports this through the use of the `and` keyword to tie the recursive functions together:

```ocaml
let rec even n = if n=0 then "even"else odd (n-1)
and odd n = if n=0 then "odd" else even (n-1);;

In this example:

  • even checks if a number is even by recursively calling odd with n-1.
  • odd checks if a number is odd by recursively calling even with n-1.

Both functions alternate calls to each other until they reach the base case of checking 0, returning "even" or "odd" accordingly.


Simplified Syntax with function Keyword

Note

The function keyword in OCaml is a syntactic sugar that makes defining functions with a single parameter, typically used in pattern matching, more concise. Let’s expand on your examples to illustrate how this simplifies code.

let rec length = fun l -> match l with
| [] -> 0
| x::xs -> 1 + length xs;;

this can be simplified with function as it takes the argument as one keyword already:

let rec length = function
| [] -> 0
| x::xs -> 1 + length xs;;

When to Use Fun, Let or Function

Understanding when to use fun and when to use match with let in OCaml can initially be confusing, but each serves specific purposes and contexts, enhancing the flexibility and clarity of your code. Here's a breakdown of each and scenarios where you might choose one over the other:

1. Using fun

The fun keyword is used to define anonymous functions in OCaml. It's particularly useful in situations where:

  • You need a quick, inline function that doesn't require naming. For example, passing a small function as an argument to higher-order functions like List.map or List.fold.

  • You want to create partial functions or curried functions without explicitly dealing with multiple arguments upfront. For instance, defining functions that return other functions based on some conditions.

Example of using fun:

List.map (fun x -> x + 1) [1; 2; 3];;

This creates an anonymous function that adds 1 to each element of the list.

2. Using match with let

match is used for pattern matching, which is a way to deconstruct and analyse data structures based on their shape. When combined with let (especially in a function definition), it's powerful for:

  • Handling multiple cases or patterns in data, especially when working with variants or lists. It's useful for writing functions that need to distinguish between different types of input.

  • Recursive function definitions where each recursive call depends on the structure of the input, such as parsing trees, traversing linked lists, etc.

Example of using match with let:

let rec find_max = function
| [] -> raise (Failure "empty list")
| [x] -> x
| x :: xs -> max x (find_max xs);;

This function uses match within a let to recursively find the maximum in a list.

3. Using function

The function keyword is a shorthand for defining a function with a single argument that immediately uses match. It's a concise way to handle functions that:

  • Directly deconstruct their input without needing to refer to the input explicitly by name.

  • Are defined primarily or solely for pattern matching on a single argument.

Example of using function:

let rec length = function
| [] -> 0
| _ :: xs -> 1 + length xs;;

This function automatically matches on its argument to calculate the length of a list.

When to Choose Each

  • Use fun when you need anonymous functions, especially for small local uses or when you want to return a function from another function.

  • Use match with let when your function needs to handle complex patterns or multiple cases, especially when dealing with data types that require explicit case handling, like lists or custom types.

  • Use function for a cleaner, more direct syntax when your entire function revolves around pattern matching on a single argument.

By choosing the appropriate construct based on these guidelines, you can make your OCaml code more readable and maintainable.


Scope of Variable

let calculate_series n =
  let rec factorial x = 
    if x <= 1 then 1 else x * factorial (x - 1)
  in
  let rec sum_series i acc =
    if i > n then acc
    else
      let term = float_of_int (factorial i) /. float_of_int (i + 1)
      in
      sum_series (i + 1) (acc +. term)
  in
  sum_series 1 0.0;;

Note

The use of sum_series (i+1) (acc +. term) is used for the recursive call of the function Where as the use of sum_series 1 0.0 is to initiate the recursion

Function Tail Calls

Note

What is a Tail Call? A tail call occurs when a function call is the last operation a function performs before returning its result, and no additional work is needed after the function call returns. In such cases, there's no need to keep the current function's stack frame around, as there are no further computations that depend on it. This allows for an optimisation called tail call elimination or tail call optimisation (TCO), where the program can reuse the stack frame for the called function rather than creating a new one, essentially converting what would be recursive calls into a simple loop under the hood.

![[CleanShot 2024-06-25 at 21.44.33.png]]

  • Tail-recursive functions can be executed as efficiently as loops in imperative languages.
  • The intermediate results are handed from one recursive call to the next in accumulating parameters.
  • From that, a stopping rule computes the result.
  • Tail-recursive functions are particularly popular for list processing ...