
Я ищу хорошее объяснение различий и вариантов использования между tl_map_function:nN
и tl_map_inline:Nn
. Я предоставляю MWE для , inline
который также, по-видимому, является самым быстрым.
\documentclass{article}
\usepackage{expl3,xparse}
\begin{document}
\ExplSyntaxOn
\cs_new:Nn\whatever:n{..{#1}~}
\tl_new:N \tl_phd_temp_a
\tl_new:N \tl_phd_temp_b
\tl_new:N \tl_phd_temp_c
\DeclareDocumentCommand\Test{ }
{
\tl_set:Nn \tl_phd_temp_a {Yiannis Mary John}
\tl_set:Nn \tl_phd_temp_b {{Lazarides}{Lou}{Smith}}
\tl_concat:NNN \tl_phd_temp_c \tl_phd_temp_a \tl_phd_temp_b
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
}
\ExplSyntaxOff
\Test
\end{document}
решение1
Функции \tl_map_function:nN
и \tl_map_function:NN
полностью расширяемы (с x
-expansion, не f
-expansion), а inline
версия — нет.
Эта function
версия также немного быстрее.
Пример файла
\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\cs_new:Nn\whatever:n{}
\tl_new:N \tl_phd_temp_a
\tl_new:N \tl_phd_temp_b
\tl_new:N \tl_phd_temp_c
\tl_set:Nn \tl_phd_temp_a {Yiannis Mary John}
\tl_set:Nn \tl_phd_temp_b {{Lazarides}{Lou}{Smith}}
\tl_concat:NNN \tl_phd_temp_c \tl_phd_temp_a \tl_phd_temp_b
\cs_new:Npn \xinline
{
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
\tl_map_inline:Nn\tl_phd_temp_c{\whatever:n{##1}}
}
\cs_new:Npn \xfunction
{
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
\tl_map_function:NN\tl_phd_temp_c \whatever:n
}
\cs_new:Npn \y #1
{
#1 #1 #1 #1 #1 #1 #1 #1 #1 #1
}
\cs_new:Npn \z #1
{
\y{#1}\y{#1}\y{#1}\y{#1}\y{#1}
\y{#1}\y{#1}\y{#1}\y{#1}\y{#1}
}
\cs_new:Npn \zz #1
{
\z{#1}\z{#1}\z{#1}\z{#1}\z{#1}
\z{#1}\z{#1}\z{#1}\z{#1}\z{#1}
}
\cs_new:Npn \zzz #1
{
\zz{#1}\zz{#1}\zz{#1}\zz{#1}\zz{#1}
\zz{#1}\zz{#1}\zz{#1}\zz{#1}\zz{#1}
}
\ExplSyntaxOff
\zzz{\xinline}
%\zzz{\xfunction}
\stop
inline
версия
Это ответ отtime
real 0m4.635s
user 0m4.613s
sys 0m0.016s
и это отчет памяти
140188 words of memory out of 5000000
function
версия
Это ответ отtime
real 0m4.163s
user 0m4.139s
sys 0m0.020s
и это отчет памяти
140188 words of memory out of 5000000
Что предпочесть? Я склонен рассматривать \tl_map_inline:nn
более простой вариант, поскольку он не требует определения новой функции, но когда код становится сложным, function
следует использовать версию для большей ясности. Его следует применять всякий раз, когда отображение, которое должно быть выполнено, использует функцию, определенную в другом месте.
Версия inline
упрощает добавление точек останова; для этой function
версии требуется специально разработанная функция, содержащая \tl_map_break:
.
Кроме того, function
версия становится немного сложнее, когда для отображения требуется более одного аргумента (например, мы находимся во вложенном отображении, использующем как внешний, так и внутренний элемент).