[latex3-commits] [git/LaTeX3-latex3-latex3] master: Implement \dim_sign:n and \fp_sign:n too (235fc39)

Bruno Le Floch bruno at le-floch.fr
Sat Nov 3 17:02:11 CET 2018


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/235fc39b0f88f2d263755de6fd278988d6f203c1

>---------------------------------------------------------------

commit 235fc39b0f88f2d263755de6fd278988d6f203c1
Author: Bruno Le Floch <bruno at le-floch.fr>
Date:   Sat Nov 3 17:01:46 2018 +0100

    Implement \dim_sign:n and \fp_sign:n too


>---------------------------------------------------------------

235fc39b0f88f2d263755de6fd278988d6f203c1
 l3kernel/CHANGELOG.md                   |    4 ++
 l3kernel/l3candidates.dtx               |   72 +++++++++++++++++++++++++++++++
 l3kernel/testfiles/m3expl001.luatex.tlg |    3 ++
 l3kernel/testfiles/m3expl001.ptex.tlg   |    3 ++
 l3kernel/testfiles/m3expl001.tlg        |    3 ++
 l3kernel/testfiles/m3expl001.uptex.tlg  |    3 ++
 l3kernel/testfiles/m3expl001.xetex.tlg  |    3 ++
 l3kernel/testfiles/m3expl003.luatex.tlg |    3 ++
 l3kernel/testfiles/m3expl003.ptex.tlg   |    3 ++
 l3kernel/testfiles/m3expl003.tlg        |    3 ++
 l3kernel/testfiles/m3expl003.uptex.tlg  |    3 ++
 l3kernel/testfiles/m3expl003.xetex.tlg  |    3 ++
 l3kernel/testfiles/m3fp-convert001.lvt  |   14 ++++++
 l3kernel/testfiles/m3fp-convert001.tlg  |   39 +++++++++++++++++
 l3kernel/testfiles/m3skip002.lvt        |    7 ++-
 l3kernel/testfiles/m3skip002.tlg        |    7 ++-
 16 files changed, 171 insertions(+), 2 deletions(-)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index 7c02ddb..a4e85ee 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -7,6 +7,10 @@ this project uses date-based 'snapshot' version identifiers.
 
 ## [Unreleased]
 
+### Added
+
+- `\int_sign:n`, `\dim_sign:n` and `\fp_sign:n`
+
 ## [2018-10-31]
 
 ## [2018-10-26]
diff --git a/l3kernel/l3candidates.dtx b/l3kernel/l3candidates.dtx
index adaf98a..f8e1c40 100644
--- a/l3kernel/l3candidates.dtx
+++ b/l3kernel/l3candidates.dtx
@@ -269,6 +269,20 @@
 %   applicable.
 % \end{function}
 %
+% \section{Additions to \pkg{l3fp-convert}}
+%
+% \begin{function}[EXP, added = 2018-11-03]{\fp_sign:n}
+%   \begin{syntax}
+%     \cs{fp_sign:n} \Arg{fpexpr}
+%   \end{syntax}
+%   Evaluates the \meta{fpexpr} and leaves its sign in the input stream
+%   using \cs{fp_eval:n} |{sign(|\meta{result}|)}|: $+1$ for positive
+%   numbers and for $+\infty$, $-1$ for negative numbers and for
+%   $-\infty$, $\pm 0$ for $\pm 0$.  If the operand is a tuple or is
+%   \nan{}, then \enquote{invalid operation} occurs and the result
+%   is~$0$.
+% \end{function}
+%
 % \section{Additions to \pkg{l3fparray}}
 %
 % \begin{function}[added = 2018-05-05]{\fparray_new:Nn}
@@ -827,6 +841,14 @@
 %
 % \section{Additions to \pkg{l3skip}}
 %
+% \begin{function}[EXP, added = 2018-11-03]{\dim_sign:n}
+%   \begin{syntax}
+%     \cs{dim_sign:n} \Arg{dimexpr}
+%   \end{syntax}
+%   Evaluates the \meta{dimexpr} then leaves $1$ or $0$ or $-1$ in the
+%   input stream according to the sign of the result.
+% \end{function}
+%
 % \begin{function}{\skip_split_finite_else_action:nnNN}
 %   \begin{syntax}
 %     \cs{skip_split_finite_else_action:nnNN} \Arg{skipexpr} \Arg{action}
@@ -2186,6 +2208,22 @@
 % \end{macro}
 % \end{macro}
 %
+% \subsection{Additions to \pkg{l3fp-convert}}
+%
+%    \begin{macrocode}
+%<@@=fp>
+%    \end{macrocode}
+%
+% \begin{macro}{\fp_sign:n}
+%   Trivial but useful.  See the implementation of \cs{fp_add:Nn} for an
+%   explanation of why to use \cs{@@_parse:n}, namely, for better error
+%   reporting.
+%    \begin{macrocode}
+\cs_new:Npn \fp_sign:n #1
+  { \fp_to_decimal:n { sign \@@_parse:n {#1} } }
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Additions to \pkg{l3file}}
 %
 %    \begin{macrocode}
@@ -2827,6 +2865,40 @@
 % \subsection{Additions to \pkg{l3skip}}
 %
 %    \begin{macrocode}
+%<@@=dim>
+%    \end{macrocode}
+%
+% \begin{macro}[EXP]{\dim_sign:n, \@@_sign:Nw}
+%   See \cs{dim_abs:n}.  Contrarily to \cs{int_sign:n} the case of a
+%   zero dimension cannot be distinguished from a positive dimension by
+%   looking only at the first character, since |0.2pt| and |0pt| start
+%   the same way.  We need explicit comparisons.  We start by
+%   distinguishing the most common case of a positive dimension.
+%    \begin{macrocode}
+\__kernel_patch_args:nNNpn
+  { { \__kernel_chk_expr:nNnN {#1} \@@_eval:w { } \dim_sign:n } }
+\cs_new:Npn \dim_sign:n #1
+  {
+    \int_value:w \exp_after:wN \@@_sign:Nw
+      \dim_use:N \@@_eval:w #1 \@@_eval_end: ;
+    \exp_stop_f:
+  }
+\cs_new:Npn \@@_sign:Nw #1#2 ;
+  {
+    \if_dim:w #1#2 > \c_zero_dim
+      1
+    \else:
+      \if_meaning:w - #1
+        -1
+      \else:
+        0
+      \fi:
+    \fi:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
 %<@@=skip>
 %    \end{macrocode}
 %
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index 8cf468b..264c575 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -5778,6 +5778,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5857,6 +5858,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl001.ptex.tlg b/l3kernel/testfiles/m3expl001.ptex.tlg
index f75482a..342a731 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -5811,6 +5811,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5890,6 +5891,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl001.tlg b/l3kernel/testfiles/m3expl001.tlg
index cb6fae2..bd40260 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -5811,6 +5811,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5890,6 +5891,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl001.uptex.tlg b/l3kernel/testfiles/m3expl001.uptex.tlg
index 820d194..81056cb 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -5808,6 +5808,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5887,6 +5888,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl001.xetex.tlg b/l3kernel/testfiles/m3expl001.xetex.tlg
index 2b63698..8ef2c99 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -5789,6 +5789,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5860,6 +5861,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl003.luatex.tlg b/l3kernel/testfiles/m3expl003.luatex.tlg
index 8cf468b..264c575 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -5778,6 +5778,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5857,6 +5858,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl003.ptex.tlg b/l3kernel/testfiles/m3expl003.ptex.tlg
index f75482a..342a731 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -5811,6 +5811,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5890,6 +5891,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl003.tlg b/l3kernel/testfiles/m3expl003.tlg
index cb6fae2..bd40260 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -5811,6 +5811,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5890,6 +5891,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl003.uptex.tlg b/l3kernel/testfiles/m3expl003.uptex.tlg
index 820d194..81056cb 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -5808,6 +5808,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5887,6 +5888,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3expl003.xetex.tlg b/l3kernel/testfiles/m3expl003.xetex.tlg
index 2b63698..8ef2c99 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -5789,6 +5789,7 @@ Defining \__coffin_scale_corner:Nnnn on line ...
 Defining \__coffin_scale_pole:Nnnnnn on line ...
 Defining \__coffin_x_shift_corner:Nnnn on line ...
 Defining \__coffin_x_shift_pole:Nnnnnn on line ...
+Defining \fp_sign:n on line ...
 Defining \file_get_mdfive_hash:nN on line ...
 Defining \file_get_size:nN on line ...
 Defining \file_get_timestamp:nN on line ...
@@ -5860,6 +5861,8 @@ Defining \seq_indexed_map_function:NN on line ...
 Defining \seq_indexed_map_inline:Nn on line ...
 Defining \__seq_indexed_map:NN on line ...
 Defining \__seq_indexed_map:Nw on line ...
+Defining \dim_sign:n on line ...
+Defining \__dim_sign:Nw on line ...
 Defining \skip_split_finite_else_action:nnNN on line ...
 Defining \c_sys_engine_version_str on line ...
 Defining \sys_rand_seed: on line ...
diff --git a/l3kernel/testfiles/m3fp-convert001.lvt b/l3kernel/testfiles/m3fp-convert001.lvt
index ce2cc1d..324ac41 100644
--- a/l3kernel/testfiles/m3fp-convert001.lvt
+++ b/l3kernel/testfiles/m3fp-convert001.lvt
@@ -187,4 +187,18 @@
   }
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\TESTEXP { Sign }
+  {
+    \fp_sign:n {  10.01 } \NEWLINE
+    \fp_sign:n { -10.01 } \NEWLINE
+    \fp_sign:n { 10.01 - 10.01 } \NEWLINE
+    \fp_sign:n { -0 } \NEWLINE
+    \fp_sign:n { 1/0 } \NEWLINE
+    \fp_sign:n { 1/-0 } \NEWLINE
+    \fp_sign:n { nan } \NEWLINE
+    \fp_sign:n { 1,2 } \NEWLINE
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \END
diff --git a/l3kernel/testfiles/m3fp-convert001.tlg b/l3kernel/testfiles/m3fp-convert001.tlg
index e90ac68..322bd2a 100644
--- a/l3kernel/testfiles/m3fp-convert001.tlg
+++ b/l3kernel/testfiles/m3fp-convert001.tlg
@@ -234,3 +234,42 @@ TEST 12: Absolute values
 10.01
 10.01
 ============================================================
+============================================================
+TEST 13: Sign
+============================================================
+! Undefined control sequence.
+<argument> \LaTeX3 error: 
+                           Invalid operation fp_to_decimal(nan)
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \LaTeX3 error: 
+                           Invalid operation sign((1, 2))
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \LaTeX3 error: 
+                           Invalid operation fp_to_decimal(nan)
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+1
+-1
+0
+-0
+1
+-1
+0
+0
+============================================================
diff --git a/l3kernel/testfiles/m3skip002.lvt b/l3kernel/testfiles/m3skip002.lvt
index 51637b3..f878031 100644
--- a/l3kernel/testfiles/m3skip002.lvt
+++ b/l3kernel/testfiles/m3skip002.lvt
@@ -149,9 +149,14 @@
   \dim_eval:n { 5 pt * \dim_ratio:nn { 0.3 pt } { 0.4 pt } } \NEWLINE
 }
 
-\TESTEXP { Absolute~dimension } {
+\TESTEXP { Absolute~dimension~and~sign } {
   \dim_abs:n { 10 pt }  \NEWLINE
   \dim_abs:n { -10 pt } \NEWLINE
+  \dim_sign:n { 10pt }  \NEWLINE
+  \dim_sign:n { 1sp }  \NEWLINE
+  \dim_sign:n { 0pt }  \NEWLINE
+  \dim_sign:n { -1sp }  \NEWLINE
+  \dim_sign:n { -10pt } \NEWLINE
 }
 
 \TESTEXP { Max~and~min~dimension } {
diff --git a/l3kernel/testfiles/m3skip002.tlg b/l3kernel/testfiles/m3skip002.tlg
index a8c8a35..faff9ac 100644
--- a/l3kernel/testfiles/m3skip002.tlg
+++ b/l3kernel/testfiles/m3skip002.tlg
@@ -57,10 +57,15 @@ TEST 5: Dimension ratio
 3.75009pt
 ============================================================
 ============================================================
-TEST 6: Absolute dimension
+TEST 6: Absolute dimension and sign
 ============================================================
 10.0pt
 10.0pt
+1
+1
+0
+-1
+-1
 ============================================================
 ============================================================
 TEST 7: Max and min dimension





More information about the latex3-commits mailing list