locked
F# Data Types RRS feed

  • Question

  • hi all,

    what data types categories F# typing system support?

    is it like C# data type system?
    Value types
    Reference types
    Pointer types
    Saturday, July 28, 2012 8:52 PM

Answers

  • A ref cell is an instance of the type Microsoft.FSharp.Core.FSharpRef<T>

    The type FSharpRef<T> is a reference type (i.e. it does not have copy-by-value semantics)

    Result - reference cells are storage locations that enable you to create mutable values with reference semantics i.e. while an int has copy-by-value semantics, a ref int doesn't.  In general, should you define a MyHugeStruct with vast amounts of data inside, a ref MyHugeStruct could be passed as an argument without that data having to be copied.

    That difference aside (since most things are reference types), they are otherwise just an alternative to declaring a mutable, with slightly different punctuation.

    let x = ref 23
    printfn "x is %A" !x
    x := 42
    printfn "x is %A" !x
    
    let mutable y = 23
    printfn "y is %A" y
    y <- 42
    printfn "y is %A" y




    • Marked as answer by Rainmater Tuesday, July 31, 2012 1:12 AM
    Sunday, July 29, 2012 7:24 AM
  • Let's do this step by step until the important point is reached...

    > let mutable x = 10;;
    
    val mutable x : int = 10

    so we have x, a value type.  Then we initialize y using it

    > let y = ref x;;
    
    val y : int ref = {contents = 10;}

    At this point x's copy-by=value semantics have cut in, so y now contains an int which has the current value of x.

    • Marked as answer by Rainmater Tuesday, July 31, 2012 1:13 AM
    Sunday, July 29, 2012 5:23 PM
  • As they both compile to the same IL running on the same virtual machine, the answer should be fairly obvious.

    Most things are reference types.

    Value types are surfaced as F# structures

    Pointers are represented by the Microsoft.FSharp.NativeInterop.nativeptr<'a> type.

    • Marked as answer by Rainmater Tuesday, July 31, 2012 1:12 AM
    Saturday, July 28, 2012 10:00 PM

All replies

  • As they both compile to the same IL running on the same virtual machine, the answer should be fairly obvious.

    Most things are reference types.

    Value types are surfaced as F# structures

    Pointers are represented by the Microsoft.FSharp.NativeInterop.nativeptr<'a> type.

    • Marked as answer by Rainmater Tuesday, July 31, 2012 1:12 AM
    Saturday, July 28, 2012 10:00 PM
  • i see a note in msdn docs that say:

    Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not related.

    my questions is: 

    1) are Reference Cells in F# related to "reference types" or "passing by reference"?

    2) what is a reference cells?

    3) when we must use reference cells?

    thanks,



    • Edited by Rainmater Saturday, July 28, 2012 11:31 PM
    Saturday, July 28, 2012 10:50 PM
  • 1) According to MSDN, reference cells are instances of the Ref generic record type, which is declared as follows:

    type Ref<'a> =
        { mutable contents: 'a }

    2)  A reference type contains a pointer to another memory location that holds the data.

    Value types hold the data within its own memory allocation.

    3) It is too general question. For example in .NET String is a reference type so whenever you are using strings you are using reference types.


    Petr

    Saturday, July 28, 2012 11:13 PM
  • A ref cell can be thought of as a 1-element array with special syntactic sugar for getting and setting that element.  The thing you have hold of indirects to the value it stores.

    The main difference between value and reference types is that value types follow copy-by-value semantics.  You use reference types when the type you are using doesn't have value semantics like that.

    Saturday, July 28, 2012 11:25 PM
  • im sorry, my mean was reference cell. sorry again
    Saturday, July 28, 2012 11:30 PM
  • F# behaves just like C#. With a reference type, it works with a reference to an instance in the heap, and with a value type (built-in, declared in C# or declared in F# using Struct attribute), the value is copied when you assign it to another value or pass as argument.
    The only notable difference is that standard F# types have structural equality semantics. This means that they are compared by comparing the actual value stored in them and not by comparing their references (even if they are reference types).



    If this post answers your question, please click Mark As Answer. If this post is helpful please click Mark as Helpful.

    Regards,
    Nair S

    Saturday, July 28, 2012 11:31 PM
  • I'm confused.

    i know what is reference types and how to passing arguments  by reference in C#.

    but i I do not understand Concept of reference cells in F#.

    references cells are reference type?

    some one help me.

    Sunday, July 29, 2012 12:04 AM
  • A ref cell is an instance of the type Microsoft.FSharp.Core.FSharpRef<T>

    The type FSharpRef<T> is a reference type (i.e. it does not have copy-by-value semantics)

    Result - reference cells are storage locations that enable you to create mutable values with reference semantics i.e. while an int has copy-by-value semantics, a ref int doesn't.  In general, should you define a MyHugeStruct with vast amounts of data inside, a ref MyHugeStruct could be passed as an argument without that data having to be copied.

    That difference aside (since most things are reference types), they are otherwise just an alternative to declaring a mutable, with slightly different punctuation.

    let x = ref 23
    printfn "x is %A" !x
    x := 42
    printfn "x is %A" !x
    
    let mutable y = 23
    printfn "y is %A" y
    y <- 42
    printfn "y is %A" y




    • Marked as answer by Rainmater Tuesday, July 31, 2012 1:12 AM
    Sunday, July 29, 2012 7:24 AM
  • you say that reference cells is a reference that dose not have copy-by-value semantics.

    see this example:

    let mutable x = 10 let y = ref x x <- 15 printfn "x: %d" x printfn "y: %d" !y

    //output

    x: 15

    y: 10


    if  "y" is a reference cells, why its value is "10" in this example?

    it must be "15".


    • Edited by Rainmater Sunday, July 29, 2012 4:57 PM
    Sunday, July 29, 2012 4:54 PM
  • Let's do this step by step until the important point is reached...

    > let mutable x = 10;;
    
    val mutable x : int = 10

    so we have x, a value type.  Then we initialize y using it

    > let y = ref x;;
    
    val y : int ref = {contents = 10;}

    At this point x's copy-by=value semantics have cut in, so y now contains an int which has the current value of x.

    • Marked as answer by Rainmater Tuesday, July 31, 2012 1:13 AM
    Sunday, July 29, 2012 5:23 PM
  • its mean that reference cell are not real reference? (A reference cell holds an actual value; it is not just an address.)

    reference cells have behavior like other mutable value types? is it true?

    if we want to have an address reference only, what we must to do?(my mean is that in previous example, value of "y" refer to address of "x")

    Sunday, July 29, 2012 9:18 PM
  • This how the FSharpRef<T> type is implemented

    	public sealed class FSharpRef<T> : // lots of interfaces omitted
    	{
    		public T contents@;
    		
    		public T contents
    		{
    			get
    			{
    				return this.contents@;
    			}
    			set
    			{
    				this.contents@ = value;
    			}
    		}
    		public T Value
    		{
    			get
    			{
    				return this.contents@;
    			}
    			set
    			{
    				this.contents = value;
    			}
    		}
    		public FSharpRef(T contents)
    		{
    			this.contents@ = contents;
    		}
    		// interface implementations omitted
    	)

    When it is constructed, the assignment has to follow the behaviour of the contained type, so will be a value copy of a value type.

    Perhaps you are looking for byref or the & operator.


    • Edited by Mr. Tines Sunday, July 29, 2012 10:32 PM Added link to Parameters and Arguments (F#) at http://msdn.microsoft.com/en-us/library/dd233213.aspx
    Sunday, July 29, 2012 10:14 PM
  • thank you for your response.

    i have two another questions:

    1): what is F# converted code of below example:(PHP)

    $x = 10;

    $y = &$x;

    $x = 15

    // now value of x , y are 15

    2) what is difference between two below codes:(if possible  describe it by an example please.)

    let mutable x = ref 10 let mutable y = x let mutable z = y

    //val mutable x : int ref = {contents = 10;}
    //val mutable y : int ref = {contents = 10;}
    //val mutable z : int ref = {contents = 10;}

    and

    let mutable x = ref 10
    let mutable y = ref x
    let mutable z = ref y
    
    //val mutable x : int ref = {contents = 10;}
    //val mutable y : int ref ref = {contents = {contents = 10;};}
    //val mutable z : int ref ref ref = {contents = {contents = {contents = 10;};};}

    thank u again.


    • Edited by Rainmater Tuesday, July 31, 2012 1:11 AM
    Sunday, July 29, 2012 10:43 PM
  • 1) Did you mean $x = 15 in your PHP?  To get that sort of behaviour, you ensure that everything is a reference type at the point of initialisation, and use assignment directly because everything has reference semantics already.

    > let x = ref 10;; val x : int ref = {contents = 10;} > let y = x;; val y : int ref = {contents = 10;} > x := 15;; val it : unit = () > (x, y);; val it : int ref * int ref = ({contents = 15;}, {contents = 15;})

    Seriously, PHP is such a lax language that it is not a good guide to anything else.  If you have a background in PHP you'll find you have to spend a lot of time unlearning the sort of coding patterns it encourages when making the transition to a very precise language like F#.

    2) In each case, you are getting exactly what you asked for.

    Writing

    let identifier = ref value

    is equivalent to the C#

    var identifier = new FSharpRef(value);

    Decompiling the first code to C# we get

    	FSharpRef<int> x = Operators.Ref<int>(10);
    	FSharpRef<int> y = x;
    	FSharpRef<int> z = y;
    

    i.e. x, y and z all refer to the same object of type FSharpRef<int>

    The C# equivalent of the second code is

    	FSharpRef<int> x = Operators.Ref<int>(10);
    	FSharpRef<FSharpRef<int>> y = Operators.Ref<FSharpRef<int>>(x);
    	FSharpRef<FSharpRef<FSharpRef<int>>> z = Operators.Ref<FSharpRef<FSharpRef<int>>>(y);
    
    // where in each case
    
    public static FSharpRef<T> Ref<T>(T value)
    {
    	return new FSharpRef<T>(value);
    }

    i.e. x is an FSharpRef<int>, y is an FSharpRef<FSharpRef<int>> whose content is x, and z is an FSharpRef<FSharpRef<FSharpRef<int>>> whose content is y.



    Monday, July 30, 2012 6:57 AM