runtime(doc): Add variable categories and null related documentation(#13750)

Signed-off-by: Ernie Rael <errael@raelity.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
errael
2023-12-25 01:31:23 -08:00
committed by GitHub
parent 9042bd8b09
commit cea3dac76e
2 changed files with 160 additions and 3 deletions

View File

@ -9082,7 +9082,11 @@ notepad gui_w32.txt /*notepad*
nr2char() builtin.txt /*nr2char()* nr2char() builtin.txt /*nr2char()*
nroff.vim syntax.txt /*nroff.vim* nroff.vim syntax.txt /*nroff.vim*
null vim9.txt /*null* null vim9.txt /*null*
null-anomalies vim9.txt /*null-anomalies*
null-compare vim9.txt /*null-compare*
null-details vim9.txt /*null-details*
null-variable eval.txt /*null-variable* null-variable eval.txt /*null-variable*
null-variables vim9.txt /*null-variables*
null_blob vim9.txt /*null_blob* null_blob vim9.txt /*null_blob*
null_channel vim9.txt /*null_channel* null_channel vim9.txt /*null_channel*
null_class vim9.txt /*null_class* null_class vim9.txt /*null_class*
@ -10945,6 +10949,7 @@ val-variable eval.txt /*val-variable*
valgrind debug.txt /*valgrind* valgrind debug.txt /*valgrind*
values() builtin.txt /*values()* values() builtin.txt /*values()*
var-functions usr_41.txt /*var-functions* var-functions usr_41.txt /*var-functions*
variable-categories vim9.txt /*variable-categories*
variable-scope eval.txt /*variable-scope* variable-scope eval.txt /*variable-scope*
variable-types vim9.txt /*variable-types* variable-types vim9.txt /*variable-types*
variables eval.txt /*variables* variables eval.txt /*variables*

View File

@ -1,4 +1,4 @@
*vim9.txt* For Vim version 9.0. Last change: 2023 Dec 09 *vim9.txt* For Vim version 9.0. Last change: 2023 Dec 24
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -1055,8 +1055,11 @@ variable, since they cannot be deleted with `:unlet`. E.g.: >
The values can also be useful as the default value for an argument: > The values can also be useful as the default value for an argument: >
def MyFunc(b: blob = null_blob) def MyFunc(b: blob = null_blob)
if b == null_blob # Note: compare against null, not null_blob,
# b argument was not given # to distinguish the default value from an empty blob.
if b == null
# b argument was not given
See |null-compare| for more information about testing against null.
It is possible to compare `null` with any value, this will not give a type It is possible to compare `null` with any value, this will not give a type
error. However, comparing `null` with a number, float or bool will always error. However, comparing `null` with a number, float or bool will always
@ -1698,6 +1701,155 @@ argument type checking: >
Types are checked for most builtin functions to make it easier to spot Types are checked for most builtin functions to make it easier to spot
mistakes. mistakes.
Categories of variables, defaults and null handling ~
*variable-categories* *null-variables*
There are categories of variables:
primitive number, float, boolean
container string, blob, list, dict
specialized function, job, channel, user-defined-object
When declaring a variable without an initializer, an explicit type must be
provided. Each category has different default initialization semantics. Here's
an example for each category: >
var num: number # primitives default to a 0 equivalent
var cont: list<string> # containers default to an empty container
var spec: job # specialized variables default to null
<
Vim does not have a familiar null value; it has various null_<type> predefined
values, for example |null_string|, |null_list|, |null_job|. Primitives do not
have a null_<type>. The typical use cases for null_<type> are:
- to `clear a variable` and release its resources;
- as a `default for a parameter` in a function definition, see |null-compare|.
For a specialized variable, like `job`, null_<type> is used to clear the
resources. For a container variable, resources can also be cleared by
assigning an empty container to the variable. For example: >
var j: job = job_start(...)
# ... job does its work
j = null_job # clear the variable and release the job's resources
var l: list<any>
# ... add lots of stuff to list
l = [] # clear the variable and release container resources
Using the empty container, rather than null_<type>, to clear a container
variable may avoid null complications as described in |null-anomalies|.
The initialization semantics of container variables and specialized variables
differ. An uninitialized container defaults to an empty container: >
var l1: list<string> # empty container
var l2: list<string> = [] # empty container
var l3: list<string> = null_list # null container
"l1" and "l2" are equivalent and indistinguishable initializations; but "l3"
is a null container. A null container is similar to, but different from, an
empty container, see |null-anomalies|.
Specialized variables default to null. These job initializations are
equivalent and indistinguishable: >
var j1: job
var j2: job = null_job
var j3 = null_job
When a list or dict is declared, if the item type is not specified and can not
be inferred, then the type is "any": >
var d1 = {} # type is "dict<any>"
var d2 = null_dict # type is "dict<any>"
Declaring a function, see |vim9-func-declaration|, is particularly unique.
*null-compare*
For familiar null compare semantics, where a null container is not equal to
an empty container, do not use null_<type> in a comparison: >
vim9script
def F(arg: list<string> = null_list)
if arg == null
echo "null"
else
echo printf("not null, %sempty", empty(arg) ? '' : 'not ')
endif
enddef
F() # output: "null"
F(null_list) # output: "null"
F([]) # output: "not null, empty"
F(['']) # output: "not null, not empty"
The above function takes a `list of strings` and reports on it.
Change the above function signature to accept different types of arguments: >
def F(arg: list<any> = null_list) # any type of list
def F(arg: any = null) # any type
<
In the above example, where the goal is to distinguish a null list from an
empty list, comparing against `null` instead of `null_list` is the correct
choice. The basic reason is because "null_list == null" and "[] != null".
Comparing to `null_list` fails since "[] == null_list". In the following section
there are details about comparison results.
*null-details* *null-anomalies*
This section describes issues about using null and null_<type>; included below
are the enumerated results of null comparisons. In some cases, if familiar
with vim9 null semantics, the programmer may chose to use null_<type> in
comparisons and/or other situations.
Elsewhere in the documentation it says:
Quite often a null value is handled the same as an
empty value, but not always
Here's an example: >
vim9script
var s1: list<string>
var s2: list<string> = null_list
echo s1 # output: "[]"
echo s2 # output: "[]"
echo s1 + ['a'] # output: "['a']"
echo s2 + ['a'] # output: "['a']"
echo s1->add('a') # output: "['a']"
echo s2->add('a') # E1130: Can not add to null list
<
Two values equal to a null_<type> are not necessarily equal to each other: >
vim9script
echo {} == null_dict # true
echo null_dict == null # true
echo {} == null # false
<
Unlike the other containers, an uninitialized string is equal to null. The
'is' operator can be used to determine if it is a null_string: >
vim9script
var s1: string
var s2 = null_string
echo s1 == null # true - this is unexpected
echo s2 == null # true
echo s2 is null_string # true
var b1: blob
var b2 = null_blob
echo b1 == null # false
echo b2 == null # true
<
Any variable initialized to the null_<type> is equal to the null_<type> and is
also equal to null. For example: >
vim9script
var x = null_blob
echo x == null_blob # true
echo x == null # true
<
An uninitialized variable is usually equal to null; it depends on its type:
var s: string s == null
var b: blob b != null ***
var l: list<any> l != null ***
var d: dict<any> d != null ***
var f: func f == null
var j: job j == null
var c: channel c == null
var o: Class o == null
A variable initialized to empty equals null_<type>; but not null:
var s2: string = "" == null_string != null
var b2: blob = 0z == null_blob != null
var l2: list<any> = [] == null_list != null
var d2: dict<any> = {} == null_dict != null
NOTE: the specialized variables, like job, default to null value and have no
corresponding empty value.
============================================================================== ==============================================================================
5. Namespace, Import and Export 5. Namespace, Import and Export