From 43dd185f737adb42956f747ddc7812b67b833953 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:48:53 +0200 Subject: [PATCH 1/7] [docs][style][1/n] initial documentation Provide a short description and usage. --- docs/USER_DOC.md | 1 + docs/coding_style/CODING_STYLE.md | 47 +++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 docs/coding_style/CODING_STYLE.md diff --git a/docs/USER_DOC.md b/docs/USER_DOC.md index 59e43d2..6d69e26 100644 --- a/docs/USER_DOC.md +++ b/docs/USER_DOC.md @@ -57,6 +57,7 @@ This documentation is split accross different topics: - [Methods](methods/METHODS.md) describes the semantics and usage of the "unused methods" report section, and provides examples. - [Constructors/Record fields](fields_and_constructors/FIELDS_AND_CONSTRUCTORS.md) describes the semantics and usage of the "unused constructors/record fields" report section, and provides examples. - [Optional arguments](optional_arguments/OPTIONAL_ARGUMENTS.md) describes the semantics and usage of the optional arguments always/never used report sections, and provides examples. +- [Coding style](coding_style/CODING_STYLE.md) describes the semantics and usage of the "coding style" report section, and provides examples. ## Footnotes diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md new file mode 100644 index 0000000..79e58e7 --- /dev/null +++ b/docs/coding_style/CODING_STYLE.md @@ -0,0 +1,47 @@ +# Table of contents + ++ [Coding style](#coding-style) + + [Usage](#usage) + +# Coding style + +This section relates to coding patterns. Although this is not related to dead +code, the tool has been reporting style issues almost since its conception +(commit [0adbc0d](https://github.com/LexiFi/dead_code_analyzer/commit/0adbc0d504830a01d64a701572b5e7cb3b29f03e)). +Tracking stylistic issues comes for "free" during the analysis and can be handy +when cleaning up a codebase so it was kept as part of the tool. + +The analyzer only reports 4 different kinds of stylistic issues : +- `bind`: useless binding +- `opt`: parameter of arrow type expecting an optional argument +- `seq`: binding to unit instead of using sequence +- `unit`: binding unit to a name + +## Usage + +Stylistic issues are not reported by default. +Their reports can be activated by using the `--all` or `-S +all` command line +arguments. +They can be deactivated by using the `--nothing` or `-S -all` command line +arguments. +Each of the sylistic issue category can be selectively activated/decativated as +described in their respective sections. +For more details about the command line arguments see [the more general Usage +documentation](../USAGE.md). + +The report section looks like: +``` +.> CODING STYLE: +=============== +filepath:line: issue + +Nothing else to report in this section +-------------------------------------------------------------------------------- +``` +The report line format is `filepath:line: issue` with `filepath` the absolute +path to the file where the `issue` lies, `line` the line index in `filepath` at +which the `issue` is, and `issue` the description of the stylistic issue. +There can be any number of such lines. + +The expected resolution depends on the reported issue category. This is +described in their respective sections. From 4e2adf395c467d340ac398347f8c2435f234d9ce Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:50:59 +0200 Subject: [PATCH 2/7] [docs][style][2/n] add bind section Provide a short description of its usage, an example and its limitation. --- check/classic/classic.exp | 4 + check/classic/classic.ref | 10 ++- check/internal/internal.exp | 4 + check/internal/internal.ref | 10 ++- check/threshold-1/threshold-1.exp | 4 + check/threshold-1/threshold-1.ref | 10 ++- check/threshold-3-0.5/threshold-3-0.5.exp | 4 + check/threshold-3-0.5/threshold-3-0.5.ref | 10 ++- docs/coding_style/CODING_STYLE.md | 99 +++++++++++++++++++++++ examples/docs/Makefile | 2 + examples/docs/coding_style/Makefile | 11 +++ examples/docs/coding_style/bind/Makefile | 12 +++ examples/docs/coding_style/bind/bind.ml | 4 + 13 files changed, 172 insertions(+), 12 deletions(-) create mode 100644 examples/docs/coding_style/Makefile create mode 100644 examples/docs/coding_style/bind/Makefile create mode 100644 examples/docs/coding_style/bind/bind.ml diff --git a/check/classic/classic.exp b/check/classic/classic.exp index 84b5e98..e757e8e 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -613,6 +615,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 1b14123..dedcf0f 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -618,6 +620,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -698,7 +702,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 581 -Success: 574 +Total: 583 +Success: 576 Failed: 7 -Ratio: 98.7951807229% +Ratio: 98.7993138937% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index 08398ab..cff039f 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -565,6 +567,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 9d79c4c..0cbac5b 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -570,6 +572,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -650,7 +654,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 537 -Success: 530 +Total: 539 +Success: 532 Failed: 7 -Ratio: 98.696461825% +Ratio: 98.7012987013% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index 6d5d62e..61066b4 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1020,6 +1022,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index a160bc5..9863bd3 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1024,6 +1026,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1104,7 +1108,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 916 -Success: 908 +Total: 918 +Success: 910 Failed: 8 -Ratio: 99.1266375546% +Ratio: 99.128540305% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index 0f4a43b..6079384 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1424,6 +1426,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 8e6323a..3dc654a 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1,5 +1,7 @@ .> UNUSED EXPORTED VALUES: ========================= +./examples/docs/coding_style/bind/bind.ml:2: v + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1428,6 +1430,8 @@ Nothing else to report in this section .> CODING STYLE: =============== +./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1508,7 +1512,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1236 -Success: 1228 +Total: 1238 +Success: 1230 Failed: 8 -Ratio: 99.3527508091% +Ratio: 99.3537964459% diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md index 79e58e7..f7b866a 100644 --- a/docs/coding_style/CODING_STYLE.md +++ b/docs/coding_style/CODING_STYLE.md @@ -2,6 +2,9 @@ + [Coding style](#coding-style) + [Usage](#usage) + + [Useless binding](#useless-binding) + + [Example](#bind-example) + + [Limitation](#bind-limitation) # Coding style @@ -45,3 +48,99 @@ There can be any number of such lines. The expected resolution depends on the reported issue category. This is described in their respective sections. + +## Useless binding + +A.k.a `bind`. +This issue is different from unused variables or unused values (for more +details, see the [Exported Values](../exported_values/EXPORTED_VALUES.md) +documentation). + +This stylistic issue category can be selectively activated by using the +`-S +bind` command line argument. +It can be deactivated by using the `-S -bind` command line argument. + +This category targets patterns of the form: +```OCaml +let x = ... in x +``` +I.e. the variable is immediately returned. + +The expected resolution is to remove the intermediate binding: +```Diff +- let x = + ... +- in x +``` + +### Example + +The reference files for this example are in the +[bind](../../examples/docs/coding_style/bind) directory. + +The reference takes place in `/tmp/docs/coding_style`, which +is a copy of the [coding\_style](../../examples/docs/coding_style) +directory. Reported locations may differ depending on the location of the source +files. + +The compilation command is : +``` +make -C bind build +``` + +The analysis command is : +``` +make -C bind analyze +``` + +The compile + analyze command is : +``` +make -C bind +``` + +Code: +```OCaml +(* bind.ml *) +let v = + let interm = 42 in + interm +``` + +Compile and analyze: +``` +$ make -C bind +make: Entering directory '/tmp/docs/coding_style/bind' +ocamlopt -bin-annot bind.ml +dead_code_analyzer --nothing -S +bind . +Scanning files... + [DONE] + +.> CODING STYLE: +=============== +/tmp/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) + +Nothing else to report in this section +-------------------------------------------------------------------------------- + + +make: Leaving directory '/tmp/docs/coding_style/bind' +``` + +The analyzer reports a coding style issue in `tmp/docs/coding_style/bind/bind.ml` +at line `3`. The reported issue is `let x = ... in x (=> useless binding)`, aka +a `bind` issue. + +The reported location points to `let interm = 42 in`. Removing the binding to +`interm` and replacing its use by its value (`42`) fixes the issue. + +Code: +```OCaml +(* bind.ml *) +let v = 42 +``` + +### Limitation + +`bind` issues are always reported with the same content : +`let x = ... in x (=> useless binding)`. The name of the variable is not +adapted to fit the actual name found in code (`interm` in the example above). diff --git a/examples/docs/Makefile b/examples/docs/Makefile index 0405a9b..87e4dab 100644 --- a/examples/docs/Makefile +++ b/examples/docs/Makefile @@ -7,6 +7,7 @@ build: make -C methods make -C fields_and_constructors make -C optional_arguments + make -C coding_style clean: rm -f *~ *.cm* *.o *.obj @@ -14,4 +15,5 @@ clean: make -C methods clean make -C fields_and_constructors clean make -C optional_arguments clean + make -C coding_style clean diff --git a/examples/docs/coding_style/Makefile b/examples/docs/coding_style/Makefile new file mode 100644 index 0000000..ab3d636 --- /dev/null +++ b/examples/docs/coding_style/Makefile @@ -0,0 +1,11 @@ +.PHONY: clean build + +all: build + +build: + make -C bind build + +clean: + rm -f *~ *.cm* *.o *.obj + make -C bind clean + diff --git a/examples/docs/coding_style/bind/Makefile b/examples/docs/coding_style/bind/Makefile new file mode 100644 index 0000000..6a6a793 --- /dev/null +++ b/examples/docs/coding_style/bind/Makefile @@ -0,0 +1,12 @@ +SRC:=bind.ml + +all: build analyze + +build: + ocamlopt -bin-annot ${SRC} + +analyze: + dead_code_analyzer --nothing -S +bind . + +clean: + rm -f *.cm* *.o a.out diff --git a/examples/docs/coding_style/bind/bind.ml b/examples/docs/coding_style/bind/bind.ml new file mode 100644 index 0000000..7c84adb --- /dev/null +++ b/examples/docs/coding_style/bind/bind.ml @@ -0,0 +1,4 @@ +(* bind.ml *) +let v = + let interm = 42 in + interm From c49c87440bfb15c6ef2a0e713fa2203db354dd38 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:51:27 +0200 Subject: [PATCH 3/7] [docs][style][3/n] add opt section Provide a short description of its usage, an example and its limitation. --- check/classic/classic.exp | 6 + check/classic/classic.ref | 12 +- check/internal/internal.exp | 6 + check/internal/internal.ref | 12 +- check/threshold-1/threshold-1.exp | 8 ++ check/threshold-1/threshold-1.ref | 14 ++- check/threshold-3-0.5/threshold-3-0.5.exp | 12 ++ check/threshold-3-0.5/threshold-3-0.5.ref | 18 ++- docs/coding_style/CODING_STYLE.md | 147 ++++++++++++++++++++++ examples/docs/coding_style/Makefile | 2 + examples/docs/coding_style/opt/Makefile | 12 ++ examples/docs/coding_style/opt/opt.ml | 16 +++ 12 files changed, 253 insertions(+), 12 deletions(-) create mode 100644 examples/docs/coding_style/opt/Makefile create mode 100644 examples/docs/coding_style/opt/opt.ml diff --git a/check/classic/classic.exp b/check/classic/classic.exp index e757e8e..c042b24 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -327,6 +329,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -617,6 +621,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/classic/classic.ref b/check/classic/classic.ref index dedcf0f..a2ddf10 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -332,6 +334,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -622,6 +626,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -702,7 +708,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 583 -Success: 576 +Total: 586 +Success: 579 Failed: 7 -Ratio: 98.7993138937% +Ratio: 98.8054607509% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index cff039f..e6c9dc6 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -279,6 +281,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -569,6 +573,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 0cbac5b..5c3e488 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -284,6 +286,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -574,6 +578,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -654,7 +660,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 539 -Success: 532 +Total: 542 +Success: 535 Failed: 7 -Ratio: 98.7012987013% +Ratio: 98.7084870849% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index 61066b4..6c2053c 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -110,6 +112,8 @@ .>-> ALMOST UNUSED EXPORTED VALUES: Called 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: map_with_index_on_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:3: memoize ./examples/docs/exported_values/code_constructs/function/function_lib.mli:5: heavy_computation ./examples/docs/exported_values/code_constructs/function/function_lib.mli:9: do_nothing @@ -734,6 +738,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -1024,6 +1030,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 9863bd3..27d702b 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -115,6 +117,8 @@ .>-> ALMOST UNUSED EXPORTED VALUES: Called 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: map_with_index_on_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:3: memoize ./examples/docs/exported_values/code_constructs/function/function_lib.mli:5: heavy_computation ./examples/docs/exported_values/code_constructs/function/function_lib.mli:9: do_nothing @@ -738,6 +742,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -1028,6 +1034,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1108,7 +1116,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 918 -Success: 910 +Total: 922 +Success: 914 Failed: 8 -Ratio: 99.128540305% +Ratio: 99.1323210412% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index 6079384..48835a0 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -110,6 +112,8 @@ .>-> ALMOST UNUSED EXPORTED VALUES: Called 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: map_with_index_on_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:3: memoize ./examples/docs/exported_values/code_constructs/function/function_lib.mli:5: heavy_computation ./examples/docs/exported_values/code_constructs/function/function_lib.mli:9: do_nothing @@ -959,6 +963,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -1118,6 +1124,8 @@ Nothing else to report in this section .>-> OPTIONAL ARGUMENTS: ALMOST ALWAYS: Except 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: ?index (1/2 calls) + ./examples/using_dune/preprocessed_lib/preprocessed.ml:59: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.ml:64: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.mli:44: ?sometimes (1/2 calls) @@ -1343,6 +1351,8 @@ Nothing else to report in this section .>-> OPTIONAL ARGUMENTS: ALMOST NEVER: Except 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: ?index (1/2 calls) + ./examples/using_dune/preprocessed_lib/preprocessed.ml:59: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.ml:64: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.mli:44: ?sometimes (1/2 calls) @@ -1428,6 +1438,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 3dc654a..89bf2bd 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -2,6 +2,8 @@ ========================= ./examples/docs/coding_style/bind/bind.ml:2: v +./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -115,6 +117,8 @@ .>-> ALMOST UNUSED EXPORTED VALUES: Called 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: map_with_index_on_negative + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:3: memoize ./examples/docs/exported_values/code_constructs/function/function_lib.mli:5: heavy_computation ./examples/docs/exported_values/code_constructs/function/function_lib.mli:9: do_nothing @@ -963,6 +967,8 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: ALWAYS: ============================= +./examples/docs/coding_style/opt/opt.ml:15: ?index + ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -1122,6 +1128,8 @@ Nothing else to report in this section .>-> OPTIONAL ARGUMENTS: ALMOST ALWAYS: Except 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: ?index (1/2 calls) + ./examples/using_dune/preprocessed_lib/preprocessed.ml:59: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.ml:64: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.mli:44: ?sometimes (1/2 calls) @@ -1347,6 +1355,8 @@ Nothing else to report in this section .>-> OPTIONAL ARGUMENTS: ALMOST NEVER: Except 1 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +./examples/docs/coding_style/opt/opt.ml:2: ?index (1/2 calls) + ./examples/using_dune/preprocessed_lib/preprocessed.ml:59: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.ml:64: ?sometimes (1/2 calls) ./examples/using_dune/preprocessed_lib/preprocessed.mli:44: ?sometimes (1/2 calls) @@ -1432,6 +1442,8 @@ Nothing else to report in this section =============== ./examples/docs/coding_style/bind/bind.ml:3: let x = ... in x (=> useless binding) +./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1512,7 +1524,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1238 -Success: 1230 +Total: 1244 +Success: 1236 Failed: 8 -Ratio: 99.3537964459% +Ratio: 99.3569131833% diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md index f7b866a..49cbb01 100644 --- a/docs/coding_style/CODING_STYLE.md +++ b/docs/coding_style/CODING_STYLE.md @@ -5,6 +5,9 @@ + [Useless binding](#useless-binding) + [Example](#bind-example) + [Limitation](#bind-limitation) + + [Optional arg in arg](#optional-arg-in-arg) + + [Example](#opt-example) + + [Limitation](#opt-limitation) # Coding style @@ -144,3 +147,147 @@ let v = 42 `bind` issues are always reported with the same content : `let x = ... in x (=> useless binding)`. The name of the variable is not adapted to fit the actual name found in code (`interm` in the example above). + + +## Optional arg in arg + +A.k.a `opt`. + +This stylistic issue category can be selectively activated by using the +`-S +opt` command line argument. +It can be deactivated by using the `-S -opt` command line argument. + +This category targets patterns of the form: +```OCaml +val f: ... -> (... -> ?_:_ -> ...) -> ... +``` +I.e. higher-order functions expecting a function with an optional argument. + +The expected resolution is to make the optional argument mandatory. + +### Example + +The reference files for this example are in the +[bindopt/../examples/docs/coding_style/bind) directory. + +The reference takes place in `/tmp/docs/coding_style`, which +is a copy of the [coding\_style](../../examples/docs/coding_style) +directory. Reported locations may differ depending on the location of the source +files. + +The compilation command is : +``` +make -C opt build +``` + +The analysis command is : +``` +make -C opt analyze +``` + +The compile + analyze command is : +``` +make -C opt +``` + +Code: +```OCaml +(* opt.ml *) +let map_with_index_on_negative (f : ?index:int -> int -> 'a) l = + let index = ref 0 in + let f' x = + let res = + if x < 0 then f ~index:(!index) x + else f x + in + incr index; + res + in + List.map f' l + +let add_index_to_negative l = + let add_index ?(index=0) x = x + index in + map_with_index_on_negative add_index l +``` + +Compile and analyze: +``` +$ make -C opt +make: Entering directory '/tmp/docs/coding_style/opt' +ocamlopt -bin-annot opt.ml +dead_code_analyzer --nothing -S +opt . +Scanning files... + [DONE] + +.> CODING STYLE: +=============== +/tmp/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... + +Nothing else to report in this section +-------------------------------------------------------------------------------- + + +make: Leaving directory '/tmp/docs/coding_style/opt' +``` + +The analyzer reports a coding style issue in `/tmp/docs/coding_style/opt/opt.ml` +at line `2`. The reported issue is `val f: ... -> (... -> ?_:_ -> ...) -> ...`, +aka an `opt` issue. + +The reported location points to `let map_with_index_on_negative ...` which +expects a function as argument (`f`), which itself expects an optional argument (`?index`). +Making `?index` mandatory, and updating the code accordingly, fixes the issue. + +Code: +```OCaml +(* opt.ml *) +let map_with_index_on_negative f l = + let index = ref 0 in + let f' x = + let res = + if x < 0 then f ~index:(Some !index) x + else f ~index:None x + in + incr index; + res + in + List.map f' l + +let add_index_to_negative l = + let add_index ?(index=0) x = x + index in + let add_index ~index = add_index ?index in + map_with_index_on_negative add_index l +``` + +> [!NOTE] +> We made `~index` madatory but changed its type to an option, and added a +> redefinition of `add_index` to convert the mandatory argument into the +> optional one. This is the "easiest" and most re-appliable solution for this +> issue but not necessarily the best one. Context is key to decide on the +> refactors that should help resolve the issue. +> E.g. in this example, a possible refactor would be : +> ```OCaml +> (* opt.ml *) +> let map_with_index f l = +> let index = ref 0 in +> let f' x = +> let res = f ~index:(!index) x in +> incr index; +> res +> in +> List.map f' l +> +> let add_index_to_negative l = +> let add_index_to_negative ~index x = +> if x < 0 then x + index +> else x +> in +> map_with_index add_index_to_negative l +> ``` + +### Limitation + +`opt` issues are always reported with the same content : +`val f: ... -> (... -> ?_:_ -> ...) -> ...`. The name of the function is not +adapted to fit the actual name found in code (`map_with_index_on_negative` in +the example above). diff --git a/examples/docs/coding_style/Makefile b/examples/docs/coding_style/Makefile index ab3d636..35cc16d 100644 --- a/examples/docs/coding_style/Makefile +++ b/examples/docs/coding_style/Makefile @@ -4,8 +4,10 @@ all: build build: make -C bind build + make -C opt build clean: rm -f *~ *.cm* *.o *.obj make -C bind clean + make -C opt clean diff --git a/examples/docs/coding_style/opt/Makefile b/examples/docs/coding_style/opt/Makefile new file mode 100644 index 0000000..d2b4f6c --- /dev/null +++ b/examples/docs/coding_style/opt/Makefile @@ -0,0 +1,12 @@ +SRC:=opt.ml + +all: build analyze + +build: + ocamlopt -bin-annot ${SRC} + +analyze: + dead_code_analyzer --nothing -S +opt . + +clean: + rm -f *.cm* *.o a.out diff --git a/examples/docs/coding_style/opt/opt.ml b/examples/docs/coding_style/opt/opt.ml new file mode 100644 index 0000000..f40883c --- /dev/null +++ b/examples/docs/coding_style/opt/opt.ml @@ -0,0 +1,16 @@ +(* opt.ml *) +let map_with_index_on_negative (f : ?index:int -> int -> 'a) l = + let index = ref 0 in + let f' x = + let res = + if x < 0 then f ~index:(!index) x + else f x + in + incr index; + res + in + List.map f' l + +let add_index_to_negative l = + let add_index ?(index=0) x = x + index in + map_with_index_on_negative add_index l From d38f78a462ce0424c9c897765d54cfb3c5ec3cfb Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 9 Apr 2026 15:53:24 +0200 Subject: [PATCH 4/7] [docs][style][4/n] add seq section Provide a short description of its usage and an example --- check/classic/classic.exp | 4 + check/classic/classic.ref | 10 ++- check/internal/internal.exp | 4 + check/internal/internal.ref | 10 ++- check/threshold-1/threshold-1.exp | 4 + check/threshold-1/threshold-1.ref | 10 ++- check/threshold-3-0.5/threshold-3-0.5.exp | 4 + check/threshold-3-0.5/threshold-3-0.5.ref | 10 ++- docs/coding_style/CODING_STYLE.md | 97 +++++++++++++++++++++++ examples/docs/coding_style/Makefile | 2 + examples/docs/coding_style/seq/Makefile | 12 +++ examples/docs/coding_style/seq/seq.ml | 4 + 12 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 examples/docs/coding_style/seq/Makefile create mode 100644 examples/docs/coding_style/seq/seq.ml diff --git a/check/classic/classic.exp b/check/classic/classic.exp index c042b24..5775989 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -623,6 +625,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/classic/classic.ref b/check/classic/classic.ref index a2ddf10..ace794b 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -628,6 +630,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -708,7 +712,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 586 -Success: 579 +Total: 588 +Success: 581 Failed: 7 -Ratio: 98.8054607509% +Ratio: 98.8095238095% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index e6c9dc6..f01b624 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -575,6 +577,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 5c3e488..471e300 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -580,6 +582,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -660,7 +664,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 542 -Success: 535 +Total: 544 +Success: 537 Failed: 7 -Ratio: 98.7084870849% +Ratio: 98.7132352941% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index 6c2053c..2315696 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1032,6 +1034,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 27d702b..ff2bd20 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1036,6 +1038,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1116,7 +1120,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 922 -Success: 914 +Total: 924 +Success: 916 Failed: 8 -Ratio: 99.1323210412% +Ratio: 99.1341991342% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index 48835a0..e1bec62 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1440,6 +1442,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 89bf2bd..7d5398b 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -4,6 +4,8 @@ ./examples/docs/coding_style/opt/opt.ml:14: add_index_to_negative +./examples/docs/coding_style/seq/seq.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1444,6 +1446,8 @@ Nothing else to report in this section ./examples/docs/coding_style/opt/opt.ml:2: val f: ... -> (... -> ?_:_ -> ...) -> ... +./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1524,7 +1528,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1244 -Success: 1236 +Total: 1246 +Success: 1238 Failed: 8 -Ratio: 99.3569131833% +Ratio: 99.3579454254% diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md index 49cbb01..31cadbd 100644 --- a/docs/coding_style/CODING_STYLE.md +++ b/docs/coding_style/CODING_STYLE.md @@ -8,6 +8,8 @@ + [Optional arg in arg](#optional-arg-in-arg) + [Example](#opt-example) + [Limitation](#opt-limitation) + + [Use sequence](#use-sequence) + + [Example](#seq-example) # Coding style @@ -291,3 +293,98 @@ let add_index_to_negative l = `val f: ... -> (... -> ?_:_ -> ...) -> ...`. The name of the function is not adapted to fit the actual name found in code (`map_with_index_on_negative` in the example above). + +## Use sequence + +A.k.a `seq`. + +This stylistic issue category can be selectively activated by using the +`-S +seq` command line argument. +It can be deactivated by using the `-S -seq` command line argument. + +This category targets patterns of the form: +```OCaml +let () = e1 in e2 +``` +I.e. binding to unit instead of using a sequence. + +The expected resolution is to use a sequence instead of the intermediate binding: +```OCaml +e1; +e2 +``` + +> [!TIP] +> If you are using this pattern to ensure `e1` is of type `unit`, the compiler +> will report a warning 10 `non-unit-statement` when using the suggested +> sequence pattern if `e1` is not `unit`. Alternatively, you may use a type +> annotation `(e1 : unit)` to enforce it and the compiler will report an error +> if `e1` is not `unit`. + +### Example + +The reference files for this example are in the +[seq](../../examples/docs/coding_style/seq) directory. + +The reference takes place in `/tmp/docs/coding_style`, which +is a copy of the [coding\_style](../../examples/docs/coding_style) +directory. Reported locations may differ depending on the location of the source +files. + +The compilation command is : +``` +make -C seq build +``` + +The analysis command is : +``` +make -C seq analyze +``` + +The compile + analyze command is : +``` +make -C seq +``` + +Code: +```OCaml +(* seq.ml *) +let compute_answer () = + let () = print_endline "Computing answer" in + 42 +``` + +Compile and analyze: +``` +$ make -C seq +make: Entering directory '/tmp/docs/coding_style/seq' +ocamlopt -bin-annot seq.ml +dead_code_analyzer --nothing -S +seq . +Scanning files... + [DONE] + +.> CODING STYLE: +=============== +/tmp/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) + +Nothing else to report in this section +-------------------------------------------------------------------------------- + + +make: Leaving directory '/tmp/docs/coding_style/seq' +``` + +The analyzer reports a coding style issue in `tmp/docs/coding_style/seq/seq.ml` +at line `3`. The reported issue is `let () = ... in ... (=> use sequence)`, aka +a `seq` issue. + +The reported location points to `let () = print_endline "Computing answer" in` +which can be replaced by a sequence `print_endline "Computing answer;` + +Code: +```OCaml +(* seq.ml *) +let compute_answer () = + print_endline "Computing answer"; + 42 +``` diff --git a/examples/docs/coding_style/Makefile b/examples/docs/coding_style/Makefile index 35cc16d..63811a2 100644 --- a/examples/docs/coding_style/Makefile +++ b/examples/docs/coding_style/Makefile @@ -5,9 +5,11 @@ all: build build: make -C bind build make -C opt build + make -C seq build clean: rm -f *~ *.cm* *.o *.obj make -C bind clean make -C opt clean + make -C seq clean diff --git a/examples/docs/coding_style/seq/Makefile b/examples/docs/coding_style/seq/Makefile new file mode 100644 index 0000000..756b331 --- /dev/null +++ b/examples/docs/coding_style/seq/Makefile @@ -0,0 +1,12 @@ +SRC:=seq.ml + +all: build analyze + +build: + ocamlopt -bin-annot ${SRC} + +analyze: + dead_code_analyzer --nothing -S +seq . + +clean: + rm -f *.cm* *.o a.out diff --git a/examples/docs/coding_style/seq/seq.ml b/examples/docs/coding_style/seq/seq.ml new file mode 100644 index 0000000..8db329b --- /dev/null +++ b/examples/docs/coding_style/seq/seq.ml @@ -0,0 +1,4 @@ +(* seq.ml *) +let compute_answer () = + let () = print_endline "Computing answer" in + 42 From 45808f15eb8432110641633a80954e07ad655ad1 Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:49:30 +0200 Subject: [PATCH 5/7] [docs][style][5/n] add unit section Provide a short description of its usage, an example and limitation. --- check/classic/classic.exp | 7 ++ check/classic/classic.ref | 16 ++- check/internal/internal.exp | 7 ++ check/internal/internal.ref | 16 ++- check/threshold-1/threshold-1.exp | 7 ++ check/threshold-1/threshold-1.ref | 16 ++- check/threshold-3-0.5/threshold-3-0.5.exp | 7 ++ check/threshold-3-0.5/threshold-3-0.5.ref | 16 ++- docs/coding_style/CODING_STYLE.md | 128 ++++++++++++++++++++++ examples/docs/coding_style/Makefile | 2 + examples/docs/coding_style/unit/Makefile | 12 ++ examples/docs/coding_style/unit/unit.ml | 6 + 12 files changed, 224 insertions(+), 16 deletions(-) create mode 100644 examples/docs/coding_style/unit/Makefile create mode 100644 examples/docs/coding_style/unit/unit.ml diff --git a/check/classic/classic.exp b/check/classic/classic.exp index 5775989..fa87157 100644 --- a/check/classic/classic.exp +++ b/check/classic/classic.exp @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -627,6 +629,11 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/classic/classic.ref b/check/classic/classic.ref index ace794b..60be838 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:9: F.internally_used @@ -632,6 +634,12 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r +./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -712,7 +720,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 588 -Success: 581 -Failed: 7 -Ratio: 98.8095238095% +Total: 595 +Success: 586 +Failed: 9 +Ratio: 98.487394958% diff --git a/check/internal/internal.exp b/check/internal/internal.exp index f01b624..899c4c9 100644 --- a/check/internal/internal.exp +++ b/check/internal/internal.exp @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -579,6 +581,11 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 471e300..458f8c8 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -584,6 +586,12 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r +./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -664,7 +672,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 544 -Success: 537 -Failed: 7 -Ratio: 98.7132352941% +Total: 551 +Success: 542 +Failed: 9 +Ratio: 98.3666061706% diff --git a/check/threshold-1/threshold-1.exp b/check/threshold-1/threshold-1.exp index 2315696..65c58dc 100644 --- a/check/threshold-1/threshold-1.exp +++ b/check/threshold-1/threshold-1.exp @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1036,6 +1038,11 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index ff2bd20..74445a5 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1040,6 +1042,12 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r +./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1120,7 +1128,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 924 -Success: 916 -Failed: 8 -Ratio: 99.1341991342% +Total: 931 +Success: 921 +Failed: 10 +Ratio: 98.9258861439% diff --git a/check/threshold-3-0.5/threshold-3-0.5.exp b/check/threshold-3-0.5/threshold-3-0.5.exp index e1bec62..93d15ad 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.exp +++ b/check/threshold-3-0.5/threshold-3-0.5.exp @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1444,6 +1446,11 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 7d5398b..d9f81d3 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -6,6 +6,8 @@ ./examples/docs/coding_style/seq/seq.ml:2: compute_answer +./examples/docs/coding_style/unit/unit.ml:2: compute_answer + ./examples/docs/exported_values/code_constructs/function/function_lib.mli:7: unused ./examples/docs/exported_values/code_constructs/functor/functor_lib.mli:10: F.unused @@ -1448,6 +1450,12 @@ Nothing else to report in this section ./examples/docs/coding_style/seq/seq.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:2: unit pattern input +./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) +./examples/docs/coding_style/unit/unit.ml:3: unit pattern print +./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected +./examples/docs/coding_style/unit/unit.ml:5: unit pattern r +./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1528,7 +1536,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1246 -Success: 1238 -Failed: 8 -Ratio: 99.3579454254% +Total: 1253 +Success: 1243 +Failed: 10 +Ratio: 99.201915403% diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md index 31cadbd..aacb961 100644 --- a/docs/coding_style/CODING_STYLE.md +++ b/docs/coding_style/CODING_STYLE.md @@ -10,6 +10,9 @@ + [Limitation](#opt-limitation) + [Use sequence](#use-sequence) + [Example](#seq-example) + + [Unit pattern](#unit-pattern) + + [Example](#unit-example) + + [Limitation](#unit-limitation) # Coding style @@ -388,3 +391,128 @@ let compute_answer () = print_endline "Computing answer"; 42 ``` + +## Unit pattern + +A.k.a `unit`. + +This stylistic issue category can be selectively activated by using the +`-S +unit` command line argument. +It can be deactivated by using the `-S -unit` command line argument. + +This category targets patterns giving a name to expressions of type `unit`. + +The expected resolution is to use `()` in place of the name. + +### Example + +The reference files for this example are in the +[unit](../../examples/docs/coding_style/unit) directory. + +The reference takes place in `/tmp/docs/coding_style`, which +is a copy of the [coding\_style](../../examples/docs/coding_style) +directory. Reported locations may differ depending on the location of the source +files. + +The compilation command is : +``` +make -C unit build +``` + +The analysis command is : +``` +make -C unit analyze +``` + +The compile + analyze command is : +``` +make -C unit +``` + +Code: +```OCaml +(* unit.ml *) +let compute_answer input = + let print = print_endline "Computing answer" in + match print with + | r when input = print -> 42 + | _ -> assert false +``` + +Compile and analyze: +``` +$ make -C unit +make -C unit +make: Entering directory '/tmp/docs/coding_style/unit' +ocamlopt -bin-annot unit.ml +dead_code_analyzer --nothing -S +unit . +Scanning files... + [DONE] + +.> CODING STYLE: +=============== +/tmp/docs/coding_style/unit/unit.ml:2: unit pattern input +/tmp/docs/coding_style/unit/unit.ml:3: unit pattern print +/tmp/docs/coding_style/unit/unit.ml:5: unit pattern other +/tmp/docs/coding_style/unit/unit.ml:5: unit pattern r +/tmp/docs/coding_style/unit/unit.ml:6: unit pattern other + +Nothing else to report in this section +-------------------------------------------------------------------------------- + + +make: Leaving directory '/tmp/docs/coding_style/unit' +``` + +The analyzer reports 5 coding style issues in `tmp/docs/coding_style/unit/unit.ml`. +They all have the form `unit pattern `. Among them, the to reported +`other` are actually duplicates due to a limitation. Let's ignore them. + +> [!IMPORTANT] +> **Limitation** +> +> In some cases, the analyzer may report `other` instead of the actual pattern. +> This happens for patterns matching more complex expressions than names. + +The names listed (`input`, `print, `r`) are the values of type `unit`. + +> [!TIP] +> Using the `--underscore` command line argument of the `dead_code_analyzer` +> will trigger the reports for values named `_` or with names prefixed by `_`. + +Fixing the reports be done by replacing the reported values by `()`. + +Code: +```OCaml +(* unit.ml *) +let compute_answer () = + let () = print_endline "Computing answer" in + match () with + | () when () = () -> 42 + | _ -> assert false +``` + +Now this code can be further simplified by removing the useless pattern matching. + +Code: +```OCaml +(* unit.ml *) +let compute_answer () = + let () = print_endline "Computing answer" in + 42 +``` + +This can be further improved as detailed in the above +[Use sequence example](#seq-example). To trigger the `seq` reports, add `+seq` +to the `-S +unit` command line argument in the `Makefile` : +```Diff +analyze: +- dead_code_analyzer --nothing -S +unit . ++ dead_code_analyzer --nothing -S +unit+seq . +``` + +### Limitation + +As demonstrated in the example, in some cases, the analyzer may report `other` +instead of the actual pattern of type `unit`. This happens for patterns that are +more complex expressions than names. diff --git a/examples/docs/coding_style/Makefile b/examples/docs/coding_style/Makefile index 63811a2..55a9ef4 100644 --- a/examples/docs/coding_style/Makefile +++ b/examples/docs/coding_style/Makefile @@ -6,10 +6,12 @@ build: make -C bind build make -C opt build make -C seq build + make -C unit build clean: rm -f *~ *.cm* *.o *.obj make -C bind clean make -C opt clean make -C seq clean + make -C unit clean diff --git a/examples/docs/coding_style/unit/Makefile b/examples/docs/coding_style/unit/Makefile new file mode 100644 index 0000000..f3c34a7 --- /dev/null +++ b/examples/docs/coding_style/unit/Makefile @@ -0,0 +1,12 @@ +SRC:=unit.ml + +all: build analyze + +build: + ocamlopt -bin-annot ${SRC} + +analyze: + dead_code_analyzer --nothing -S +unit . + +clean: + rm -f *.cm* *.o a.out diff --git a/examples/docs/coding_style/unit/unit.ml b/examples/docs/coding_style/unit/unit.ml new file mode 100644 index 0000000..160a73f --- /dev/null +++ b/examples/docs/coding_style/unit/unit.ml @@ -0,0 +1,6 @@ +(* unit.ml *) +let compute_answer input = + let print = print_endline "Computing answer" in + match print with + | r when input = print -> 42 + | _ -> assert false From 963d8fe607e79d8d596ac153f13c9e62d34fe3ea Mon Sep 17 00:00:00 2001 From: Corentin De Souza <9597216+fantazio@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:25:06 +0200 Subject: [PATCH 6/7] [src][deadCode] improve unit binding issue report Issue reports on unit binding may be duplicated with `other` in case the `Tpat_value` subpattern is not a `Tpat_construct`. This adds the other understood patterns to the list of "silenced" patterns in `Tpat_value`. This also updates the reported "unknown" unit patterns as `!!patern!!`. The FP introduced in the previous example are now fixed. The docs is fixed accordingly. --- check/classic/classic.ref | 9 ++++----- check/internal/internal.ref | 9 ++++----- check/threshold-1/threshold-1.ref | 9 ++++----- check/threshold-3-0.5/threshold-3-0.5.ref | 9 ++++----- docs/coding_style/CODING_STYLE.md | 20 +++++--------------- src/deadCode.ml | 6 +++--- 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 60be838..35ae2f3 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -637,9 +637,8 @@ Nothing else to report in this section ./examples/docs/coding_style/unit/unit.ml:2: unit pattern input ./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) ./examples/docs/coding_style/unit/unit.ml:3: unit pattern print -./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected ./examples/docs/coding_style/unit/unit.ml:5: unit pattern r -./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -720,7 +719,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 595 +Total: 593 Success: 586 -Failed: 9 -Ratio: 98.487394958% +Failed: 7 +Ratio: 98.8195615514% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index 458f8c8..5c83976 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -589,9 +589,8 @@ Nothing else to report in this section ./examples/docs/coding_style/unit/unit.ml:2: unit pattern input ./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) ./examples/docs/coding_style/unit/unit.ml:3: unit pattern print -./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected ./examples/docs/coding_style/unit/unit.ml:5: unit pattern r -./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -672,7 +671,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 551 +Total: 549 Success: 542 -Failed: 9 -Ratio: 98.3666061706% +Failed: 7 +Ratio: 98.7249544627% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 74445a5..eb6e126 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -1045,9 +1045,8 @@ Nothing else to report in this section ./examples/docs/coding_style/unit/unit.ml:2: unit pattern input ./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) ./examples/docs/coding_style/unit/unit.ml:3: unit pattern print -./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected ./examples/docs/coding_style/unit/unit.ml:5: unit pattern r -./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1128,7 +1127,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 931 +Total: 929 Success: 921 -Failed: 10 -Ratio: 98.9258861439% +Failed: 8 +Ratio: 99.1388589882% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index d9f81d3..f3f1da5 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -1453,9 +1453,8 @@ Nothing else to report in this section ./examples/docs/coding_style/unit/unit.ml:2: unit pattern input ./examples/docs/coding_style/unit/unit.ml:3: let () = ... in ... (=> use sequence) ./examples/docs/coding_style/unit/unit.ml:3: unit pattern print -./examples/docs/coding_style/unit/unit.ml:5: unit pattern other: Should not be detected ./examples/docs/coding_style/unit/unit.ml:5: unit pattern r -./examples/docs/coding_style/unit/unit.ml:6: unit pattern other: Should not be detected + ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:16: unit pattern used_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:17: unit pattern unused_required ./examples/docs/exported_values/code_constructs/functor/functor_lib.ml:21: unit pattern used_required @@ -1536,7 +1535,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1253 +Total: 1251 Success: 1243 -Failed: 10 -Ratio: 99.201915403% +Failed: 8 +Ratio: 99.3605115907% diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md index aacb961..acdabc9 100644 --- a/docs/coding_style/CODING_STYLE.md +++ b/docs/coding_style/CODING_STYLE.md @@ -453,9 +453,7 @@ Scanning files... =============== /tmp/docs/coding_style/unit/unit.ml:2: unit pattern input /tmp/docs/coding_style/unit/unit.ml:3: unit pattern print -/tmp/docs/coding_style/unit/unit.ml:5: unit pattern other /tmp/docs/coding_style/unit/unit.ml:5: unit pattern r -/tmp/docs/coding_style/unit/unit.ml:6: unit pattern other Nothing else to report in this section -------------------------------------------------------------------------------- @@ -464,16 +462,8 @@ Nothing else to report in this section make: Leaving directory '/tmp/docs/coding_style/unit' ``` -The analyzer reports 5 coding style issues in `tmp/docs/coding_style/unit/unit.ml`. -They all have the form `unit pattern `. Among them, the to reported -`other` are actually duplicates due to a limitation. Let's ignore them. - -> [!IMPORTANT] -> **Limitation** -> -> In some cases, the analyzer may report `other` instead of the actual pattern. -> This happens for patterns matching more complex expressions than names. - +The analyzer reports 3 coding style issues in `tmp/docs/coding_style/unit/unit.ml`. +They all have the form `unit pattern `. The names listed (`input`, `print, `r`) are the values of type `unit`. > [!TIP] @@ -513,6 +503,6 @@ analyze: ### Limitation -As demonstrated in the example, in some cases, the analyzer may report `other` -instead of the actual pattern of type `unit`. This happens for patterns that are -more complex expressions than names. +In some cases, the analyzer may report `!!pattern!!` instead of the actual +pattern of type `unit`. This happens for patterns that are more complex patterns +than names. diff --git a/src/deadCode.ml b/src/deadCode.ml index a05a491..faaf0fa 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -228,10 +228,10 @@ let pat: type k. Tast_mapper.mapper -> Tast_mapper.mapper -> k general_pattern - | Tpat_any -> if state.config.underscore then u "_" | Tpat_value tpat_arg -> begin match (tpat_arg :> value general_pattern) with - | {pat_desc=Tpat_construct _; _} -> () - | _ -> u "other" + | {pat_desc=(Tpat_construct _ | Tpat_var _ | Tpat_any); _} -> () + | _ -> u "!!pattern!!" end - | _ -> u "" + | _ -> u "!!pattern!!" end; begin match p.pat_desc with | Tpat_record (l, _) -> From 139ba16ef18bb0b2c75813ee85e5e0a16466729c Mon Sep 17 00:00:00 2001 From: Corentin De Souza Date: Mon, 13 Apr 2026 15:58:36 +0200 Subject: [PATCH 7/7] [docs][style][6/n] fix typos and wordings Apply suggestions from code review Co-authored-by: Corentin De Souza --- docs/coding_style/CODING_STYLE.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/coding_style/CODING_STYLE.md b/docs/coding_style/CODING_STYLE.md index acdabc9..e4f58c5 100644 --- a/docs/coding_style/CODING_STYLE.md +++ b/docs/coding_style/CODING_STYLE.md @@ -35,7 +35,7 @@ Their reports can be activated by using the `--all` or `-S +all` command line arguments. They can be deactivated by using the `--nothing` or `-S -all` command line arguments. -Each of the sylistic issue category can be selectively activated/decativated as +Each of the sylistic issue category can be selectively activated/deactivated as described in their respective sections. For more details about the command line arguments see [the more general Usage documentation](../USAGE.md). @@ -134,7 +134,7 @@ Nothing else to report in this section make: Leaving directory '/tmp/docs/coding_style/bind' ``` -The analyzer reports a coding style issue in `tmp/docs/coding_style/bind/bind.ml` +The analyzer reports a coding style issue in `/tmp/docs/coding_style/bind/bind.ml` at line `3`. The reported issue is `let x = ... in x (=> useless binding)`, aka a `bind` issue. @@ -162,7 +162,7 @@ This stylistic issue category can be selectively activated by using the `-S +opt` command line argument. It can be deactivated by using the `-S -opt` command line argument. -This category targets patterns of the form: +This category targets functions with types of the form: ```OCaml val f: ... -> (... -> ?_:_ -> ...) -> ... ``` @@ -173,7 +173,7 @@ The expected resolution is to make the optional argument mandatory. ### Example The reference files for this example are in the -[bindopt/../examples/docs/coding_style/bind) directory. +[opt](../../examples/docs/coding_style/opt) directory. The reference takes place in `/tmp/docs/coding_style`, which is a copy of the [coding\_style](../../examples/docs/coding_style) @@ -295,7 +295,8 @@ let add_index_to_negative l = `opt` issues are always reported with the same content : `val f: ... -> (... -> ?_:_ -> ...) -> ...`. The name of the function is not adapted to fit the actual name found in code (`map_with_index_on_negative` in -the example above). +the example above), and the names of the parameters (`f` and `?index` in the +example above) are not shown. ## Use sequence @@ -377,7 +378,7 @@ Nothing else to report in this section make: Leaving directory '/tmp/docs/coding_style/seq' ``` -The analyzer reports a coding style issue in `tmp/docs/coding_style/seq/seq.ml` +The analyzer reports a coding style issue in `/tmp/docs/coding_style/seq/seq.ml` at line `3`. The reported issue is `let () = ... in ... (=> use sequence)`, aka a `seq` issue. @@ -462,15 +463,15 @@ Nothing else to report in this section make: Leaving directory '/tmp/docs/coding_style/unit' ``` -The analyzer reports 3 coding style issues in `tmp/docs/coding_style/unit/unit.ml`. +The analyzer reports 3 coding style issues in `/tmp/docs/coding_style/unit/unit.ml`. They all have the form `unit pattern `. -The names listed (`input`, `print, `r`) are the values of type `unit`. +The names listed (`input`, `print`, `r`) are the values of type `unit`. > [!TIP] > Using the `--underscore` command line argument of the `dead_code_analyzer` > will trigger the reports for values named `_` or with names prefixed by `_`. -Fixing the reports be done by replacing the reported values by `()`. +Fixing the reports is done by replacing the reported values by `()`. Code: ```OCaml @@ -504,5 +505,5 @@ analyze: ### Limitation In some cases, the analyzer may report `!!pattern!!` instead of the actual -pattern of type `unit`. This happens for patterns that are more complex patterns +pattern of type `unit`. This happens for patterns that are more complex than names.