1

In the book "Expert F# 3.0", there is a text-parsing example to 'lex' and 'parse' polynomial expressions. I was trying to understand it a bit (there was no explanation for the code written) and I came across functions such as this:

let parseIndex src =
    match tryToken src with
        | Some(Hat,src) ->
            match tryToken src with
            | Some(Int num,src) -> (num,src)
            | _ -> failwith "expected an int after ^"
        | _ -> (1,src)

which uses the function

let tryToken (src:TokenStream) = 
    match src with 
    | head::rest -> Some(head, rest)
    | _ -> None

the function parseIndex uses the parameter src and as the code progresses by using tryToken multiple times,every time, the returned src is somehow something else but the function still uses that name!

my question is: what is parseIndex really doing here with src? because on the second pattern-matching, it uses src as if it was a deffirent value given by tryToken, but looking at tryToken, I see that it should give the same result on every use with pattern-matching.

the Hat and Int you see are union cases of Token, as type TokenStream = Token list

Zaid Ajaj
  • 680
  • 8
  • 16

2 Answers2

2

As Daniel says, this is called shadowing.

It's actually really useful in many situations; imagine this C# function:

public void DoStuff(string s)
{
    var trimmed = s.Trim();

    // For the rest of this function, we should use trimmed, but s is
    // sadly still in scope :( 
}

Shadowing can fix this issue by hiding the original variable:

let DoStuff s =
    let s = s.Trim()
    // Only one 's' is in scope here, and it's trimmed
Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275
1

Later bindings shadow, or hide, earlier bindings. You can bind x as many times as you like:

let x = 1
let x = 2
let x = 3
...

The remainder of the scope will only see the last one.

Daniel
  • 47,404
  • 11
  • 101
  • 179
  • so when you use x, you get the last bound value to x? but src is not being rebound! – Zaid Ajaj Oct 28 '13 at 22:17
  • @ZaidAjaj : It is in the match pattern. – ildjarn Oct 28 '13 at 22:21
  • Sorry, I stated that incorrectly (fixed). Shadowing is *per scope*. It's not rebinding prior values but hiding them. Once you leave the inner scope, the outer `src` is visible again. – Daniel Oct 28 '13 at 22:21
  • @ZaidAjaj: [This question](http://stackoverflow.com/q/2478079/162396) has some useful examples. – Daniel Oct 28 '13 at 22:23
  • so by the second pattern-matching, are we using src given from Some(Hat,src) or from the parameter of the function? – Zaid Ajaj Oct 28 '13 at 22:24
  • 1
    You are using the last definition visible from that scope (so, from the pattern match). – Daniel Oct 28 '13 at 22:25
  • @Daniel thanks man, the examples were indeed helpful, i changed the names to src1 and src2 and now it's a bit more readable! – Zaid Ajaj Oct 28 '13 at 22:36
  • 2
    @ZaidAjaj In cases like this shadowing is sometimes used to intentionally hide previous values which should only be used in the outer scope. In this example, hiding the origional `src` binding prevents it from being used in the inner scope. – N_A Oct 29 '13 at 00:50