summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/functional/functional.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-04-02 03:01:41 +0000
committerNorbert Preining <norbert@preining.info>2022-04-02 03:01:41 +0000
commit0a334de875944625912f2bf2d918122bb55c0dad (patch)
tree7a13a8f48bf68f95926e9ff2b70eb9048562b2ed /macros/latex/contrib/functional/functional.sty
parent18e3709c9fe9554f72b8fa347bd27ae4b76b841e (diff)
CTAN sync 202204020301
Diffstat (limited to 'macros/latex/contrib/functional/functional.sty')
-rw-r--r--macros/latex/contrib/functional/functional.sty501
1 files changed, 464 insertions, 37 deletions
diff --git a/macros/latex/contrib/functional/functional.sty b/macros/latex/contrib/functional/functional.sty
index dcc863b3c5..6f54205fe0 100644
--- a/macros/latex/contrib/functional/functional.sty
+++ b/macros/latex/contrib/functional/functional.sty
@@ -14,13 +14,16 @@
\NeedsTeXFormat{LaTeX2e}[2018-04-01]
\RequirePackage{expl3}
-\ProvidesExplPackage{functional}{2022-03-19}{2022B}
+\ProvidesExplPackage{functional}{2022-04-01}{2022C}
{^^JLaTeX2 functional interfaces for LaTeX3 programming layer}
\cs_generate_variant:Nn \iow_log:n { V }
+\cs_generate_variant:Nn \str_set:Nn { Ne }
\cs_generate_variant:Nn \tl_log:n { e }
\cs_generate_variant:Nn \tl_set:Nn { Ne }
+\prg_generate_conditional_variant:Nnn \str_if_eq:nn { Ve } { TF }
+
\tl_new:N \gResultTl
\int_new:N \l__fun_arg_count_int
\tl_new:N \l__fun_parameters_defined_tl
@@ -67,7 +70,7 @@
\__fun_group_begin:
\tl_gclear:N \gResultTl
#3
- \__fun_tracing_log:e { [O] ~ \gResultTl }
+ \__fun_tracing_log:e { [O] ~ \exp_not:V \gResultTl }
\__fun_group_end:
}
\use:c { __fun_new_with_arg_ \int_to_roman:n { \l__fun_arg_count_int } :NnV }
@@ -440,21 +443,45 @@
{ \tl_use:N \gResultTl }
}
-\tl_new:N \l__fun_variable_type_tl
+\str_new:N \l__fun_variable_name_str
+\str_new:N \l__fun_variable_name_a_str
+\str_new:N \l__fun_variable_name_b_str
\prg_new_protected_conditional:Npnn \__fun_if_global_variable:N #1 { TF }
{
- \tl_set:Ne \l__fun_variable_type_tl
- { \exp_args:Ne \tl_head:n { \cs_to_str:N #1 } }
- \str_if_eq:VnTF \l__fun_variable_type_tl { g }
- { \prg_return_true: }
+ \str_set:Ne \l__fun_variable_name_str { \cs_to_str:N #1 }
+ \str_set:Ne \l__fun_variable_name_b_str
+ { \str_item:Nn \l__fun_variable_name_str { 2 } }
+ \str_if_eq:VeTF
+ \l__fun_variable_name_b_str
+ { \str_uppercase:f { \l__fun_variable_name_b_str } }
+ {
+ \str_set:Ne \l__fun_variable_name_a_str
+ { \str_head:N \l__fun_variable_name_str }
+ \str_case:VnF \l__fun_variable_name_a_str
+ {
+ { l } { \prg_return_false: }
+ { g } { \prg_return_true: }
+ }
+ { \__fun_if_set_local: }
+ }
+ { \__fun_if_set_local: }
+ }
+
+\bool_new:N \g__fun_variable_local_bool
+
+\cs_new:Npn \__fun_if_set_local:
+ {
+ \bool_if:NTF \g__fun_variable_local_bool
{
- \str_if_eq:VnTF \l__fun_variable_type_tl { c }
- { \prg_return_true: }
- { \prg_return_false: }
+ \bool_gset_false:N \g__fun_variable_local_bool
+ \prg_return_false:
}
+ { \prg_return_true: }
}
+\PrgNewFunction \Local { } { \bool_gset_true:N \g__fun_variable_local_bool }
+
%% We must not put an assignment inside a group
\cs_new_protected:Npn \__fun_do_assignment:Nnn #1 #2 #3
{
@@ -499,7 +526,8 @@
\cs_generate_variant:Nn \__fun_tracing_log_on:n { e, V }
\cs_new_protected:Npn \__fun_tracing_log_off:n #1 { }
-\cs_generate_variant:Nn \__fun_tracing_log_off:n { e, V }
+\cs_new_protected:Npn \__fun_tracing_log_off:e #1 { }
+\cs_new_protected:Npn \__fun_tracing_log_off:V #1 { }
\cs_new_protected:Npn \__fun_tracing_true:
{
@@ -553,22 +581,23 @@
{
\exp_args:Nc \__fun_put_result:n { #1 }
}
-\cs_set_eq:NN \UseName \Name
\PrgNewFunction \Value { M }
{
\__fun_put_result:V #1
}
-\cs_set_eq:NN \UseValue \Value
\PrgNewFunction \Expand { m }
{
\__fun_put_result:e { #1 }
}
-\cs_set_eq:NN \UseExpand \Expand
-\cs_set_eq:NN \ExpNot \exp_not:n
-\cs_set_eq:NN \ExpValue \exp_not:V
+\cs_set_eq:NN \UnExpand \exp_not:n
+\cs_set_eq:NN \NoExpand \exp_not:N
+\cs_set_eq:NN \OnlyName \exp_not:c
+\cs_set_eq:NN \OnlyValue \exp_not:V
+\cs_set_eq:NN \OnlyExpandF \exp_not:f
+\cs_set_eq:NN \OnlyExpandO \exp_not:o
\PrgNewFunction \UseOne { n } { \Result { #1 } }
@@ -729,25 +758,25 @@
{ \tl_gput_right:Nn #1 {#2} } { \tl_put_right:Nn #1 {#2} }
}
-\PrgNewFunction \TlReplaceOnce { M m m }
+\PrgNewFunction \TlVarReplaceOnce { M m m }
{
\__fun_do_assignment:Nnn #1
{ \tl_greplace_once:Nnn #1 {#2} {#3} } { \tl_replace_once:Nnn #1 {#2} {#3} }
}
-\PrgNewFunction \TlReplaceAll { M m m }
+\PrgNewFunction \TlVarReplaceAll { M m m }
{
\__fun_do_assignment:Nnn #1
{ \tl_greplace_all:Nnn #1 {#2} {#3} } { \tl_replace_all:Nnn #1 {#2} {#3} }
}
-\PrgNewFunction \TlRemoveOnce { M m }
+\PrgNewFunction \TlVarRemoveOnce { M m }
{
\__fun_do_assignment:Nnn #1
{ \tl_gremove_once:Nn #1 {#2} } { \tl_remove_once:Nn #1 {#2} }
}
-\PrgNewFunction \TlRemoveAll { M m }
+\PrgNewFunction \TlVarRemoveAll { M m }
{
\__fun_do_assignment:Nnn #1
{ \tl_gremove_all:Nn #1 {#2} } { \tl_remove_all:Nn #1 {#2} }
@@ -933,25 +962,25 @@
{ \str_gput_right:Nn #1 {#2} } { \str_put_right:Nn #1 {#2} }
}
-\PrgNewFunction \StrReplaceOnce { M m m }
+\PrgNewFunction \StrVarReplaceOnce { M m m }
{
\__fun_do_assignment:Nnn #1
{ \str_greplace_once:Nnn #1 {#2} {#3} } { \str_replace_once:Nnn #1 {#2} {#3} }
}
-\PrgNewFunction \StrReplaceAll { M m m }
+\PrgNewFunction \StrVarReplaceAll { M m m }
{
\__fun_do_assignment:Nnn #1
{ \str_greplace_all:Nnn #1 {#2} {#3} } { \str_replace_all:Nnn #1 {#2} {#3} }
}
-\PrgNewFunction \StrRemoveOnce { M m }
+\PrgNewFunction \StrVarRemoveOnce { M m }
{
\__fun_do_assignment:Nnn #1
{ \str_gremove_once:Nn #1 {#2} } { \str_remove_once:Nn #1 {#2} }
}
-\PrgNewFunction \StrRemoveAll { M m }
+\PrgNewFunction \StrVarRemoveAll { M m }
{
\__fun_do_assignment:Nnn #1
{ \str_gremove_all:Nn #1 {#2} } { \str_remove_all:Nn #1 {#2} }
@@ -1568,40 +1597,38 @@
{ \clist_gput_right:Nn #1 {#2} } { \clist_put_right:Nn #1 {#2} }
}
-\PrgNewFunction \ClistRemoveDuplicates { M }
+\PrgNewFunction \ClistVarRemoveDuplicates { M }
{
\__fun_do_assignment:Nnn #1
{ \clist_gremove_duplicates:N #1 } { \clist_remove_duplicates:N #1 }
}
-\PrgNewFunction \ClistRemoveAll { M m }
+\PrgNewFunction \ClistVarRemoveAll { M m }
{
\__fun_do_assignment:Nnn #1
{ \clist_gremove_all:Nn #1 {#2} } { \clist_remove_all:Nn #1 {#2} }
}
-\PrgNewFunction \ClistReverse { M }
+\PrgNewFunction \ClistVarReverse { M }
{
\__fun_do_assignment:Nnn #1 { \clist_greverse:N #1 } { \clist_reverse:N #1 }
}
-\PrgNewFunction \ClistSort { M m }
+\PrgNewFunction \ClistVarSort { M m }
{
\__fun_do_assignment:Nnn #1
{ \clist_gsort:Nn #1 {#2} } { \clist_sort:Nn #1 {#2} }
}
-\PrgNewFunction \ClistCount { m }
- {
- \Result { \Expand { \clist_count:n { #1 } } }
- }
+\PrgNewFunction \ClistCount { m } { \Expand { \clist_count:n { #1 } } }
-\PrgNewFunction \ClistVarCount { m }
+\PrgNewFunction \ClistVarCount { M } { \Expand { \clist_count:N #1 } }
+
+\PrgNewFunction \ClistGet { M M }
{
- \Result { \Expand { \clist_count:N #1 } }
+ \clist_get:NN #1 #2
+ \__fun_quark_upgrade_no_value:N #2
}
-
-\PrgNewFunction \ClistGet { M M } { \clist_get:NN #1 #2 }
\PrgNewFunction \ClistGetT { M M n } { \clist_get:NNT #1 #2 {#3} }
\PrgNewFunction \ClistGetF { M M n } { \clist_get:NNF #1 #2 {#3} }
\PrgNewFunction \ClistGetTF { M M n n } { \clist_get:NNTF #1 #2 {#3} {#4} }
@@ -1610,6 +1637,7 @@
{
\__fun_do_assignment:Nnn #1
{ \clist_gpop:NN #1 #2 } { \clist_pop:NN #1 #2 }
+ \__fun_quark_upgrade_no_value:N #2
}
\PrgNewFunction \ClistPopT { M M n }
{
@@ -1673,7 +1701,7 @@
\clist_if_empty:nTF {#1} { \Result { \cTrueBool } } { \Result { \cFalseBool } }
}
-\PrgNewConditional \ClistVarIfEmpty { m }
+\PrgNewConditional \ClistVarIfEmpty { M }
{
\clist_if_empty:NTF #1 { \Result { \cTrueBool } } { \Result { \cFalseBool } }
}
@@ -1690,3 +1718,402 @@
{ \Result { \cTrueBool } } { \Result { \cFalseBool } }
}
+%%% --------------------------------------------------------
+%%> \section{Interfaces for Sequences and Stacks (Seq)}
+%%% --------------------------------------------------------
+
+\seq_new:N \lTmpaSeq \seq_new:N \lTmpbSeq \seq_new:N \lTmpcSeq
+\seq_new:N \lTmpiSeq \seq_new:N \lTmpjSeq \seq_new:N \lTmpkSeq
+\seq_new:N \l@Funx@Seq \seq_new:N \l@Funy@Seq \seq_new:N \l@Funz@Seq
+
+\seq_new:N \gTmpaSeq \seq_new:N \gTmpbSeq \seq_new:N \gTmpcSeq
+\seq_new:N \gTmpiSeq \seq_new:N \gTmpjSeq \seq_new:N \gTmpkSeq
+\seq_new:N \g@Funx@Seq \seq_new:N \g@Funy@Seq \seq_new:N \g@Funz@Seq
+
+\seq_set_eq:NN \cEmptySeq \c_empty_seq
+
+\PrgNewFunction \SeqNew { M } { \seq_new:N #1 }
+
+\PrgNewFunction \SeqVarLog { M } { \seq_log:N #1 }
+
+\PrgNewFunction \SeqVarShow { M } { \seq_show:N #1 }
+
+\PrgNewFunction \SeqVarJoin { M m }
+ {
+ \Expand { \seq_use:Nn #1 { #2 } }
+ }
+
+\PrgNewFunction \SeqVarJoinExtended { M m m m }
+ {
+ \Expand { \seq_use:Nnnn #1 { #2 } { #3 } { #4 } }
+ }
+
+\PrgNewFunction \SeqJoin { m m }
+ {
+ \Expand { \seq_use:nn { #1 } { #2 } }
+ }
+
+\PrgNewFunction \SeqJoinExtended { m m m m }
+ {
+ \Expand { \seq_use:nnnn { #1 } { #2 } { #3 } { #4 } }
+ }
+
+\PrgNewFunction \SeqConstFromClist { M m } { \seq_const_from_clist:Nn #1 { #2 } }
+
+\PrgNewFunction \SeqSetFromClist { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gset_from_clist:Nn #1 {#2} } { \seq_set_from_clist:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \SeqSetEq { M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gset_eq:NN #1 #2 } { \seq_set_eq:NN #1 #2 }
+ }
+
+\PrgNewFunction \SeqSetSplit { M m m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gset_split:Nnn #1 {#2} {#3} } { \seq_set_split:Nnn #1 {#2} {#3} }
+ }
+
+\PrgNewFunction \SeqConcat { M M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gconcat:NNN #1 #2 #3 } { \seq_concat:NNN #1 #2 #3 }
+ }
+
+\PrgNewFunction \SeqClear { M }
+ {
+ \__fun_do_assignment:Nnn #1 { \seq_gclear:N #1 } { \seq_clear:N #1 }
+ }
+
+\PrgNewFunction \SeqClearNew { M }
+ {
+ \__fun_do_assignment:Nnn #1 { \seq_gclear_new:N #1 } { \seq_clear_new:N #1 }
+ }
+
+\PrgNewFunction \SeqPutLeft { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gput_left:Nn #1 {#2} } { \seq_put_left:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \SeqPutRight { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gput_right:Nn #1 {#2} } { \seq_put_right:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \SeqVarRemoveDuplicates { M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gremove_duplicates:N #1 } { \seq_remove_duplicates:N #1 }
+ }
+
+\PrgNewFunction \SeqVarRemoveAll { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gremove_all:Nn #1 {#2} } { \seq_remove_all:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \SeqVarReverse { M }
+ {
+ \__fun_do_assignment:Nnn #1 { \seq_greverse:N #1 } { \seq_reverse:N #1 }
+ }
+
+\PrgNewFunction \SeqVarSort { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gsort:Nn #1 {#2} } { \seq_sort:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \SeqVarCount { M } { \Expand { \seq_count:N #1 } }
+
+\PrgNewFunction \SeqGet { M M }
+ {
+ \seq_get:NN #1 #2
+ \__fun_quark_upgrade_no_value:N #2
+ }
+\PrgNewFunction \SeqGetT { M M n } { \seq_get:NNT #1 #2 {#3} }
+\PrgNewFunction \SeqGetF { M M n } { \seq_get:NNF #1 #2 {#3} }
+\PrgNewFunction \SeqGetTF { M M n n } { \seq_get:NNTF #1 #2 {#3} {#4} }
+
+\PrgNewFunction \SeqPop { M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop:NN #1 #2 } { \seq_pop:NN #1 #2 }
+ \__fun_quark_upgrade_no_value:N #2
+ }
+\PrgNewFunction \SeqPopT { M M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop:NNT #1 #2 {#3} } { \seq_pop:NNT #1 #2 {#3} }
+ }
+\PrgNewFunction \SeqPopF { M M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop:NNF #1 #2 {#3} } { \seq_pop:NNF #1 #2 {#3} }
+ }
+\PrgNewFunction \SeqPopTF { M M n n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop:NNTF #1 #2 {#3} {#4} } { \seq_pop:NNTF #1 #2 {#3} {#4} }
+ }
+
+\PrgNewFunction \SeqPush { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpush:Nn #1 {#2} } { \seq_push:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \SeqGetLeft { M M }
+ {
+ \seq_get_left:NN #1 #2
+ \__fun_quark_upgrade_no_value:N #2
+ }
+\PrgNewFunction \SeqGetLeftT { M M n } { \seq_get_left:NNT #1 #2 {#3} }
+\PrgNewFunction \SeqGetLeftF { M M n } { \seq_get_left:NNF #1 #2 {#3} }
+\PrgNewFunction \SeqGetLeftTF { M M n n } { \seq_get_left:NNTF #1 #2 {#3} {#4} }
+
+\PrgNewFunction \SeqGetRight { M M }
+ {
+ \seq_get_right:NN #1 #2
+ \__fun_quark_upgrade_no_value:N #2
+ }
+\PrgNewFunction \SeqGetRightT { M M n } { \seq_get_right:NNT #1 #2 {#3} }
+\PrgNewFunction \SeqGetRightF { M M n } { \seq_get_right:NNF #1 #2 {#3} }
+\PrgNewFunction \SeqGetRightTF { M M n n } { \seq_get_right:NNTF #1 #2 {#3} {#4} }
+
+\PrgNewFunction \SeqPopLeft { M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_left:NN #1 #2 } { \seq_pop_left:NN #1 #2 }
+ \__fun_quark_upgrade_no_value:N #2
+ }
+\PrgNewFunction \SeqPopLeftT { M M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_left:NNT #1 #2 {#3} } { \seq_pop_left:NNT #1 #2 {#3} }
+ }
+\PrgNewFunction \SeqPopLeftF { M M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_left:NNF #1 #2 {#3} } { \seq_pop_left:NNF #1 #2 {#3} }
+ }
+\PrgNewFunction \SeqPopLeftTF { M M n n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_left:NNTF #1 #2 {#3} {#4} }
+ { \seq_pop_left:NNTF #1 #2 {#3} {#4} }
+ }
+
+\PrgNewFunction \SeqPopRight { M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_right:NN #1 #2 } { \seq_pop_right:NN #1 #2 }
+ \__fun_quark_upgrade_no_value:N #2
+ }
+\PrgNewFunction \SeqPopRightT { M M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_right:NNT #1 #2 {#3} } { \seq_pop_right:NNT #1 #2 {#3} }
+ }
+\PrgNewFunction \SeqPopRightF { M M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_right:NNF #1 #2 {#3} } { \seq_pop_right:NNF #1 #2 {#3} }
+ }
+\PrgNewFunction \SeqPopRightTF { M M n n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \seq_gpop_right:NNTF #1 #2 {#3} {#4} }
+ { \seq_pop_right:NNTF #1 #2 {#3} {#4} }
+ }
+
+\PrgNewFunction \SeqVarItem { M m } { \Expand { \seq_item:Nn #1 {#2} } }
+
+\PrgNewFunction \SeqVarRandItem { M } { \Expand { \seq_rand_item:N #1 } }
+
+\PrgNewFunction \SeqVarMapInline { M n }
+ {
+ \seq_map_inline:Nn #1 {#2}
+ }
+
+\PrgNewFunction \SeqVarMapVariable { M M n }
+ {
+ \seq_map_variable:NNn #1 #2 {#3}
+ }
+
+\cs_set_eq:NN \SeqMapBreak \seq_map_break:
+
+\PrgNewConditional \SeqIfExist { M }
+ {
+ \seq_if_exist:NTF #1 { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+
+\PrgNewConditional \SeqVarIfEmpty { M }
+ {
+ \seq_if_empty:NTF #1 { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+
+\PrgNewConditional \SeqVarIfIn { M m }
+ {
+ \seq_if_in:NnTF #1 {#2}
+ { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+
+%%% --------------------------------------------------------
+%%> \section{Interfaces for Property Lists (Prop)}
+%%% --------------------------------------------------------
+
+\prop_new:N \lTmpaProp \prop_new:N \lTmpbProp \prop_new:N \lTmpcProp
+\prop_new:N \lTmpiProp \prop_new:N \lTmpjProp \prop_new:N \lTmpkProp
+\prop_new:N \l@Funx@Prop \prop_new:N \l@Funy@Prop \prop_new:N \l@Funz@Prop
+
+\prop_new:N \gTmpaProp \prop_new:N \gTmpbProp \prop_new:N \gTmpcProp
+\prop_new:N \gTmpiProp \prop_new:N \gTmpjProp \prop_new:N \gTmpkProp
+\prop_new:N \g@Funx@Prop \prop_new:N \g@Funy@Prop \prop_new:N \g@Funz@Prop
+
+\prop_set_eq:NN \cEmptyProp \c_empty_prop
+
+\PrgNewFunction \PropNew { M } { \prop_new:N #1 }
+
+\PrgNewFunction \PropVarLog { M } { \prop_log:N #1 }
+
+\PrgNewFunction \PropVarShow { M } { \prop_show:N #1 }
+
+\PrgNewFunction \PropConstFromKeyval { M m }
+ { \prop_const_from_keyval:Nn #1 { #2 } }
+
+\PrgNewFunction \PropSetFromKeyval { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gset_from_keyval:Nn #1 {#2} } { \prop_set_from_keyval:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \PropSetEq { M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gset_eq:NN #1 #2 } { \prop_set_eq:NN #1 #2 }
+ }
+
+\PrgNewFunction \PropClear { M }
+ {
+ \__fun_do_assignment:Nnn #1 { \prop_gclear:N #1 } { \prop_clear:N #1 }
+ }
+
+\PrgNewFunction \PropClearNew { M }
+ {
+ \__fun_do_assignment:Nnn #1 { \prop_gclear_new:N #1 } { \prop_clear_new:N #1 }
+ }
+
+\PrgNewFunction \PropConcat { M M M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gconcat:NNN #1 #2 #3 } { \prop_concat:NNN #1 #2 #3 }
+ }
+
+\PrgNewFunction \PropPut { M m m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gput:Nnn #1 {#2} {#3} } { \prop_put:Nnn #1 {#2} {#3} }
+ }
+
+\PrgNewFunction \PropPutIfNew { M m m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gput_if_new:Nnn #1 {#2} {#3} } { \prop_put_if_new:Nnn #1 {#2} {#3} }
+ }
+
+\PrgNewFunction \PropPutFromKeyval { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gput_from_keyval:Nn #1 {#2} } { \prop_put_from_keyval:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \PropVarRemove { M m }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gremove:Nn #1 {#2} } { \prop_remove:Nn #1 {#2} }
+ }
+
+\PrgNewFunction \PropVarCount { M } { \Expand { \prop_count:N #1 } }
+
+\PrgNewFunction \PropVarItem { M m } { \Expand { \prop_item:Nn #1 {#2} } }
+
+\PrgNewFunction \PropToKeyval { M } { \Expand { \prop_to_keyval:N #1 } }
+
+\PrgNewFunction \PropGet { M m M }
+ {
+ \prop_get:NnN #1 {#2} #3
+ \__fun_quark_upgrade_no_value:N #3
+ }
+\PrgNewFunction \PropGetT { M m M n } { \prop_get:NnNT #1 {#2} #3 {#4} }
+\PrgNewFunction \PropGetF { M m M n } { \prop_get:NnNF #1 {#2} #3 {#4} }
+\PrgNewFunction \PropGetTF { M m M n n } { \prop_get:NnNTF #1 {#2} #3 {#4} {#5} }
+
+\PrgNewFunction \PropPop { M m M }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gpop:NnN #1 {#2} #3 } { \prop_pop:NnN #1 {#2} #3 }
+ \__fun_quark_upgrade_no_value:N #3
+ }
+\PrgNewFunction \PropPopT { M m M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gpop:NnNT #1 {#2} #3 {#4} } { \prop_pop:NnNT #1 {#2} #3 {#4} }
+ }
+\PrgNewFunction \PropPopF { M m M n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gpop:NnNF #1 {#2} #3 {#4} } { \prop_pop:NnNF #1 {#2} #3 {#4} }
+ }
+\PrgNewFunction \PropPopTF { M m M n n }
+ {
+ \__fun_do_assignment:Nnn #1
+ { \prop_gpop:NnNTF #1 {#2} #3 {#4} {#5} }
+ { \prop_pop:NnNTF #1 {#2} #3 {#4} {#5} }
+ }
+
+\PrgNewFunction \PropVarMapInline { M n }
+ {
+ \prop_map_inline:Nn #1 {#2}
+ }
+
+\cs_set_eq:NN \PropMapBreak \prop_map_break:
+
+\PrgNewConditional \PropIfExist { M }
+ {
+ \prop_if_exist:NTF #1 { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+
+\PrgNewConditional \PropVarIfEmpty { M }
+ {
+ \prop_if_empty:NTF #1 { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+
+\PrgNewConditional \PropVarIfIn { M m }
+ {
+ \prop_if_in:NnTF #1 {#2}
+ { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+
+%%% --------------------------------------------------------
+%%> \section{Interfaces for Quarks (Quark)}
+%%% --------------------------------------------------------
+
+\quark_new:N \qNoValue
+
+\cs_new_protected:Npn \__fun_quark_upgrade_no_value:N #1
+ {
+ \quark_if_no_value:NT #1 { \tl_set_eq:NN #1 \qNoValue }
+ }
+
+\PrgNewConditional \QuarkVarIfNoValue { M }
+ {
+ \tl_if_eq:NNTF \qNoValue #1
+ { \Result { \cTrueBool } } { \Result { \cFalseBool } }
+ }
+