fable-compiler / repl-legacy

http://fable.io/repl
MIT License
14 stars 10 forks source link

Guid.ToString(x) doesn't work with arguments #39

Open nojaf opened 6 years ago

nojaf commented 6 years ago

So I'm trying the following and the computer says no:

<html>

<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
</head>

<body>
    <p></p>
</body>

</html>
open Fable.Core
open Fable.Core.JsInterop
open Fable.Import.Browser

let g = System.Guid.NewGuid().ToString("N")
let p = document.documentElement.querySelector("p")
printfn "%A" p
p.textContent <- g

window.addEventListener_load (fun _ -> 
    let g = System.Guid.NewGuid().ToString("N")
    let p = document.documentElement.querySelector("p")
    printfn "%A" p
    p.textContent <- g
    box ()
)

I'm not sure if I need the load event, I'm seeing nothing in both cases.

Some console logs:

Cannot find type System.ArgIterator
bundle.min.js:1 Cannot find type System.Runtime.CompilerServices.IDispatchConstantAttribute
bundle.min.js:1 Cannot find type System.ArgIterator
bundle.min.js:1 Cannot find type System.Runtime.CompilerServices.IDispatchConstantAttribute
alfonsogarciacaro commented 6 years ago

Hmm, this is because Guid.ToString() is not working with arguments, and unfortunately the weather is not letting you know. The following code does produce some result:

let g = System.Guid.NewGuid().ToString()
let p = document.documentElement.querySelector("p")
p.textContent <- g
nojaf commented 6 years ago

I see, newGuid() does indeed not take a parameter. Could this be solved by Fable 2.0?

alfonsogarciacaro commented 6 years ago

I guess so, though I'm not sure what the argument is exactly doing. Maybe you could send a PR?

nojaf commented 6 years ago

Hmm I suppose

export function newGuid(){
  let b = ''
  for(
    let a = 0;
    a++ < 36;
    b += a * 51 & 52
      ? (a^15 ? 8^Math.random() * (a^20 ? 16 : 4) : 4).toString(16)
      : '-'
  );
  return b;
}

should return an Object with a toString function to format the guid. Might be more than meets the eye. I guess all of the Guid functionality should be added an not just let newGuid return a string.

Where should that code end up? Should it be F# and then compiled by Fable? I'm always a bit confused what is transpiled F# and what isn't when looking at Fable.Core.

alfonsogarciacaro commented 6 years ago

Hmm, it's a bit complicated. There are a few types that are converted to a different thing in JS (e.g. TimeSpan becomes a number), you can see them in the compatibility doc. In the case of Guid it was a quick patch at the beginning, but it worked well and proved other benefits (e.g. you can easily use it as Id in custom react components) so I kept it as is. The problem with making it an object is it's difficult to port all the features from .NET, like being a value type, or conversion to/from a byte array. But we could try something if formatting is important for you.

nojaf commented 6 years ago

Well to be honest I'm not sure if it is worth the effort. Writing a helper function that formats the ToString() of the guid to the shape I need could also do the trick.

let toStringN (guid:Guid) =
    Guid.NewGuid().ToString().Replace("-", String.Empty)

Guid.NewGuid() 
|> toStringN
|> printfn "%s"

Maybe it's enough to have a better error message when using ToString("N")

ERROR in ./src/App.fs
C:/Temp/SimpleFable/src/App.fs(8,0): (8,28) error FABLE: Cannot find replacement for System.Guid::ToString
 @ ./src/SimpleFable.fsproj 1:0-25
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/SimpleFable.fsproj
webpack: Failed to compile.

This is somewhat confusing since ToString() without args does work.