Bucklescript

Found a major issue with Elm’s benchmark javascript code, it was using setTimeout to test async tasks when it should be using postMessage, changed that and significantly different results now.

MS-Edge:

Chrome:

Now that I have accurate results I can actually optimize it properly now. :slight_smile:

On another note, got Cmd working, the todo app properly focuses now too. :slight_smile:

2 Likes

Worked on the vdom a bit more, commands seem tested and working.

Current state with Chrome:

And with MS-Edge:

And with Firefox (why is firefox always rendering so slowly…):

And with IE11:

I’m unsure what to profile further, getting into sub-millisecond ranges, makes it hard to test further. Interestingly the profiler reports that the total elm time is taking 220.1ms and mine is taking 170.6ms total execution time, makes me wonder if elm is doing something async even though the rules states that all async’ness should be disabled or if the runner is still not running well enough.

And I just got subscriptions working, got a clock going now.

EDIT: The clock subscription testing thing is live at Testing now.

1 Like

And got subscriptions working, tested subscriptions by making the Navigation module, which is live at Testing with the button name of Counter w/ Navigation. :slight_smile:

Also worked more on the program interface, it will now only process one message at a time, if another message comes in while processing a first then it will queue up and run the list in order after completed processing the first, obviously needed that for subscriptions to work properly. ^.^

Example Navigation Animation

2 Likes

Added in the SVG module, made a new clock (“SVG Clock” button) that is identical to the elm clock example, include the 1 second delay at the start before it updates the time the first time (I had it fixed initially, but reverted it to match the elm example, bleh…).

Added an elm-like ‘Random’ module (with I think an identical api and usage too, though entirely different implementation) with a couple of example apps (the dice roll example from elm examples, as well as a random color generator).

Also added a link to the examples page linking to the github source since I’ve been asked a couple of times where the source is (I’ve linked it in this thread, but not elsewhere I think?). ^.^

As always at: http://overminddl1.com/bucklescript/

2 Likes

It’s not Bucklescirpt, but… https://github.com/chenglou/intro-to-reason-compilation

Actually Reason uses Bucklescript as its to-js compilation step, built right in. Just as Bucklescript is an OCaml compiler plugin to output javascript instead of machine code, Reason is an OCaml compiler plugin that gives a new syntax to OCaml (I agree with some of the changes, but not most of the changes, hence why I am not using it, it even has a React-like JSX thing built in that outputs stuff for React, baked into the language).

There are a huge amount of plugins for the OCaml compiler that add all sorts of little features, it is highly extensible. :slight_smile:

Well Reason is by Facebook so I expect it to be very React-inspired :slight_smile:

That is the point, they are making a javascript-esque OCaml. ^.^

How would consuming a plain javascript library via npm work? (EDIT: e.g. d3 which I’m using right now)

Also, could you or a mod make your first entry a wiki with a handy-dandy link to your github repos like this one to bucklescript-testing for those of us who are lazy (:ahem:) but keep continual tabs on your updates? :105:

As per the docs, if you want to bind to a function named ‘add’ in an npm module named “blah”, standard FFI syntax with the bs.module attribute to specify the javascript module. :slight_smile:

external add : int -> int -> int = "add" [@@bs.module "blah"]

For whatever types, and there are ways to define functions that take multiple types and such too. It is quite easy and there are ways to define many functions all at once too.

That is the same link that I have linked from the example page too. :slight_smile:
And it should already be a wiki thing, I thought it was changed by Astonj earlier. I’ll link my demo page as I link to other things from there for now.

Speaking of which, I made a (yet another) clicker game as a demo now too. ^.^

https://overminddl1.com/bucklescript/

EDIT: Yep, the top post is already marked as ‘wiki’. :slight_smile:

2 Likes

Got the Json.Decode/Json.Encode functions made that follow the elm API (I was so tempted to strip out all those mapN functions and replace them with a single map and mapMany or something, like wow that is ugly, probably will still add a mapMany anyway, why is it limited to 8 after all?!), and built an app to test the parsing, usual url (“Json” button): http://overminddl1.com/bucklescript/
And some test JSON for you that follows what it is looking to parse (an object of strings to strings entirely, the user one is a simple decoder, the full test done below that is more comprehensive): {"1": "42", "2": "86"}

@OvermindDL1 The sample apps you have built from scratch are very impressive and one of the very few projects that I have seen that combine performance, simple to use abstractions, strong types and a small JS payload. Are there any plans in the short term to restructure the code as a library?

2 Likes

Consider sharing the code and site with the BuckleScript community!

1 Like

I entirely plan to release it as a library eventually, right now I am trying to emulate the Elm libraries public interface (the internals are way different since Elm breaks typing internally so-freaking-much by passing things through javascript, so stupid that is…) to make conversions from elm->bucklescript as seamless as possible, plus I just love the programming pattern.

The base ‘Tea’ module that I am working on is what will try to emulate Elm closely. I do plan to add more functions and helpers and such over time though. I also plan an eventual OCaml’ized version of TEA using standard OCaml paradigms instead of Elm paradigms, but I do intend for them to interoperate.

I definitely accept PR’s if you want to make more Elm’y libraries in my testing project though, saves me work. :slight_smile:

(EDIT: I do need to overhaul the central loop, it was a hack of a design to just see if it could work, but it is the opposite of clean, so do ignore that part as a coding example, well unless you want to clean it up. ^.^)

Where is such a community? I’ve mostly just been talking to them on github and they know about it (even the creator of Bucklescript is following my github project). ^.^

(EDIT: I’m also playing with the idea to make an elixir (not erlang, elixirs AST format is just so much nicer) output PPX for OCaml as well. The OCaml typing system has a few interesting things that should solve the messaging problem that mlfe experiences that I messed around with to test, plus it basically has an ‘atom’ type already and a lot of other matching bits. I’d basically be making a Bucklescript but to output to the Elixir AST instead of javascript. ^.^ Sadly this would be an extreme amount of work compared to the time I have so I’m unsure how well I could accomplish that in the short-term without help)

3 Likes

Thanks for the explanation of the project. The only other place where I have seen Bucklescript being talked about is the Bucklescript channel on ReasonML server in Discord. The OCaml on BEAM idea sounds very interesting. I had the same idea (though I didn’t follow through on it) after I played with Fable F# Compiler and Bucklescript and wanted an ML backend on a platform has good concurrency primitives to build predictable latency and robust web services on UNIX platforms and has substantial adoption and quality software for the effort to be worthwhile. OCaml multi-core always seems an year out, lwt and async error prone and not great for long running computations. F# on dotnetcore seems to be making progress, with somewhat hacky & pragmatic async servers based on libuv like Kestrel (fast but barebones) and Suave on Mono (very slow but has a functional API), but it will probably take an year or two for it to gain features like type providers and adapt libraries to be made compatible with changes to the platform (eg. reflection). At the time I came across proof of concept in porting F# to Erlang by Dave Thomas and mlfe. And then I saw that Philip Wadler and Simon Marlow has worked on bringing types to Erlang awhile back but didn’t get too far, that and slow compute performance kind of put me off of the idea. http://learnyousomeerlang.com/types-or-lack-thereof and http://homepages.inf.ed.ac.uk/wadler/papers/erlang/erlang.pdf.

Edit: Forgot to add that somebody is also working on porting Purescript to Erlang.

1 Like

And on the ReasonML gitter room yep, those are the two places I’ve seen it too.

lwt I find actually very nice. I’ve not played with async. But yes, the concurrency primitives that have been added (very recently! couple months ago) to Ocaml Multi-Core are just downright awesome! You can build any kind of concurrency setup you can imagine, I’d go for less than a year out now, but who knows. :slight_smile:

I really want to like F#, so well based off of OCaml, but I just really hate .NET, and the JVM, VM’s. The first reason is that both do the really really really stupid thing of using OO-style design for even the back-end, which involves a shared global memory heap, which makes handling the GC both fairly random, hard to make efficient, cannot lock just ‘parts’ like a good actor style memory segmentation can, etc… The second big reason is that *holy*hell*standard*library*is*huge*! I like distributing standalone executable that run natively without a giant runtime. Thankfully .NET is going back toward the native compilation route (why they ever left it I don’t know, Microsoft being idiotic by trying to copy Java I guess, not that they can ever make something new), but I prefer C++/Rust kind of things, no GC, expected speed, no random hitches, and if you use the type systems well (like I do) then they are as powerful as programming in OCaml (though a bit more wordy, and multiple orders of magnitude slower to compile). The Erlang GC I can handle, its design means that only poorly programmed actors will be slowed down to collect where nothing else will, plus it is not really built to be a standalone application. I would not prefer an Erlang VM for a standalone application either. I should stop now before this turns into a 10k-word rant. ^.^

Heh, wonder how it would solve the ‘potential any type coming in through a message issue’ that is pretty easily solvable in OCaml, F# could do it though. ^.^

But yeah, I would love some kind of typed erlang. Even an optional typing down to the compiler would let it do a lot of optimizations that it cannot do right now too.

Does OCaml have anything that can help with the message type issue? discriminated unions and GADTs are the only things that come in to mind, and even then how does one account for change of behaviour of a message loop at runtime (in Akka parlance become/unbecome, I haven’t delved into Erlang). I can sort of see Polymorphic Variants being a fit for atoms if you squint a little bit. Anyway I am moving too much from the original topic.

There is a presentation about a session type implementation in F# using Type Providers here - requires a free account at SkillsMatter.

1 Like

Microsoft did some .net cleanup to split core and it can run now on linux :slight_smile: https://www.microsoft.com/net/core .

I’d probably map argumentless polymorphic variants as atoms (with an annotation to allow arbitrary names like atoms support). As for message loops I could see using polymorphic variants with arguments matching the erlang style quite well, make a process identifier take a set of polymorphic variants as ones it knows about publicly but leave it open so any can be passed in. Or worst-case you do something like make an ErlangTerm type that you parse out the information out of and specify ‘decoder’ type things as matchers, kind of like how you parse json in elm, the json parser decoder for the test format at the bucklescript link is this for example:

      map8 mapper
        (field "string" string)
        (field "int" int)
        (field "float" float)
        (at ["object"; "sub"] string)
        (field "array" (index 0 int))
        (field "list" (index 1 string))
        (field "boolean" bool)
        (field "null" (null "null"))

I can visualize something like that, or could go the erlang matchspec route to define those directly as you can build receive and such matchers out of them (they define the entire matching spec after all for function heads, receivers, case’s etc…).

Or could just use annotations to define match specs well.

Or could go the route of testing types and magically converting, but that is nasty.

And there are a dozen other ways I can think of to get ‘arbitrary’ messages then convert them. Going the full route of typing processes would be nice of course, but that does not fit the erlang world well, instead I’d think it would be better to have to parse messages somehow (of which simple decoders/matchspecs could be made that could be re-used easily).

In very much a way where almost no .NET programs work on it, instead only .NET programs that program in the reduced ‘Core’ spec will work, which means no GUI’s and such last I saw. And that still does not fix the monolithic runtime that you have to install and carry around the apps instead of just handing someone a single small file without dependencies. :wink:

1 Like

I’m considering replacing Elm with Bucklescript for smaller footprint. You said [quote=“bbz, post:6, topic:1579”]
I’ve chosen Purescript because it’s the only one without a runtime.
[/quote]

Does it mean Bucklescript requires a “runtime”? But from what I read it doesn’t.

1 Like