jstolarek / slicer

Companion code for paper "Imperative Functional Programs that Explain their Work", Wilmer Ricciotti, Jan Stolarek, Roly Perera and James Cheney, ICFP 2017, Oxford, UK
http://dl.acm.org/citation.cfm?id=3110258
GNU General Public License v3.0
6 stars 0 forks source link

2D arrays utterly broken #62

Closed jstolarek closed 7 years ago

jstolarek commented 7 years ago

If I say:

let as = array(2,array(2,0.0)) in
set(get(as,0),0, 3.0) ;;
set(get(as,0),1, 3.0) ;;

set(get(as,1),0, 2.0) ;;
set(get(as,1),1, 5.0) ;;

let a = get(get(as,0),0) in
let b = get(get(as,0),1) in
let c = get(get(as,1),0) in
let d = get(get(as,1),1) in
(a,(b,(c,d)))

I get

val it = (2.0, (5.0, (2.0, 5.0))) : (double * (double * (double * double)))
jstolarek commented 7 years ago

That's what a trace looks like after each of the updates:

Store [] [ (0, Array [ (0, VDouble 3.0),(1,VDouble 0.0)])
         , (1, Array [ (0, VArrLoc (StoreLabel 0) 2)
                     , (1, VArrLoc (StoreLabel 0) 2)])] 2

Store [] [ (0, Array [ (0, VDouble 3.0),(1,VDouble 3.0)])
         , (1, Array [ (0, VArrLoc (StoreLabel 0) 2)
                     , (1, VArrLoc (StoreLabel 0) 2)])] 2

Store [] [ (0, Array [ (0, VDouble 2.0),(1,VDouble 3.0)])
         , (1, Array [ (0, VArrLoc (StoreLabel 0) 2)
                     , (1,VArrLoc (StoreLabel 0) 2)])] 2

Store [] [ (0, Array [(0, VDouble 2.0),(1,VDouble 5.0)]),
           (1, Array [(0, VArrLoc (StoreLabel 0) 2)
                     ,(1, VArrLoc (StoreLabel 0) 2)])] 2

When we create an array N by N we should allocate N arrays, each containing N elements and then create one more array with each cell pointing to one of arrays. What happens in our case is that we allocate only one array of length N and then each cell in the array-of-arrays points to that single array.

jamescheney commented 7 years ago

I think this bug report is misnamed. The same thing would happen in OCaml, because the default initialization value of the outer array would be shared.

jstolarek commented 7 years ago

That's not exactly what I would expect but if you're saying this is correct behaviour I'll close as invalid.

jamescheney commented 7 years ago
$ ocaml
        OCaml version 4.03.0

# Array.make;;
- : int -> 'a -> 'a array = <fun>
# let arr = Array.make 2 (Array.make 2 0.0);;
val arr : float array array = [|[|0.; 0.|]; [|0.; 0.|]|]
# Array.set (Array.get arr 1) 1 2.0
  ;;
- : unit = ()
# arr;;   
- : float array array = [|[|0.; 2.|]; [|0.; 2.|]|]
jstolarek commented 7 years ago

I had no experience with arrays in OCaml, so that's not what I expected. My expectations we're based on behaviour of imperative languages like C.