Bucklescript

wiki
bucklescript
Tags: #<Tag:0x00007f114a18bf98> #<Tag:0x00007f114a18bc78>

#126

Decoders are a wonderfully functional method of parsing JSON, I quite like them personally, though I know more traditionally-javascript people find them wordy. ^.^;

Yeah there are a couple API changes from Elm (I could emulate probably all of them, but eh, I made them for good reasons in most cases).

As for sending information ‘out’ of the app, right now you can just call an external, I’d not recommend calling it from your main loop and instead wrapping it in a command, but it is just fine to do it from within a command.

For pushing ‘in’ to the app the pushMsg is the way to do it, that is very low level and I plan higher wrappers sometime (I’m even thinking of using subscriptions as ways of exposing outside commands with a better interface). Overall I prefer the web-standard method of marshalling data up and down, use standard HTML Events (something Elm seems to hate for whatever reason), I plan to make some really nice helpers around that in my enhanced Tea. :slight_smile:

And yep, I wrapped the main very simply, something Elm should have done, it was just so simple to do it this way, and you can name it other things than ‘main’ as well, the name main is not special in any way like it is in Elm. :slight_smile:

You are welcome for sure! I use it at work in my own things but I like seeing others use it, plus more eyes on it means more ideas for it over time too! :slight_smile:


#127

@OvermindDL1 what do you think you think about Alpaca vs writing an OCaml compiler backend that targets Erlang/Elixir/BEAM bytecode?


#128

Alpaca ‘could’ be better, but if I were to make an ML style language on the BEAM directly then I’d be doing it in a much different style than they are. OCaml on the other hand has a monstrous eco-system already useful, that is a huge boon right there, plus being able to compile to javascript or native as well means only needing to use one safely typed language in all places.


#129

Hm… What would you do then in their case? And do you think people should focus on writing a new backend to OCaml instead of writing to the BEAM directly?


#130

If you want a very BEAM-specific ML language then I’d make something that is built on the internal types the BEAM knows at its base.

However, a big plus of OCaml is its already existing massive ecosystem of libraries and the fact it can compile to ‘other’ things as well, plus it is very well battle-hardened. This bonuses alone would make me choose to make a new backend for OCaml rather than write my own.


#131

So… No support for algebraic datatypes, for example?

EDIT: It would surprise me because sum and product types base on the native BEAM types, I think it makes sense to have them…


#132

Of course there would be, but I’d have them be based on the native types. So where OCaml allows:

type Colors =
  | White
  | Red
  | Green
  | Blue
  | Black
  | RGB of int * int * int

I’d instead prefer something like:

type colors =
  | :red
  | :green
  | :blue
  | {int, int, int}

Where the ‘structure’ becomes the type of the sum type, rather than the ‘name’ of it. This does mean you have to have a unique structure for each head though or some way to differentiate them (otherwise error at compile-time), just like you’d have to do in Elixir anyway. ^.^


#133

Update: BuckleScript now has awesome error messages like Elm.
Add this to "bsc-flags"

-bs-super-errors

#134

Yep they’ve been working on that for a few months, still adding more over time too. It is basically a built-in BetterErrors with more introspection of the AST to provide even more information. It is quite awesome!


#135

@OvermindDL1 If you were to write a graphical game (basic moving images/shapes, simple sprite animation, etc) what would you recommend with your TEA library? I see lots of different methods when researching Elm games: some use Collage, some use Elm’s html library, there’s some early-ish support for webgl, and a lot of stuff is outdated. I’d like to hear any thoughts/recommendations you have. I don’t mind porting libraries from Elm if that’s required.


#136

Honestly writing everything required about image loading, sound handling, ECS interfaces,and so much more would be so much work that honestly I’d just bind a good javascript game library. ^.^;

However it is entirely possible, you could do something decently in just svg even as long as you don’t need shaders and not a crazy amount of stuff rendered at once. ^.^


#137

Well, speaking of TEA, virtual DOM, and OCAML: https://blog.janestreet.com/self-adjusting-dom/


#138

Heh yep, similar to what I’ve been setting up for the TeaEx Portion of bucklescript-tea (breaking from the Elm API but far more efficient and capable).


#139

I’m writing a chess-themed tutorial on creating an SPA with Bucklescript-TEA. So far, 8 out of 12 parts are online, and I will post the remaining parts in the next few days (and probably refine what I wrote so far).

Here’s the code: https://github.com/quernd/tea-chess
Here’s the writeup: https://quernd.github.io/tutorials/tea-chess/


#141

Few questions regarding bucklescript-tea.

  1. How can I use an existing chart library (or similar like a text-editor) in bs-tea?

I know this can be a pain point in Elm (and in many other virtual-dom frameworks). I’ve tried to integrate chartist (don’ know why I picked that one but they all seem similar in the way the are used) in my bs-tea application.

So chartist require you to create a new Chartist object and give it a Dom Node or a selector (class name, id) of a Dom node.

var c = new Chartist.Line('.class-name', {... data ...});

I don’t know how to integrate this into TEA. I tried creating some bucklescript bindings:

type chart
type data = 
  { labels: string list
  ; series: int list list
  }
external create string -> data -> t = "Chartist.Line" [@@bs.new]

and then in my update function create it:


  | ViewChart ->
     let c = Chart.create ".class-name" {labels=["A";"B";"C"]; series = [[1;2;3]]}
     in
     ( model, Cmd.none )

However this does not seem to work. I take it “dom” node holding it may not have been created yet or being removed and added into the DOM tree.

I’ve tried playing around with a few different ways here but no success yet.

I’ve seen it mentioned in lots of VDom frameworks that handling external components which takes “ownership” of the DOM node is tricky. Any advice here would be really welcome!

  1. What is the preferred way of integrating with javascript? In Elm it is by using port modules but they don’t seem to exists in bs-tea. I’ve seen that you can send things to bs-tea by call app.pushMsg(...) from your javascript and this turns up in your messges. And the you can call javascript from anywhere (probably your update function) using bucklescript bindings. Is this the way to do it?

#142

Well OCaml has a built-in FFI syntax (Foreign Function Interface), so at the absolute most basic level you could just, essentially, type the calls you want to make to Chartist like:

module Chartist = struct
  external line : string -> whatever_data_format -> whatever_output_type = "Line" [@@bs.module "Chartist"]
end

Or rather I guess the most basic would be just pure ‘raw’ embedding even. ^.^;

The ‘best’ way in bucklescript-tea I’d say is to either make a subscription or command or task as necessary depending on the usage though. For things that embed ‘into’ the virtual DOM just keep the structure straight and so forth, wait a render tick before embedding, and all this will be much more simple once I get around to adding the Custom lifetime node elements. :slight_smile:

Yep, it takes a browser render-cycle for that to go through. The best thing to do is to add an event to the parent node of whatever will hold your chart, like the load DOM event or so, and have it call back into your TEA app via an event binding, then just load the chart and have it mount itself into the event’s activation element. :slight_smile:

That is something you cannot do in Elm but really really should be done, instead you have to do nasty Port wrangling… >.<

I’m always partial to using the web standard events in all possible cases. :slight_smile:

Yeah I’m not a fan of Ports, and I am a fan of the standard DOM events and so forth. So the ‘usual’ way to call back is to register DOM-standard event handlers on to whatever nodes you want to listen on, which will call back your defined callback function. As an absolute worse-case scenario you can always pushMsg something in, but there are almost always better, shorter, and more useable ways. ^.^

As always though, make sure that whatever code you run inside update/init/view/etc is safe to be run potentially ‘many’ times (it won’t ‘normally’, but a debugger could), rather code that should only ever be run once or at specific times should either be in events or commands (Cmd.t) only. Events is the most usual way of course. :slight_smile: