Drop Caml runtimes and primitives #6984
Merged
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Resolves #5779
Rationale
This removes runtime modules and primitives that exist for OCaml compatibility.
The original BuckleScript tried distinguishing between OCaml-inherited primitives and custom primitives (
?prim) and js primitives (#prim), but it didn't stick well.Since we gave up OCaml compatibility, it added unnecessary complexity with indirection, making it hard to predict where specialization would be performed.
So here I unify all primitives into a single prefix grammar of
%. There is still#primitive, but it exists temporarily for compatibility or is meant to be internal to the compiler and not exposed to the frontend.Changes
This PR contains many breaking changes
Primitive_object.updateDummy(formallyCaml_obj.update_dummy) behavior is now the same as theObject.assignand doesn't specially handleArrayinstances. See discussion from Improve obj dup using spread syntax #7043. But this is safer because it is only used inmodule recbindings.String.get: (string, int) => charbehavior is now the same as theString.prototype.codePointAt. It was potentially buggy with existing char primitives, but this fixes it. See RFC: Revisecharprimitive #7028int32(useintinstead)int64uint32nativeintfloatarray(useFloat32ArrayorFloat64Arrayinstead)bytes(useArrayBufferorUinr8Arrayinstead)caml_{type}_compare->%{type}order(e.g.%intorder)caml_{type}_min->%{type}min(e.g.%intmin)caml_{type}_max->%{type}max(e.g.%intmax)%bs_min->%min%bs_max->%max%bs_equal_null->%equal_null%bs_equal_undefined->%equal_undefined%bs_equal_nullable->%equal_nullable#unsafe_lt->%unsafe_lt#unsafe_gt->%unsafe_gt#unsafe_le->%unsafe_le#unsafe_ge->%unsafe_ge#unsafe_eq->%unsafe_eq#unsafe_neq->%unsafe_neq%bs_equal_null->%equal_null%bs_equal_undefined->%equal_undefined%bs_equal_nullable->%equal_nullable#debugger->%debugger#typeof->%typeof#null->%null#undefined->%undefined%makemutable->%makeref%bs_field0->%refget%bs_set_field0->%refset?create_dict->%makedict#makemutablelist->%makemutablelist?await->%await#import->%import#apply{N}->%curry_apply{N}#is_nullable->%is_nullable#nullable_to_opt->%nullable_to_opt#null_to_opt->%null_to_opt#undefined_to_opt->%undefined_to_opt#wrap_exn->%wrap_exn#hash->%hash#hash_mix_int->%hash_mix_int#hash_mix_string->%hash_mix_string#hash_final_mix->%hash_final_mix#unsafe_to_method->%unsafe_to_method#function_length->%function_arity?obj_dup(from Improve obj dup using spread syntax #7043)?hexstring_of_float?float_of_string?int_of_string?int64_of_string?int64_format?format_int?format_float?lex_engine?new_lex_engine?parse_engine?set_parser_trace?md5_string?string_repeat?create_bytes?bytes_length?bytes_safe_get?bytes_safe_set?bytes_unsafe_get?bytes_unsafe_setcaml_bytes_*%int64_*caml_int64_*?bigint_div?bigint_mod%bigint_of_int32%bigint_to_int32?int_of_float(%intoffloatis still available)?float_of_int(%floatofintis still available)?int_float_of_bits?int_bits_of_float?fmod_float?modf_float?ldexp_float?frexp_float?copysign_float?expm1_float?hypot_float?exn_slot_name?is_extension?as_js_exn%reraise%raise_notrace%lazy_force(UseLazy.forceinstead)%backend_type%word_size%int_size%max_wosize0u(uint32) literal0l(int32) literal0L(int64) literalJs.isCamlExceptionOrOpenVariantformat_floatstring_of_boolbool_of_stringbool_of_string_optstring_of_intint_of_stringint_of_string_optstring_of_floatfloat_of_stringfloat_of_string_optprint_stringprint_intprint_floatprint_endlineprint_newlineprerr_endlineprerr_newlinevalid_float_lexemArgCallbackGenlexLexingParsingParsingDigestRandomBytesUcharBufferStreamFilenameInt32Int64StringpartiallyCharpartiallyArraySortListSetMapHashtbl(exceptHashtbl.hash)MapStackQueueComplexCaml_module->Primitive_moduleCaml_obj->Primitive_objectCaml_array->Primitive_arrayCaml_char->Primitive_charCaml_string->Primitive_stringCaml_exceptions,Caml_js_exceptions->Primitive_exceptionsCaml_hash,Caml_hash_primitive->Primitive_hashCaml_lazy->Primitive_lazyCaml_module->Primitive_moduleCaml_option->Primitive_optionCurry->Primitive_curryRuntime_promise->Primitive_promiseRuntime_dict->Primitive_dictRuntime_deriving->Primitive_utilPrimitive_boolPrimitive_intPrimitive_floatPrimitive_bigintCaml_format-> xCaml_sys-> xCaml_lexer-> xCaml_parser-> xCaml_md5-> xCaml_int32-> xCaml_int64-> xCaml_splice_call-> x (from improve variadic call using spread syntax #7030)Note for future refactoring
All primitives except # prefixed should eventually be treated as "features" and documented. We can rename all by a new convention for primitive names, but the old names should be kept for a while for compatibility.
Primitives are declared in two different places because they are processed separately before and after
Lam_convert. It is difficult to change and to determine the types used or not used, resulting in many dangerous assertions.Ultimately, I want to consolidate the primitive declarations into one place and make them easier to manage.