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

Bug with inline FFI typesig and strict wrappers #379

Closed hdgarrood closed 10 years ago

hdgarrood commented 10 years ago

Using a strict wrapper with an FFI declaration seems to only work in the case where there is a separate top level type signature, and no inline type signature.

For example:

module Test where

import Prelude
import FFI

logInlineOnly = ffi "console.log(%1)" :: a -> Fay ()

logSeparateOnly :: a -> Fay ()
logSeparateOnly = ffi "console.log(%1)"

logBoth :: a -> Fay ()
logBoth = ffi "console.log(%1)" :: a -> Fay ()

main = do
    putStrLn "inlineOnly:"
    ffi "Strict.Test.logInlineOnly('hello')" :: Fay ()

    putStrLn "separateOnly:"
    ffi "Strict.Test.logSeparateOnly('hello')" :: Fay ()

    putStrLn "both:"
    ffi "Strict.Test.logBoth('hello')" :: Fay ()

Only the separateOnly call seems to actually call console.log. It's not an FFI thing -- the same happens with an HTML wrapper in the browser console.

Here's a possibly relevant bit of the compiled JS:

Test.logInlineOnly = new Fay$$$(function() {
    return function($p1) {
        return new Fay$$$(function() {
            return new Fay$$Monad(Fay$$jsToFay(["unknown"], console.log(Fay$$fayToJs(["unknown"], $p1))));
        });
    };
});
Test.logSeparateOnly = function($p1) {
    return new Fay$$$(function() {
        return new Fay$$Monad(Fay$$jsToFay(["unknown"], console.log(Fay$$fayToJs(["unknown"], $p1))));
    });
};
Test.logBoth = new Fay$$$(function() {
    return function($p1) {
        return new Fay$$$(function() {
            return new Fay$$Monad(Fay$$jsToFay(["unknown"], console.log(Fay$$fayToJs(["unknown"], $p1))));
        });
    };
});
hdgarrood commented 10 years ago

Also, Strict.Test.logBoth('hello').force() does print 'hello' to the console (and the same happens with logInlineOnly)

bergmark commented 10 years ago

Ah, the issue is visible in the output you pasted, ffi expressions introduce an extra thunk which it shouldn't.