File 4331-EEP-61-Built-in-dynamic-type.patch of Package erlang
From 048e62b9041d84958f1e089b4ae3d4666004269e Mon Sep 17 00:00:00 2001
From: Ilya Klyuchnikov <ilya.klyuchnikov@gmail.com>
Date: Mon, 6 Mar 2023 23:10:06 +0000
Subject: [PATCH] EEP 61: Built-in dynamic type
---
erts/preloaded/src/erlang.erl | 3 ++-
lib/dialyzer/src/erl_types.erl | 3 +++
lib/stdlib/src/erl_internal.erl | 1 +
system/doc/reference_manual/typespec.xml | 17 ++++++++++++++++-
4 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 923b0ad806..ddb81dfc76 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -86,6 +86,7 @@
-type boolean() :: true | false.
-type byte() :: 0..255.
-type char() :: 0..16#10FFFF.
+-type dynamic() :: dynamic().
-type float() :: float().
-type function() :: fun().
-type identifier() :: pid() | port() | reference().
@@ -123,7 +124,7 @@
-type timeout() :: 'infinity' | non_neg_integer().
-type tuple() :: tuple().
-export_type([any/0, arity/0, atom/0, binary/0, bitstring/0, bool/0, boolean/0, byte/0,
- char/0, float/0, function/0, identifier/0, integer/0, iodata/0, iolist/0,
+ char/0, dynamic/0, float/0, function/0, identifier/0, integer/0, iodata/0, iolist/0,
list/0, list/1, map/0, maybe_improper_list/0, maybe_improper_list/2, mfa/0,
module/0, neg_integer/0, nil/0, no_return/0, node/0, non_neg_integer/0,
none/0, nonempty_binary/0, nonempty_bitstring/0, nonempty_improper_list/2,
diff --git a/lib/dialyzer/src/erl_types.erl b/lib/dialyzer/src/erl_types.erl
index 9943996882..8068baf8e8 100644
--- a/lib/dialyzer/src/erl_types.erl
+++ b/lib/dialyzer/src/erl_types.erl
@@ -4394,6 +4394,8 @@ from_form({type, _Anno, byte, []}, _S, _D, L, C) ->
{t_byte(), L, C};
from_form({type, _Anno, char, []}, _S, _D, L, C) ->
{t_char(), L, C};
+from_form({type, _Anno, dynamic, []}, _S, _D, L, C) ->
+ {t_any(), L, C};
from_form({type, _Anno, float, []}, _S, _D, L, C) ->
{t_float(), L, C};
from_form({type, _Anno, function, []}, _S, _D, L, C) ->
@@ -5062,6 +5064,7 @@ t_form_to_string({type, _Anno, binary, [Base, Unit]} = Type) ->
_ -> io_lib:format("Badly formed bitstr type ~w", [Type])
end;
t_form_to_string({type, _Anno, bitstring, []}) -> "bitstring()";
+t_form_to_string({type, _Anno, dynamic, []}) -> "dynamic()";
t_form_to_string({type, _Anno, 'fun', []}) -> "fun()";
t_form_to_string({type, _Anno, 'fun', [{type, _, any}, Range]}) ->
"fun(...) -> " ++ t_form_to_string(Range);
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index 8453c1e7b7..1ac604a363 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.erl
@@ -566,6 +566,7 @@ is_type(bool, 0) -> true;
is_type(boolean, 0) -> true;
is_type(byte, 0) -> true;
is_type(char, 0) -> true;
+is_type(dynamic, 0) -> true;
is_type(float, 0) -> true;
is_type(function, 0) -> true;
is_type(identifier, 0) -> true;
diff --git a/system/doc/reference_manual/typespec.xml b/system/doc/reference_manual/typespec.xml
index e4b9c4f62c..fa751834f6 100644
--- a/system/doc/reference_manual/typespec.xml
+++ b/system/doc/reference_manual/typespec.xml
@@ -83,17 +83,32 @@
</p>
<pre> atom() | integer()</pre>
<p>
- Because of subtype relations that exist between types, types
+ Because of subtype relations that exist between types, all types,
+ except <c>dynamic()</c>,
form a lattice where the top-most element, <c>any()</c>, denotes
the set of all Erlang terms and the bottom-most element, <c>none()</c>,
denotes the empty set of terms.
</p>
+ <p>
+ To facilitate <url href="https://en.wikipedia.org/wiki/Gradual_typing">
+ gradual typing</url> of Erlang, the type `dynamic()` is provided.
+ It is similar to
+ <url href="https://docs.python.org/3/library/typing.html#the-any-type">Any</url>
+ in Python,
+ <url href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any">any</url>
+ in TypeScript and
+ <url href="https://docs.hhvm.com/hack/built-in-types/dynamic">dynamic</url>
+ in Hack. `any()` and `dynamic()` interact with
+ <url href="https://learnyousomeerlang.com/dialyzer#success-typing">success typing</url>
+ the same way, so Dialyzer doesn't distinguish between them.
+ </p>
<p>
The set of predefined types and the syntax for types follows:
</p>
<pre><![CDATA[
Type :: any() %% The top type, the set of all Erlang terms
| none() %% The bottom type, contains no terms
+ | dynamic()
| pid()
| port()
| reference()
--
2.35.3