Skip to content

Uncurried always #5968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 16, 2023
Merged
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ subset of the arguments, and return a curried type with the remaining ones https
- Add support for default arguments in uncurried functions https://github.com/rescript-lang/rescript-compiler/pull/5835
- Inline uncurried application when it is safe https://github.com/rescript-lang/rescript-compiler/pull/5847
- Support optional named arguments without a final unit in uncurried functions https://github.com/rescript-lang/rescript-compiler/pull/5907
- Add support for uncurried-always: a mode where everything is considered uncurried, whether with or without the `.`. This can be turned on with `@@uncurriedAlways` locally in a file. Added a project config `"uncurried"`, which propagates to dependencies, and takes the values: `"legacy"` which changes nothing, or `"default"` for uncurried by default, or `"always"` for uncurried-always.
Since there's no syntax for partial application in this new mode, introduce `@res.partial foo(x)` to express partial application. This is temporary and will later have some surface syntax.
Use best effort to determine the config when formatting a file.
https://github.com/rescript-lang/rescript-compiler/pull/5968

#### :boom: Breaking Change

Expand Down
8 changes: 8 additions & 0 deletions docs/docson/build-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@
"additionalProperties": false,
"required": ["version"]
},
"uncurried-specs": {
"type": "string",
"enum": ["legacy", "default", "always"]
},
"bsc-flags": {
"oneOf": [
{
Expand Down Expand Up @@ -440,6 +444,10 @@
"$ref": "#/definitions/jsx-specs",
"description": "Configuration for the JSX transformation."
},
"uncurried": {
"$ref": "#/definitions/uncurried-specs",
"description": "Configuration for the uncurried mode."
},
"reason": {
"$ref": "#/definitions/reason-specs",
"description": "ReScript comes with [Reason](http://reasonml.github.io/) by default. Specific configurations here."
Expand Down
2 changes: 2 additions & 0 deletions jscomp/bsb/bsb_build_schemas.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,5 @@ let gentypeconfig = "gentypeconfig"
let language = "language"
let path = "path"
let ignored_dirs = "ignored-dirs"

let uncurried = "uncurried"
2 changes: 1 addition & 1 deletion jscomp/bsb/bsb_clean.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ let clean_bs_garbage proj_dir =
Bsb_log.warn "@{<warning>Failed@} to clean due to %s" (Printexc.to_string e)

let clean_bs_deps proj_dir =
let _, _, pinned_dependencies = Bsb_config_parse.deps_from_bsconfig () in
let _, _, _, pinned_dependencies = Bsb_config_parse.deps_from_bsconfig () in
let queue = Bsb_build_util.walk_all_deps proj_dir ~pinned_dependencies in
Queue.iter
(fun (pkg_cxt : Bsb_build_util.package_context) ->
Expand Down
14 changes: 14 additions & 0 deletions jscomp/bsb/bsb_config_parse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ let extract_gentype_config (map : json_map) : Bsb_config_types.gentype_config =
| Some config ->
Bsb_exception.config_error config "gentypeconfig expect an object"

let extract_uncurried (map : json_map) : Res_uncurried.config =
match map.?(Bsb_build_schemas.uncurried) with
| None -> Legacy
| Some (Str { str = "legacy" }) -> Legacy
| Some (Str { str = "default" }) -> Default
| Some (Str { str = "always" }) -> Always
| Some config ->
Bsb_exception.config_error config "uncurried expects one of: \"legacy\", \"default\", \"always\"."

let extract_string (map : json_map) (field : string) cb =
match map.?(field) with
| None -> None
Expand Down Expand Up @@ -337,6 +346,10 @@ let interpret_json ~(package_kind : Bsb_package_kind.t) ~(per_proj_dir : string)
jsx;
generators = extract_generators map;
cut_generators;
uncurried =
(match package_kind with
| Toplevel -> extract_uncurried map
| Pinned_dependency x | Dependency x -> x.uncurried);
}
| None ->
Bsb_exception.invalid_spec "no sources specified in bsconfig.json")
Expand All @@ -348,5 +361,6 @@ let deps_from_bsconfig () =
| Obj { map } ->
( Bsb_package_specs.from_map ~cwd:Bsb_global_paths.cwd map,
Bsb_jsx.from_map map,
extract_uncurried map,
Bsb_build_util.extract_pinned_dependencies map )
| _ -> assert false
2 changes: 1 addition & 1 deletion jscomp/bsb/bsb_config_parse.mli
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)

val deps_from_bsconfig : unit -> Bsb_package_specs.t * Bsb_jsx.t * Set_string.t
val deps_from_bsconfig : unit -> Bsb_package_specs.t * Bsb_jsx.t * Res_uncurried.config * Set_string.t

val interpret_json :
package_kind:Bsb_package_kind.t -> per_proj_dir:string -> Bsb_config_types.t
1 change: 1 addition & 0 deletions jscomp/bsb/bsb_config_types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@ type t = {
cut_generators : bool;
(* note when used as a dev mode, we will always ignore it *)
gentype_config : gentype_config;
uncurried: Res_uncurried.config;
}
3 changes: 2 additions & 1 deletion jscomp/bsb/bsb_ninja_gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ let output_ninja_and_namespace_map ~per_proj_dir ~package_kind
built_in_dependency;
reason_react_jsx;
jsx;
uncurried;
generators;
namespace;
warning;
Expand Down Expand Up @@ -205,7 +206,7 @@ let output_ninja_and_namespace_map ~per_proj_dir ~package_kind
let rules : Bsb_ninja_rule.builtin =
Bsb_ninja_rule.make_custom_rules ~gentype_config
~has_postbuild:js_post_build_cmd ~pp_file ~has_builtin:built_in_dependency
~reason_react_jsx ~jsx ~package_specs ~namespace ~digest ~package_name
~reason_react_jsx ~jsx ~uncurried ~package_specs ~namespace ~digest ~package_name
~warnings ~ppx_files ~bsc_flags ~dpkg_incls (* dev dependencies *)
~lib_incls (* its own libs *)
~dev_incls (* its own devs *)
Expand Down
8 changes: 7 additions & 1 deletion jscomp/bsb/bsb_ninja_rule.ml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ let make_custom_rules ~(gentype_config : Bsb_config_types.gentype_config)
~(has_postbuild : string option) ~(pp_file : string option)
~(has_builtin : bool)
~(reason_react_jsx : Bsb_config_types.reason_react_jsx option)
~(jsx : Bsb_jsx.t) ~(digest : string) ~(package_specs : Bsb_package_specs.t)
~(jsx : Bsb_jsx.t) ~(uncurried: Res_uncurried.config) ~(digest : string) ~(package_specs : Bsb_package_specs.t)
~(namespace : string option) ~package_name ~warnings
~(ppx_files : Bsb_config_types.ppx list) ~bsc_flags ~(dpkg_incls : string)
~(lib_incls : string) ~(dev_incls : string) ~bs_dependencies
Expand All @@ -102,6 +102,10 @@ let make_custom_rules ~(gentype_config : Bsb_config_types.gentype_config)
since the default is already good -- it does not*)
let buf = Ext_buffer.create 100 in
let ns_flag = match namespace with None -> "" | Some n -> " -bs-ns " ^ n in
let add_uncurried_flag = function
| Res_uncurried.Legacy -> ()
| Default -> Ext_buffer.add_string buf " -uncurried default"
| Always -> Ext_buffer.add_string buf " -uncurried always" in
let mk_ml_cmj_cmd ~(read_cmi : [ `yes | `is_cmi | `no ]) ~is_dev ~postbuild :
string =
Ext_buffer.clear buf;
Expand All @@ -121,6 +125,7 @@ let make_custom_rules ~(gentype_config : Bsb_config_types.gentype_config)
(match gentype_config with
| false -> ()
| true -> Ext_buffer.add_string buf " -bs-gentype");
add_uncurried_flag uncurried;
if read_cmi <> `is_cmi then (
Ext_buffer.add_string buf " -bs-package-name ";
Ext_buffer.add_string buf (Ext_filename.maybe_quote package_name);
Expand Down Expand Up @@ -171,6 +176,7 @@ let make_custom_rules ~(gentype_config : Bsb_config_types.gentype_config)
| None -> ()
| Some Classic -> Ext_buffer.add_string buf " -bs-jsx-mode classic"
| Some Automatic -> Ext_buffer.add_string buf " -bs-jsx-mode automatic");
add_uncurried_flag uncurried;

Ext_buffer.add_char_string buf ' ' bsc_flags;
Ext_buffer.add_string buf " -absname -bs-ast -o $out $i";
Expand Down
1 change: 1 addition & 0 deletions jscomp/bsb/bsb_ninja_rule.mli
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ val make_custom_rules :
has_builtin:bool ->
reason_react_jsx:Bsb_config_types.reason_react_jsx option ->
jsx:Bsb_jsx.t ->
uncurried:Res_uncurried.config ->
digest:string ->
package_specs:Bsb_package_specs.t ->
namespace:string option ->
Expand Down
2 changes: 1 addition & 1 deletion jscomp/bsb/bsb_package_kind.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)

type dep_payload = { package_specs : Bsb_package_specs.t; jsx : Bsb_jsx.t }
type dep_payload = { package_specs : Bsb_package_specs.t; jsx : Bsb_jsx.t; uncurried : Res_uncurried.config }

type t =
| Toplevel
Expand Down
8 changes: 4 additions & 4 deletions jscomp/bsb/bsb_world.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ let vendor_ninja = Bsb_global_paths.vendor_ninja

let make_world_deps cwd (config : Bsb_config_types.t option)
(ninja_args : string array) =
let package_specs, jsx, pinned_dependencies =
let package_specs, jsx, uncurried, pinned_dependencies =
match config with
| None ->
(* When this running bsb does not read bsconfig.json,
Expand All @@ -36,7 +36,7 @@ let make_world_deps cwd (config : Bsb_config_types.t option)
*)
Bsb_config_parse.deps_from_bsconfig ()
| Some config ->
(config.package_specs, config.jsx, config.pinned_dependencies)
(config.package_specs, config.jsx, config.uncurried, config.pinned_dependencies)
in
let args =
if Ext_array.is_empty ninja_args then [| vendor_ninja |]
Expand Down Expand Up @@ -67,8 +67,8 @@ let make_world_deps cwd (config : Bsb_config_types.t option)
let _config : _ option =
Bsb_ninja_regen.regenerate_ninja
~package_kind:
(if is_pinned then Pinned_dependency { package_specs; jsx }
else Dependency { package_specs; jsx })
(if is_pinned then Pinned_dependency { package_specs; jsx; uncurried }
else Dependency { package_specs; jsx; uncurried })
~per_proj_dir:proj_dir ~forced:false
in
let command =
Expand Down
21 changes: 12 additions & 9 deletions jscomp/bsc/rescript_compiler_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let setup_compiler_printer (syntax_kind : [ syntax_kind | `default])=
(match syntax_kind with
| `default -> ()
| #syntax_kind as k -> Config.syntax_kind := k);
let syntax_kind = !Config.syntax_kind in
let syntax_kind = !Config.syntax_kind in
if syntax_kind = `rescript then begin
Lazy.force Super_main.setup;
Lazy.force Res_outcome_printer.setup
Expand Down Expand Up @@ -245,20 +245,17 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array =

"-bs-jsx", string_call (fun i ->
(if i <> "3" && i <> "4" then Bsc_args.bad_arg (" Not supported jsx version : " ^ i));
let open Js_config in
jsx_version := jsx_version_of_int @@ int_of_string i),
Js_config.jsx_version := Js_config.jsx_version_of_int @@ int_of_string i),
"*internal* Set jsx version";

"-bs-jsx-module", string_call (fun i ->
(if i <> "react" then Bsc_args.bad_arg (" Not supported jsx-module : " ^ i));
let open Js_config in
Js_config.jsx_module := jsx_module_of_string i),
Js_config.jsx_module := Js_config.jsx_module_of_string i),
"*internal* Set jsx module";

"-bs-jsx-mode", string_call (fun i ->
(if i <> "classic" && i <> "automatic" then Bsc_args.bad_arg (" Not supported jsx-mode : " ^ i));
let open Js_config in
Js_config.jsx_mode := jsx_mode_of_string i),
Js_config.jsx_mode := Js_config.jsx_mode_of_string i),
"*internal* Set jsx mode";

"-bs-package-output", string_call Js_packages_state.update_npm_package_path,
Expand Down Expand Up @@ -409,8 +406,14 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array =

"-nopervasives", set Clflags.nopervasives,
"*internal*";
"-bs-uncurry", set Config.default_uncurry,
"*internal" ;
"-uncurried", string_call (fun i ->
match i with
| "default" -> Res_uncurried.init := Default
| "always" -> Res_uncurried.init := Always; Config.use_automatic_curried_application := true
| "legacy" -> Res_uncurried.init := Legacy
| _ -> Bsc_args.bad_arg (" Not supported -uncurried option : " ^ i)
),
"*internal* Set jsx module";
"-v", unit_call print_version_string,
"Print compiler version and location of standard library and exit";

Expand Down
26 changes: 26 additions & 0 deletions jscomp/build_tests/uncurried-always/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
*.exe
*.obj
*.out
*.compile
*.native
*.byte
*.cmo
*.annot
*.cmi
*.cmx
*.cmt
*.cmti
*.cma
*.a
*.cmxa
*.obj
*~
*.annot
*.cmj
*.bak
lib/bs
*.mlast
*.mliast
.vscode
.merlin
.bsb.lock
9 changes: 9 additions & 0 deletions jscomp/build_tests/uncurried-always/bsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "uncurried",
"version": "0.1.0",
"sources": {
"dir" : "src",
"subdirs" : true
},
"uncurried": "always"
}
9 changes: 9 additions & 0 deletions jscomp/build_tests/uncurried-always/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ts-check
const cp = require("child_process");
const assert = require("assert");
const fs = require('fs')
const path = require('path')
var rescript_exe = require("../../../scripts/bin_path").rescript_exe

cp.execSync(`${rescript_exe} clean -with-deps`, { cwd: __dirname, });
cp.execSync(`${rescript_exe}`, { cwd: __dirname, });
44 changes: 44 additions & 0 deletions jscomp/build_tests/uncurried-always/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions jscomp/build_tests/uncurried-always/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "uncurried",
"version": "0.1.0",
"scripts": {
"clean": "rescript clean",
"build": "rescript build",
"watch": "rescript build -w"
},
"keywords": [
"ReScript"
],
"author": "",
"license": "MIT",
"devDependencies": {
"rescript": "^10.0.0"
}
}
15 changes: 15 additions & 0 deletions jscomp/build_tests/uncurried-always/src/UncurriedAlways.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
let foo = (x, y) => x + y

let z = foo(. 3, 4)

let bar = (. x, y) => x + y

let b = bar(3, 4)

let w = 3->foo(4)

let a = 3->foo(. 4)

Js.log(a) // Test automatic uncurried application

let _ = Js.Array2.map([1], (. x) => x+1)
4 changes: 2 additions & 2 deletions jscomp/ext/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ let bs_only = ref true

let unsafe_empty_array = ref false

let use_automatic_curried_application = ref false

and cmi_magic_number = "Caml1999I022"

and ast_impl_magic_number = "Caml1999M022"
Expand All @@ -29,8 +31,6 @@ let interface_suffix = ref ".mli"
separately because it can differ when we're in the middle of a
bootstrapping phase. *)

let default_uncurry = ref false

let print_config oc =
let p name valu = Printf.fprintf oc "%s: %s\n" name valu in
p "version" version;
Expand Down
Loading