rescript-compiler icon indicating copy to clipboard operation
rescript-compiler copied to clipboard

WIP: Drop Caml runtimes and primitives

Open cometkim opened this issue 1 year ago • 1 comments

Resolves #5779

This PR contains many breaking changes

Completely dropped

  • [x] BukleScript compile time contexts
  • OCaml utils
    • [ ] parser
    • [ ] lexer
    • [ ] arg parser
    • [ ] digest
    • [ ] formatter
    • [ ] printer
  • OCaml structures
    • [ ] Array
    • [ ] List
    • [ ] Hashtbl
    • [ ] Set
    • [ ] Queue
    • [ ] Complex
    • [x] Stream
  • [x] OCaml IO
    • [ ] Sys
  • OCaml primitives
    • [ ] String
    • [ ] Char
    • [ ] Int32
    • [ ] Int64

TBD list here what changed

cometkim avatar Aug 27 '24 16:08 cometkim

Like it

DZakh avatar Aug 27 '24 18:08 DZakh

Maybe it's better to merge #6979 first, then I'll rebase

cometkim avatar Sep 22 '24 19:09 cometkim

Maybe it's better to merge #6979 first, then I'll rebase

Definitely. Given the size of this amazing work we can't really review it but we can quickly observe if all the generated code is simply identical.

cristianoc avatar Sep 22 '24 21:09 cristianoc

Actually, it was a bit improved like https://github.com/rescript-lang/rescript-compiler/pull/6984/commits/03fe31086dccfe98ca91fe66e92983df95bb26b6#diff-ef282bde01036b4b8ce35133e81733df0530c2e4192992862d2ef200c114e5e0

Having dedicated variants rather than just Pccall makes analyzing side effects /specialization much easier.

cometkim avatar Sep 22 '24 22:09 cometkim

I tested against one of our projects and found that the array indexing now does not return option anymore, even if Core is open.

I.e. this compiles:

open RescriptCore

let a = [1, 2, 3]

let x: int = a[0]
let y: option<int> = a->Array.get(0)

cknitt avatar Sep 23 '24 05:09 cknitt

Maybe it's better to merge https://github.com/rescript-lang/rescript-compiler/pull/6979 first, then I'll rebase

Not sure as #6979 is currently blocked by the binary incompatibility issue described in https://github.com/rescript-lang/rescript-compiler/pull/6979/files#r1738735381, so we would need to wait for that to be resolved.

cknitt avatar Sep 23 '24 05:09 cknitt

Maybe it's better to merge #6979 first, then I'll rebase

Not sure as #6979 is currently blocked by the binary incompatibility issue described in https://github.com/rescript-lang/rescript-compiler/pull/6979/files#r1738735381, so we would need to wait for that to be resolved.

I'm going to see if we can figure out a quick fix ASAP for just this situation so that can get merged, so that and this can move along. Will get back here when I got something.

zth avatar Sep 23 '24 06:09 zth

Maybe it's better to merge #6979 first, then I'll rebase

Not sure as #6979 is currently blocked by the binary incompatibility issue described in https://github.com/rescript-lang/rescript-compiler/pull/6979/files#r1738735381, so we would need to wait for that to be resolved.

I'm going to see if we can figure out a quick fix ASAP for just this situation so that can get merged, so that and this can move along. Will get back here when I got something.

Actually seems like the binary compat was already broken here: https://github.com/rescript-lang/rescript-compiler/pull/6943

Me and @cristianoc discussed a bit, and we think it's fine to merge that PR as is, because the editor extension doesn't touch any of these things where we've extended the AST. However, we need to figure out a real solution for this mid to long term.

The real solution is likely to be that the extension ships its own compiler libs vendored that's compatible with <=11.x, and we start shipping the language server runnable via the compiler for v12+ going forward, so that changes made to the AST is fine to make.

However, that's going to be some work, and I don't have time for that right now. The hard "deadline" for this work is when we introduce changes that break the binary compat in ways that matter for the editor extension. So, it'll be fine for now.

zth avatar Sep 23 '24 13:09 zth

I tested against one of our projects and found that the array indexing now does not return option anymore, even if Core is open.

I.e. this compiles:

open RescriptCore

let a = [1, 2, 3]

let x: int = a[0]
let y: option<int> = a->Array.get(0)

Fixed in https://github.com/rescript-lang/rescript-compiler/pull/6984/commits/613970b2ce1d70a37f3b68059cc9f231f073e55e

This is related to the behavior I mentioned in Discord. It's quite confusing that open MyStd or module Array = ... can break types of primitive syntax.

cometkim avatar Sep 24 '24 13:09 cometkim

I tested again against one of our projects. Array indexing now works as expected.

I ran into some things like mod_float and string_of_int missing and had to patch some dependencies, but once I got it to build, there were no diffs in the output compared to alpha.3! 🎉

So I guess we should keep at least the more widely used functions like mod_float and string_of_int, but mark them as deprecated in v12.

cknitt avatar Sep 24 '24 15:09 cknitt

Added compatibility/deprecations for Pervasives, Array, List, Char, and String.

Additionally, I modified the ninja.js to make runtime dir include only primitives and others dir include only stdlib. Pervasives now belong solely to primitives, and Js should be part of the stdlib. No-more copy-pasting and ordering hacks

The dependency graph is now others -> runtime clearly

cometkim avatar Sep 24 '24 21:09 cometkim

string_of_int and mod_float are still missing.

For the deprecations, I would suggest to only have "Use Core instead", not "Use Core or Js instead", as Js is also legacy.

Hmm, actually, once Core is in the compiler, we should refer to the matching function without mentioning Core at all, e.g., "Use Float.toString instead."

cknitt avatar Sep 25 '24 08:09 cknitt

I didn't make all functions compatible. I removed functions and OCaml primitives that were already deprecated. AFAIK we've been seeing messages like "use Belt.Int.toString instead" for a long time now.

Also note: Those modules should eventually be removed from the runtime; the "compiler primitives" path, because they are standard library, not primitives. Core is the new stdlib, but it already has some different signature than OCaml. Breaking changes will be inevitable if we add -open Core by default.

To be honest, I don't want to be forced to use Core. I want to have my own stdlib and I don't want to be in a situation where I have to depend on it or shadow it. we can avoid most of the problems if we make using Core as optional.

cometkim avatar Sep 25 '24 09:09 cometkim

Core will not be optional, as in it will always be available and on by default. This is because one of the big goals with Core is to provide a great default, and we don't want to give the impression that it's "Core or these other available things" . Core won't be a separate concept anymore when it's integrated in the compiler, it'll just be a part of the language.

However, for advanced users it'll work exactly like today - you can shadow it easily with your own stdlib if you want, just like you can shadow the OCaml and/or the Js stuff today.

zth avatar Sep 25 '24 09:09 zth

Core will not be optional, as in it will always be available and on by default. This is because one of the big goals with Core is to provide a great default, and we don't want to give the impression that it's "Core or these other available things" . Core won't be a separate concept anymore when it's integrated in the compiler, it'll just be a part of the language.

However, for advanced users it'll work exactly like today - you can shadow it easily with your own stdlib if you want, just like you can shadow the OCaml and/or the Js stuff today.

ok I don't argue with that goal.

Anyway, the role of primitive is clear, so we have to be careful not to mix it up with the API surface of Core again.

Primitive is basically "used by the compiler" and should be referenced as an external binding as needed, not as a module, except a few edge cases.

If we open Core as the default, we have to deal with compatibility issues anyway. The most noticible one is that the return type of array[0] syntax changes from 'a to option<'a>. This is why I tried to change the behavior to a Primitive_array.get instead of Array.get earlier.

cometkim avatar Sep 25 '24 11:09 cometkim

@cometkim IMO you don't need to spend time on getting the error messages right here, we'll have to adjust them anyway as Core is brought in.

Yeah, that was a somewhat calculated breaking change. The positive side is that anyone who's moved to Core already (which I hope is the majority) will already have dealt with that.

Anyway, again, absolutely fantastic job on this PR. A pretty insane feat changing this amount of code and causing no major breakages!

zth avatar Sep 25 '24 12:09 zth

@cometkim Skimmed through the rest of the changes. Looks good to me! 👍

Could you just bring back the "cargo clean" in the Makefile in some form or other a discussed above? Then good to go from my point of view.

cknitt avatar Sep 26 '24 13:09 cknitt

Could you just bring back the "cargo clean" in the Makefile in some form or other a discussed above? Then good to go from my point of view.

Added clean-rewatch, and rebased

cometkim avatar Sep 27 '24 13:09 cometkim

Merge! Merge! Merge!

😁

zth avatar Sep 27 '24 13:09 zth

Merged! 🎉

cknitt avatar Sep 27 '24 14:09 cknitt