From 274e5b47bfbc86e8b9591134f28da9ef68f87221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 14 May 2014 17:07:38 +0200 Subject: doc: Move Maps reference documentation to expressions --- system/doc/reference_manual/expressions.xml | 238 ++++++++++++++++++++++++ system/doc/reference_manual/maps.xml | 274 ---------------------------- system/doc/reference_manual/part.xml | 1 - system/doc/reference_manual/xmlfiles.mk | 1 - 4 files changed, 238 insertions(+), 276 deletions(-) delete mode 100644 system/doc/reference_manual/maps.xml diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml index 37208710fe..0ca425da86 100644 --- a/system/doc/reference_manual/expressions.xml +++ b/system/doc/reference_manual/expressions.xml @@ -791,6 +791,244 @@ Expr1 -- Expr2 long lists.

+
+ Map Expressions +
+ Creating Maps +

+ Constructing a new map is done by letting an expression K be associated with + another expression V: +

+ #{ K => V } +

+ New maps may include multiple associations at construction by listing every + association: +

+ #{ K1 => V1, .., Kn => Vn } +

+ An empty map is constructed by not associating any terms with each other: +

+ #{} +

+ All keys and values in the map are terms. Any expression is first evaluated and + then the resulting terms are used as key and value respectively. +

+

+ Keys and values are separated by the => arrow and associations are + separated by ,. +

+ +

+ Examples: +

+ +M0 = #{}, % empty map +M1 = #{a => <<"hello">>}, % single association with literals +M2 = #{1 => 2, b => b}, % multiple associations with literals +M3 = #{k => {A,B}}, % single association with variables +M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression +

+ where, A and B are any expressions and M0 through M4 + are the resulting map terms. +

+

+ If two matching keys are declared, the latter key will take precedence. +

+

+ Example: +

+ +
+1> #{1 => a, 1 => b}.
+#{1 => b }
+2> #{1.0 => a, 1 => b}.
+#{1 => b, 1.0 => a}
+
+

+ The order in which the expressions constructing the keys and their + associated values are evaluated is not defined. The syntactic order of + the key-value pairs in the construction is of no relevance, except in + the above mentioned case of two matching keys. +

+
+ +
+ Updating Maps +

+ Updating a map has similar syntax as constructing it. +

+

+ An expression defining the map to be updated is put in front of the expression + defining the keys to be updated and their respective values. +

+ M#{ K => V } +

+ where M is a term of type map and K and V are any expression. +

+

+ If key K does not match any existing key in the map, a new association + will be created from key K to value V. If key K matches + an existing key in map M its associated value will be replaced by the + new value V. In both cases the evaluated map expression will return a new map. +

+

+ If M is not of type map an exception of type badmap is thrown. +

+

+ To only update an existing value, the following syntax is used, +

+ M#{ K := V } +

+ where M is an term of type map, V is an expression and K + is an expression which evaluates to an existing key in M. +

+

+ If key K does not match any existing keys in map M an exception + of type badarg will be triggered at runtime. If a matching key K + is present in map M its associated value will be replaced by the new + value V and the evaluated map expression returns a new map. +

+

+ If M is not of type map an exception of type badmap is thrown. +

+

+ Examples: +

+ +M0 = #{}, +M1 = M0#{a => 0}, +M2 = M1#{a => 1, b => 2}, +M3 = M2#{"function" => fun() -> f() end}, +M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`. +

+ where M0 is any map. It follows that M1 .. M4 are maps as well. +

+

+ More Examples: +

+
+1> M = #{1 => a}.
+#{1 => a }
+2> M#{1.0 => b}.
+#{1 => a, 1.0 => b}.
+3> M#{1 := b}.
+#{1 => b}
+4> M#{1.0 := b}.
+** exception error: bad argument
+
+

+ As in construction, the order in which the key and value expressions + are evaluated is not defined. The + syntactic order of the key-value pairs in the update is of no + relevance, except in the case where two keys match, in which + case the latter value is used. +

+
+ +
+ Maps in Patterns +

+ Matching of key-value associations from maps is done in the following way: +

+ + #{ K := V } = M +

+ where M is any map. The key K has to be an expression with bound + variables or a literals, and V can be any pattern with either bound or + unbound variables. +

+

+ If the variable V is unbound, it will be bound to the value associated + with the key K, which has to exist in the map M. If the variable + V is bound, it has to match the value associated with K in M. +

+

Example:

+ +1> M = #{"tuple" => {1,2}}. +#{"tuple" => {1,2}} +2> #{"tuple" := {1,B}} = M. +#{"tuple" => {1,2}} +3> B. +2. +

+ This will bind variable B to integer 2. +

+

+ Similarly, multiple values from the map may be matched: +

+ #{ K1 := V1, .., Kn := Vn } = M +

+ where keys K1 .. Kn are any expressions with literals or bound variables. If all + keys exist in map M all variables in V1 .. Vn will be matched to the + associated values of their respective keys. +

+

+ If the matching conditions are not met, the match will fail, either with +

+ + + a badmatch exception, if used in the context of the matching operator + as in the example, + + + or resulting in the next clause being tested in function heads and + case expressions. + + +

+ Matching in maps only allows for := as delimiters of associations. + The order in which keys are declared in matching has no relevance. +

+

+ Duplicate keys are allowed in matching and will match each pattern associated + to the keys. +

+ #{ K := V1, K := V2 } = M +

+ Matching an expression against an empty map literal will match its type but + no variables will be bound: +

+ #{} = Expr +

+ This expression will match if the expression Expr is of type map, otherwise + it will fail with an exception badmatch. +

+
+ Matching syntax: Example with literals in function heads +

+ Matching of literals as keys are allowed in function heads. +

+ +%% only start if not_started +handle_call(start, From, #{ state := not_started } = S) -> +... + {reply, ok, S#{ state := start }}; + +%% only change if started +handle_call(change, From, #{ state := start } = S) -> +... + {reply, ok, S#{ state := changed }}; +
+
+
+ Maps in Guards +

+ Maps are allowed in guards as long as all sub-expressions are valid guard expressions. +

+

+ Two guard BIFs handles maps: +

+ + + is_map/1 + + + map_size/1 + + +
+
+
Bit Syntax Expressions diff --git a/system/doc/reference_manual/maps.xml b/system/doc/reference_manual/maps.xml deleted file mode 100644 index 78808ce4a2..0000000000 --- a/system/doc/reference_manual/maps.xml +++ /dev/null @@ -1,274 +0,0 @@ - - - - -
- - 2014 - Ericsson AB. All Rights Reserved. - - - The contents of this file are subject to the Erlang Public License, - Version 1.1, (the "License"); you may not use this file except in - compliance with the License. You should have received a copy of the - Erlang Public License along with this software. If not, it can be - retrieved online at http://www.erlang.org/. - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - the License for the specific language governing rights and limitations - under the License. - - - Maps - - - - - maps.xml -
- - -

Maps are considered experimental during OTP 17 and may be subject to change.

-

The documentation below describes it being possible to use arbitrary - expressions or variables as keys, this is NOT implemented in the current - version of Erlang/OTP.

-

Exceptions returns badarg instead of badmap, this will change in - the future releases.

-
- -
- Creating Maps -

- Constructing a new map is done by letting an expression K be associated with - another expression V: -

- #{ K => V } -

- New maps may include multiple associations at construction by listing every - association: -

- #{ K1 => V1, .., Kn => Vn } -

- An empty map is constructed by not associating any terms with each other: -

- #{} -

- All keys and values in the map are terms. Any expression is first evaluated and - then the resulting terms are used as key and value respectively. -

-

- Keys and values are separated by the => arrow and associations are - separated by ,. -

- -

- Examples: -

- -M0 = #{}, % empty map -M1 = #{a => <<"hello">>}, % single association with literals -M2 = #{1 => 2, b => b}, % multiple associations with literals -M3 = #{k => {A,B}}, % single association with variables -M4 = #{{"w", 1} => f()}. % compound key associated with an evaluated expression -

- where, A and B are any expressions and M0 through M4 - are the resulting map terms. -

-

- If two matching keys are declared, the latter key will take precedence. -

-

- Example: -

- -
-1> #{1 => a, 1 => b}.
-#{1 => b }
-2> #{1.0 => a, 1 => b}.
-#{1 => b, 1.0 => a}
-
-

- The order in which the expressions constructing the keys and their - associated values are evaluated is not defined. The syntactic order of - the key-value pairs in the construction is of no relevance, except in - the above mentioned case of two matching keys. -

-
- -
- Updating Maps -

- Updating a map has similar syntax as constructing it. -

-

- An expression defining the map to be updated is put in front of the expression - defining the keys to be updated and their respective values. -

- M#{ K => V } -

- where M is a term of type map and K and V are any expression. -

-

- If key K does not match any existing key in the map, a new association - will be created from key K to value V. If key K matches - an existing key in map M its associated value will be replaced by the - new value V. In both cases the evaluated map expression will return a new map. -

-

- If M is not of type map an exception of type badmap is thrown. -

-

- To only update an existing value, the following syntax is used, -

- M#{ K := V } -

- where M is an term of type map, V is an expression and K - is an expression which evaluates to an existing key in M. -

-

- If key K does not match any existing keys in map M an exception - of type badarg will be triggered at runtime. If a matching key K - is present in map M its associated value will be replaced by the new - value V and the evaluated map expression returns a new map. -

-

- If M is not of type map an exception of type badmap is thrown. -

-

- Examples: -

- -M0 = #{}, -M1 = M0#{a => 0}, -M2 = M1#{a => 1, b => 2}, -M3 = M2#{"function" => fun() -> f() end}, -M4 = M3#{a := 2, b := 3}. % 'a' and 'b' was added in `M1` and `M2`. -

- where M0 is any map. It follows that M1 .. M4 are maps as well. -

-

- More Examples: -

-
-1> M = #{1 => a}.
-#{1 => a }
-2> M#{1.0 => b}.
-#{1 => a, 1.0 => b}.
-3> M#{1 := b}.
-#{1 => b}
-4> M#{1.0 := b}.
-** exception error: bad argument
-
-

- As in construction, the order in which the key and value expressions - are evaluated is not defined. The - syntactic order of the key-value pairs in the update is of no - relevance, except in the case where two keys match, in which - case the latter value is used. -

-
- -
- Maps in Patterns -

- Matching of key-value associations from maps is done in the following way: -

- - #{ K := V } = M -

- where M is any map. The key K has to be an expression with bound - variables or a literals, and V can be any pattern with either bound or - unbound variables. -

-

- If the variable V is unbound, it will be bound to the value associated - with the key K, which has to exist in the map M. If the variable - V is bound, it has to match the value associated with K in M. -

-

Example:

- -1> M = #{"tuple" => {1,2}}. -#{"tuple" => {1,2}} -2> #{"tuple" := {1,B}} = M. -#{"tuple" => {1,2}} -3> B. -2. -

- This will bind variable B to integer 2. -

-

- Similarly, multiple values from the map may be matched: -

- #{ K1 := V1, .., Kn := Vn } = M -

- where keys K1 .. Kn are any expressions with literals or bound variables. If all - keys exist in map M all variables in V1 .. Vn will be matched to the - associated values of their respective keys. -

-

- If the matching conditions are not met, the match will fail, either with -

- - - a badmatch exception, if used in the context of the matching operator - as in the example, - - - or resulting in the next clause being tested in function heads and - case expressions. - - -

- Matching in maps only allows for := as delimiters of associations. - The order in which keys are declared in matching has no relevance. -

-

- Duplicate keys are allowed in matching and will match each pattern associated - to the keys. -

- #{ K := V1, K := V2 } = M -

- Matching an expression against an empty map literal will match its type but - no variables will be bound: -

- #{} = Expr -

- This expression will match if the expression Expr is of type map, otherwise - it will fail with an exception badmatch. -

-
- Matching syntax: Example with literals in function heads -

- Matching of literals as keys are allowed in function heads. -

- -%% only start if not_started -handle_call(start, From, #{ state := not_started } = S) -> -... - {reply, ok, S#{ state := start }}; - -%% only change if started -handle_call(change, From, #{ state := start } = S) -> -... - {reply, ok, S#{ state := changed }}; -
-
-
- Maps in Guards -

- Maps are allowed in guards as long as all sub-expressions are valid guard expressions. -

-

- Two guard BIFs handles maps: -

- - - is_map/1 - - - map_size/1 - - -
-
diff --git a/system/doc/reference_manual/part.xml b/system/doc/reference_manual/part.xml index 36fb888748..ee8f3dd7eb 100644 --- a/system/doc/reference_manual/part.xml +++ b/system/doc/reference_manual/part.xml @@ -36,7 +36,6 @@ - diff --git a/system/doc/reference_manual/xmlfiles.mk b/system/doc/reference_manual/xmlfiles.mk index 181e6f8042..6886c8c7cf 100644 --- a/system/doc/reference_manual/xmlfiles.mk +++ b/system/doc/reference_manual/xmlfiles.mk @@ -24,7 +24,6 @@ REF_MAN_CHAPTER_FILES = \ functions.xml \ expressions.xml \ macros.xml \ - maps.xml \ records.xml \ errors.xml \ processes.xml \ -- cgit v1.2.3