BuckleScript 8.2 released


#1

The major highlights of this release is first class string literal types

See more details here https://reasonml.org/blog/bucklescript-release-8-2

Enjoy!


#2

I’m a little confused by this blog post.

The extra documentation is nice, its clear and gives good motivating examples but it feels like it’s trying really hard to avoid the name “polymorphic variants”. As a result I can’t tell what the new feature is, has the encoding for polymorphic variants changed so that constructors without any arguments are now strings (without the wrapping object)?

I think trying to re-label polymorphic variants as string-literals is a bit misleading and ultimately not very helpful for people new to the language. You can use polymorphic variants with any data type after all.


#3

I think the big news here is seamles interop with JS values that are sets of string literals, e.g. "ascii" | "utf-8". In case of interop, it does matter what the Reason types compile to.


#4

Thats what I am getting at, previously you needed an [@bs.string] or something to get that behaviour right?

EDIT: It looks like the feature is indeed that you don’t need [@bs.string] anymore


#5

I think this has been incorrectly “sugared”, and was very confusing for me to read

[ 3 -> `Int , "3" -> `String ]

I think this is supposed to be

[ `Int(3), `String("3") ]

#6

I was confused by this as well. Is it part of the new syntax maybe?


#7

Well, FWIW, I find myself using fast pipes with bs-css, since border(1->`px, solid, (0, 0, 0, 0.2)->`rgba) reads better (to me) than border(`px(1), solid, `rgba((0, 0, 0, 0.2))), especially with arrow ligatures (which are neat both as in pretty and as in less noisy).

But I agree that [ 3 -> `Int , "3" -> `String ] looks confusing, especially because it doesn’t resemble how you’d pattern match it.


#8

Your understanding is correct, polymorphic variant tags without payloads are compiled to just string literals. It’s really that simple. The blog post written to cater to audiences familiar with JavaScript and TypeScript, for whom ‘polymorphic variants’ would not be meaningful terminology. So I personally don’t find it misleading, just targeted in a specific way.


#9

Hi, the whole excitement is that it is compiled to literal string, otherwise polyvar is not usable unless you would like to debug those magic numbers.

We acknowledge the legacy we inherited from OCaml and appreciate it, but we want to build a culture of our own, using names more accessible to average users generally follows the same philosophy


#10

Both works.

3 -> `Int gives user a lively view that they are separate, you can attach any data with any string tag. I hope it makes more sense for beginners.


#11

About string literals and polymorphic types: is it possible now to use reserved keywords as polymorphic variants?

Simple example: ariaCurrent in ReasonReact ReactDOM. For now, this is commented out, and the type should be something like:

type ariaCurrent = [
  | `page
  | `step
  | `location
  | `date
  | `time
  | `true
  | `false
  ];

However, this does not compile, we would need a variant like

`True

or

`true_

But this is obviously not compiled to the correct string (sorry, I don’t know how to escape single backticks :sweat_smile:). Using something like

| `Bool(bool)

cannot be used because this compiles to a struct (and it must be like this to avoid tag collisions).

At the same time, I am not able to do something like

| [@bs.as "true"] `True

or, IMHO even better

| [@bs.transparent] `Bool(bool)

At the current state is it possible to use some workaround for this?


#12

It is possible using the new BuckleScript syntax:

type ariaCurrent = [
| #\"true"
| #\"false"
| ...
]

#13

Thanks for the reply, but unfortunately this does not compile with bs 8.2.

Your syntax produces the error Illegal character (\\), I tried some variants but I am not able to find a way to make it compile. Is it necessary to use the new .res extension to use this new syntax?


#14

We definitely could patch the ocaml grammar to accept things like `“true”,
is it a desired thing?


#15

I think that it would be useful, but I would like to ask people involved in the maintainment and development of ReasonReact, which surely know the issue better than me.

CC @bloodyowl @rickyvetter


#16

Would patching the ocaml grammar make the code that uses this feature incompatible with the native OCaml backend?


#17

Yes, for the new BuckleScript syntax you need to use the .res/.resi extension, otherwise you’re using the current Reason syntax (.re/.rei).

If you use new syntax it works.


#18

Thanks for the reply.

I hope that this won’t be a problem for projects like ReasonReact: from what you are saying, these features are completely unavailable with the pre-8.0 syntax. This means that ReasonReact (and similarly other projects) need to create a breaking release in order to migrate to the new syntax and then to start implementing all the components attributes that, with the old syntax, cannot be expressed without overhead.

Many people were worried about an ecosystem split, and this kind of things seems to bring in this exact direction :cry:. I really hope that this wont be something overwhelming for the ReasonML community, I would really like to see the language being adopted around the world…


#19

There is a discussion on GitHub to make this available in Reason as well. It needs a slight change in the Reason compiler and not BuckleScript. Most stakeholders agree this should become available. It just takes a bit of time to get this implemented. This change is also important to support “string literals” in reason-react-native.