faylang/fay

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

jaburns opened this issue · 4 comments

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

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.

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.

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

data Vector a
Data Stuff = Stuff { stuff :: Vector Int }

Merged in 93f4f91