faylang / fay

A proper subset of Haskell that compiles to JavaScript
https://github.com/faylang/fay/wiki
BSD 3-Clause "New" or "Revised" License
1.29k stars 86 forks source link

List/tuple deserialization from JS to Fay fails in uncurried strict function invoke #409

Closed jaburns closed 9 years ago

jaburns commented 10 years ago

When calling Fay code from JavaScript, if the the Fay module is compiled using --strict, data structures containing lists or tuples will have those lists or tuples empty. It should be noted as well that fields which are not lists or tuples work fine when using the uncurried function invoke from JS, including nested data types.

Fay code (BugDemo.hs)

module BugDemo where
data Stuff = Stuff { stuff :: [Int] } deriving (Show)
fn :: Stuff -> Stuff -> Stuff
fn (Stuff xs) (Stuff ys) = Stuff $ zipWith (+) xs ys

Compilation

fay BugDemo.hs --strict BugDemo

Test page (demo.html)

<!DOCTYPE html>
<html>
  <body>
    <script type="text/javascript" src="BugDemo.js"></script>
    <script type="text/javascript">
      var a = { instance:"Stuff", stuff: [1,2,3] }
      var b = { instance:"Stuff", stuff: [3,2,1] }
      // These should output the same thing, but the first returns with an empty array.
      console.log (Strict.BugDemo.fn (a,b));
      console.log (Strict.BugDemo.fn (a)(b));
    </script>
  </body>
</html>

Console output from demo.html

Object
instance: "Stuff"
stuff: Array[0]
    length: 0

Object
instance: "Stuff"
stuff: Array[3]
    0: 4
    1: 4
    2: 4
    length: 3
bergmark commented 10 years ago

This sounds familiar but I'm not sure. It would be nice if someone could step through in the debugger and see what goes wrong in the runtime, can't promise I'll be able to do it anytime soon.

jaburns commented 10 years ago

No worries, I might take a look at it myself if I have the time. It was easy enough to work around though. I think this only happens with functions declared at the top level in the module, rather than functions which are members of a data structure.

bergmark commented 9 years ago

Another workaround for this is to not use lists, e.g.

data Vector a
Data Stuff = Stuff { stuff :: Vector Int }
bergmark commented 9 years ago

Merged in 93f4f91