Bug 18807 - Incorrect tuple equality for iOS simulator and device when using '=' in F#
Summary: Incorrect tuple equality for iOS simulator and device when using '=' in F#
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 7.2.0
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-04-03 22:40 UTC by trekfortytwo
Modified: 2015-04-10 05:55 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
TestProject (19.03 KB, application/zip)
2014-04-04 05:10 UTC, Sadik Ali
Details
Attached Project to reproduce this issue (5.86 KB, application/zip)
2014-04-07 10:27 UTC, Sadik Ali
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description trekfortytwo 2014-04-03 22:40:24 UTC
In F#, tuples and arrays use structural equality, therefore
the following program should print "equals":

/// Generate a tuple whose elements are arrays
let makeTuple x = [|x|], [|x|]

let a = makeTuple 1  // a is [|1|], [|1|]
let b = makeTuple 1  // b is the same as a.

if a = b then
  printfn "equals."  // this happens when running in MacOSX as consoles application.
else
  printfn "wrong!"   // this happens in iOS simulator and iOS real device.


Monotouch: 7.2.0, 7.2.1.31
MacOSX: 10.9.2, 10.8.4
Xamarin: 4.2.3 (build 60), 4.3.4 (build 0)

(Just some naive guess… this might have something to do with the fact 
that F#'s array uses structural equality while .NET array
uses referential equality. F# bypasses .NET array equality by providing a 
System.Collection.IComparer to IStructuralEquality.Equals(): 
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/prim-types.fs#L1504
which might be lost in Monotouch/AOT?)

thanks!
Comment 1 Sadik Ali 2014-04-04 05:06:11 UTC
I have checked this issue and unable reproduce this issue. I have implemented code mentioned in bug description.

Screen cast: http://screencast.com/t/dlLWnHxJR

Build Info:

=== Xamarin Studio ===
Version 4.2.3 (build 60)
Installation UUID: ce3f5199-e126-42fd-bc8a-6a96370af9ab
Runtime:
	Mono 3.2.7 ((no/40f92d5)
	GTK+ 2.24.23 theme: Raleigh
	GTK# (2.12.0.0)
	Package version: 302070000

=== Xamarin.iOS ===
Version: 7.2.0.2, 7.2.1.31
Hash: 58c3efa
Branch: 
Build date: 2014-10-03 18:02:26-0400

=== Build Information ===
Release ID: 402030060
Git revision: 30c4afc300c2a39ec5300851357ce02e49dd217e
Xamarin addins: f8a9589b57c2bfab2ccd73c880e7ad81e3ecf044

=== Operating System ===
Mac OS X 10.9.2
Comment 2 Sadik Ali 2014-04-04 05:10:33 UTC
Created attachment 6494 [details]
TestProject

I have attached test project, please look into this and suggest me if missing any thing in the code to reproduce this issue.
Comment 3 trekfortytwo 2014-04-04 10:45:28 UTC
Thanks for looking at this! Sorry I simplified the code in the bug and the problem wasn't showing up -- my bad. The following code produces the bug (using F# Empty Project):

module bug18807

open System
open MonoTouch.UIKit
open MonoTouch.Foundation

let makeTuple x = [|x|], [|x|]

let compare (f: int -> 'T): bool =
  let a = f 1
  let b = f 1
  a = b

[<Register ("AppDelegate")>]
type AppDelegate () =
    inherit UIApplicationDelegate ()

    let window = new UIWindow (UIScreen.MainScreen.Bounds)

    let sumPlus x =
      if compare makeTuple then 
        printfn "ok"
      else
        printfn "wrong"

    // This method is invoked when the application is ready to run.
    override this.FinishedLaunching (app, options) =
        // If you have defined a root view controller, set it here:
        // window.RootViewController <- new MyViewController ()
        window.MakeKeyAndVisible ()
        sumPlus ()
        true

module Main =
    [<EntryPoint>]
    let main args =
        UIApplication.Main (args, null, "AppDelegate")
        0


=== Output ===

Starting iPad simulator 7.1
Launching application
Application launched. PID = 368
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Core.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.dll [External]
Thread started:  #2
Loaded assembly: /Volumes/untitled/tests/bug18807/bug18807/bin/iPhoneSimulator/Debug/bug18807.exe
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/FSharp.Core.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll [External]
2014-04-04 10:34:45.159 bug18807[368:70b] wrong
2014-04-04 10:34:45.162 bug18807[368:70b] Application windows are expected to have a root view controller at the end of application launch

(OS: 10.9.2, Xamarin.iOS: 7.2.0.2)

"mono --version" gives "mono JIT compiler version 3.2.6 ((no/9b58377 Thu Jan 16 17:49:56 EST 2014)"
Comment 4 trekfortytwo 2014-04-04 11:05:24 UTC
The following code contains the previous case and a new examples, all produce the bug: 

(1) case1: the same as previous one, but uses 1 instead of () for tuple element
(2) case2: avoid using generic function, just compare plain arrays that contain tuple.

I also printfn the values to make the output clearer.

==== code ====

module bug18807

open System
open MonoTouch.UIKit
open MonoTouch.Foundation

let makeTuple x = [|x|], [|x|]

// Case 1: passing a function to a generic compare function.
let compare1 (f: int -> 'T): bool =
  let a = f 1
  let b = f 1
  printfn "a: %A, b: %A" a b
  a = b

// Case 2: no generic function involved: 
// Put tuple of arrays into arrays, and the comparison failed.
let compare2 (x: int): bool =
  let a = [| [|x|], [|x|] |]
  let b = [| [|x|], [|x|] |]
  printfn "a: %A, b: %A" a b
  a = b

[<Register ("AppDelegate")>]
type AppDelegate () =
    inherit UIApplicationDelegate ()

    let window = new UIWindow (UIScreen.MainScreen.Bounds)

    // This method is invoked when the application is ready to run.
    override this.FinishedLaunching (app, options) =
        // If you have defined a root view controller, set it here:
        // window.RootViewController <- new MyViewController ()
        window.MakeKeyAndVisible ()

        printfn "compare1: %A" (compare1 makeTuple)
        printfn "compare2: %A" (compare2 1)

        true

module Main =
    [<EntryPoint>]
    let main args =
        UIApplication.Main (args, null, "AppDelegate")
        0

===== Output ======

Starting iPad simulator 7.1
Launching application
Application launched. PID = 2003
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Core.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.dll [External]
Thread started:  #2
Loaded assembly: /Volumes/untitled/tests/bug18807/bug18807/bin/iPhoneSimulator/Debug/bug18807.exe
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/FSharp.Core.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll [External]
2014-04-04 11:02:56.774 bug18807[2003:70b] a: ([|1|], [|1|]), b: ([|1|], [|1|])
2014-04-04 11:02:56.777 bug18807[2003:70b] compare1: false
2014-04-04 11:02:56.779 bug18807[2003:70b] a: [|([|1|], [|1|])|], b: [|([|1|], [|1|])|]
2014-04-04 11:02:56.803 bug18807[2003:70b] compare2: false
2014-04-04 11:02:56.804 bug18807[2003:70b] Application windows are expected to have a root view controller at the end of application launch
Comment 5 Sadik Ali 2014-04-07 10:04:09 UTC
We have checked this issue and with the help of "Comment3" and "Comment4" We are able to reproduce this issue.

Steps to reproduce:

1.Create an "F#" iOS "Empty project".
2.Copy the following code into the "AppDelegate.fs" file.
3.Build/Debug the project.
4.Check the value of variable "Compare1" and "Compare2" in "Application Output".

Screen cast: http://screencast.com/t/94ayWZk0P

Environment:

Xamarin Studio
Version 4.2.3 (build 60)
Installation UUID: 0b7eaebc-a0ed-4b58-81df-91e378cad28c
Runtime:
	Mono 3.2.6 ((no/9b58377)
	GTK+ 2.24.23 theme: Raleigh
	GTK# (2.12.0.0)
	Package version: 302060000

Apple Developer Tools
Xcode 5.0 (3332.22)
Build 5A1412

Xamarin.iOS
Version: 7.2.0.2 (Trial Edition)
Hash: 58c3efa
Branch: 

Build Information
Release ID: 402030060
Git revision: 30c4afc300c2a39ec5300851357ce02e49dd217e
Xamarin addins: f8a9589b57c2bfab2ccd73c880e7ad81e3ecf044

Operating System
Mac OS X 10.8.5
Darwin Admin-Macs-Mac-mini.local 12.5.0 Darwin Kernel Version 12.5.0
    root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64
Comment 6 Sadik Ali 2014-04-07 10:27:34 UTC
Created attachment 6510 [details]
Attached Project to reproduce this issue
Comment 7 Dave Thomas 2015-04-10 05:55:58 UTC
This looks to be fixed in the current Xamarin.iOS (8.10.0.197)