• R/O
  • SSH

YSLib: Commit

The YSLib project - main repository


Commit MetaInfo

Revisión4d7fdf52b6d565fc9db7bc5485f05e3d5e36a180 (tree)
Tiempo2022-07-25 06:22:59
AutorFrankHB <frankhb1989@gmai...>
CommiterFrankHB

Log Message

更新主分支版本: build 950 rev 10 。

Cambiar Resumen

Diferencia incremental

diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/include/NPL/NPLA.h
--- a/YFramework/include/NPL/NPLA.h Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/include/NPL/NPLA.h Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA.h
1212 \ingroup NPL
1313 \brief NPLA 公共接口。
14-\version r9695
14+\version r9714
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 663
1717 \par 创建时间:
1818 2016-01-07 10:32:34 +0800
1919 \par 修改时间:
20- 2022-07-06 08:28 +0800
20+ 2022-07-24 21:14 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -35,14 +35,14 @@
3535 // std::initializer_list, IsBranch, type_id, shared_ptr,
3636 // ystdex::is_nothrow_copy_constructible, ystdex::is_nothrow_copy_assignable,
3737 // ystdex::is_nothrow_move_constructible, ystdex::is_nothrow_move_assignable,
38-// EnsureValueTags, AssertValueTags, IsTyped, ThrowListTypeErrorForInvalidType,
39-// observer_ptr, TryAccessValue, IsAtom, IsLeaf, ystdex::equality_comparable,
40-// weak_ptr, lref, AssertReferentTags, ystdex::get_equal_to, NPL::IsMovable,
41-// pair, std::declval, ystdex::invoke_value_or, ystdex::expand_proxy,
42-// Access, ystdex::ref_eq, ValueObject, NPL::SetContentWith, std::for_each,
43-// TNIter, AccessFirstSubterm, AssertBranch, NPL::Deref,
44-// YSLib::EmplaceCallResult, ystdex::less, YSLib::map, pmr,
45-// ystdex::copy_and_swap, NoContainer, ystdex::try_emplace,
38+// EnsureValueTags, AssertValueTags, IsPair, IsList, HasStickySubterm,
39+// ThrowListTypeErrorForInvalidType, observer_ptr, TryAccessValue, IsAtom,
40+// IsLeaf, ystdex::equality_comparable, weak_ptr, lref, AssertReferentTags,
41+// ystdex::get_equal_to, NPL::IsMovable, pair, std::declval,
42+// ystdex::invoke_value_or, ystdex::expand_proxy, Access, ystdex::ref_eq,
43+// ValueObject, NPL::SetContentWith, std::for_each, TNIter, AccessFirstSubterm,
44+// AssertBranch, NPL::Deref, YSLib::EmplaceCallResult, ystdex::less,
45+// YSLib::map, pmr, ystdex::copy_and_swap, NoContainer, ystdex::try_emplace,
4646 // ystdex::try_emplace_hint, ystdex::insert_or_assign, type_info,
4747 // ystdex::expanded_function, ystdex::enable_if_same_param_t,
4848 // ystdex::exclude_self_t, ystdex::make_obj_using_allocator,
@@ -457,6 +457,18 @@
457457 PDefH(bool, IsCombiningTerm, const TermNode& term) ynothrow
458458 ImplRet(IsPair(term))
459459
460+/*!
461+\brief 断言规约合并项。
462+\pre 断言:参数指定的项是规约合并项。
463+\pre 断言:若为列表,不具有粘滞位。
464+\since build 950
465+*/
466+YB_NONNULL(2) inline PDefH(void, AssertCombiningTerm, const TermNode& term,
467+ const char* msg = "Invalid term found for combined term.") ynothrowv
468+ ImplExpr(yunused(term), yunused(msg), YAssert(IsCombiningTerm(term), msg),
469+ YAssert(!(IsList(term) && HasStickySubterm(term)),
470+ "Invalid representation found."))
471+
460472
461473 /*! \defgroup TermAccessAuxiliary Term Access Auxiliary API
462474 \brief 辅助项访问接口。
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/include/NPL/NPLA1.h
--- a/YFramework/include/NPL/NPLA1.h Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/include/NPL/NPLA1.h Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1.h
1212 \ingroup NPL
1313 \brief NPLA1 公共接口。
14-\version r9538
14+\version r9551
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 472
1717 \par 创建时间:
1818 2014-02-02 17:58:24 +0800
1919 \par 修改时间:
20- 2022-06-18 02:40 +0800
20+ 2022-07-24 21:31 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -1138,13 +1138,19 @@
11381138 public:
11391139 /*!
11401140 \brief 检查是否符合应用子的参数列表。
1141- \pre 断言:若为列表,不具有粘滞位。
1142- \throw ListReductionFailure 第一参数不等于 0 且第二参数不表示列表。
1141+ \pre 参数指定的项是规约合并项。
11431142 \note 因为对象语言中的参数求值规则不影响参数项的结构,所以调用前只需要检查一次。
1144- \since build 948
1143+ \sa AssertCombiningTerm
1144+ \since build 950
11451145 */
1146+ //@{
1147+ //! \throw ListReductionFailure 参数不表示列表。
11461148 static void
1147- CheckArguments(size_t, TermNode&);
1149+ CheckArguments(const TermNode&);
1150+ //! \throw ListReductionFailure 第一参数不等于 0 且第二参数不表示列表。
1151+ static void
1152+ CheckArguments(size_t, const TermNode&);
1153+ //@}
11481154
11491155 private:
11501156 //! \since build 859
@@ -1597,7 +1603,7 @@
15971603 参数指定形式参数、实际参数、两个处理器、绑定选项和引用值关联的环境。
15981604 其中,形式参数被视为作为形式参数树的右值。
15991605 绑定选项以 TermTags 编码,但含义和作用在项上时不完全相同:
1600-Unique 表示唯一引用项(在此即消亡值值);
1606+Unique 表示唯一引用项(在此即消亡值);
16011607 Nonmodifying 表示需要复制;
16021608 Temporary 表示不被共享的项(在此即纯右值或没有匹配列表的引用值)。
16031609 当需要复制时,递归处理的所有对实际参数的绑定以复制代替转移;
@@ -1617,7 +1623,7 @@
16171623 若最后的子项为 . 起始的记号,则匹配操作数中结尾的任意个数的项作为结尾序列。
16181624 其它子项一一匹配操作数的子项。
16191625 若项是空列表,则操作数的对应的项应为空列表。
1620- 若项是引用值,则以表示其被引用对象的项作为子项继续匹配。
1626+ 若项是引用值,则以表示其被引用对象的项作为子项,继续匹配一次。
16211627 若项是 #ignore ,则忽略操作数对应的项。
16221628 若项的值不是符号,则匹配出错。
16231629 否则,匹配非列表项。
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/include/NPL/NPLA1Forms.h
--- a/YFramework/include/NPL/NPLA1Forms.h Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/include/NPL/NPLA1Forms.h Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Forms.h
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r8742
14+\version r8766
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2020-02-15 11:19:21 +0800
1919 \par 修改时间:
20- 2022-06-14 18:32 +0800
20+ 2022-07-25 01:51 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -105,9 +105,6 @@
105105 class YF_API EncapsulationBase
106106 {
107107 private:
108- // XXX: Is it possible to support %TermReference safety check here with
109- // anchors?
110- // TODO: Add naming scheme and persistence interoperations?
111108 shared_ptr<void> p_type;
112109
113110 public:
@@ -278,8 +275,12 @@
278275 ::call(f, NPL::Deref(std::next(term.begin())), yforward(args)...)))
279276 {
280277 RetainN(term);
278+
279+ auto& x(NPL::Deref(std::next(term.begin())));
280+
281+ AssertValueTags(x);
281282 return ystdex::expand_proxy<yimpl(void)(TermNode&, _tParams&&...)>::call(f,
282- NPL::Deref(std::next(term.begin())), yforward(args)...);
283+ x, yforward(args)...);
283284 }
284285
285286 //! \brief 解析节点的子节点并调用一元函数。
@@ -397,9 +398,11 @@
397398 auto i(term.begin());
398399 auto& x(NPL::Deref(++i));
399400
401+ AssertValueTags(x);
402+ AssertValueTags(NPL::Deref(++i));
400403 return NPL::EmplaceCallResultOrReturn(term, ystdex::invoke_nonvoid(
401404 ystdex::make_expanded<void(TermNode&, TermNode&, _tParams&&...)>(
402- std::ref(f)), x, NPL::Deref(++i), yforward(args)...));
405+ std::ref(f)), x, *i, yforward(args)...));
403406 }
404407
405408 template<typename _type, typename _type2, typename _func, typename... _tParams>
@@ -1363,7 +1366,7 @@
13631366 按值传递返回值:提升项。
13641367
13651368 参考调用文法:
1366-<pre>$lambda/e \<environment> \<formals> \<body></pre>
1369+<pre>$lambda/e \<parent> \<formals> \<body></pre>
13671370 */
13681371 YF_API ReductionStatus
13691372 LambdaWithEnvironment(TermNode&, ContextNode&);
@@ -1372,7 +1375,7 @@
13721375 在返回时不提升项,允许返回引用。
13731376
13741377 参考调用文法:
1375-<pre>$lambda/e% \<environment> \<formals> \<body></pre>
1378+<pre>$lambda/e% \<parent> \<formals> \<body></pre>
13761379 */
13771380 YF_API ReductionStatus
13781381 LambdaWithEnvironmentRef(TermNode&, ContextNode&);
@@ -1427,7 +1430,7 @@
14271430 按值传递返回值:提升项以避免返回引用造成内存安全问题。
14281431
14291432 参考调用文法:
1430-<pre>$vau/e \<environment> \<formals> \<eformal> \<body></pre>
1433+<pre>$vau/e \<parent> \<formals> \<eformal> \<body></pre>
14311434 */
14321435 YF_API ReductionStatus
14331436 VauWithEnvironment(TermNode&, ContextNode&);
@@ -1436,7 +1439,7 @@
14361439 在返回时不提升项,允许返回引用。
14371440
14381441 参考调用文法:
1439-<pre>$vau/e% \<environment> \<formals> \<eformal> \<body></pre>
1442+<pre>$vau/e% \<parent> \<formals> \<eformal> \<body></pre>
14401443 */
14411444 YF_API ReductionStatus
14421445 VauWithEnvironmentRef(TermNode&, ContextNode&);
@@ -1480,7 +1483,7 @@
14801483 按值传递返回值:提升项以避免返回引用造成内存安全问题。
14811484
14821485 参考调用文法:
1483-<pre>$wvau/e \<environment> \<formals> \<eformal> \<body></pre>
1486+<pre>$wvau/e \<parent> \<formals> \<eformal> \<body></pre>
14841487 */
14851488 YF_API ReductionStatus
14861489 WVauWithEnvironment(TermNode&, ContextNode&);
@@ -1489,7 +1492,7 @@
14891492 在返回时不提升项,允许返回引用。
14901493
14911494 参考调用文法:
1492-<pre>$wvau/e% \<environment> \<formals> \<eformal> \<body></pre>
1495+<pre>$wvau/e% \<parent> \<formals> \<eformal> \<body></pre>
14931496 */
14941497 YF_API ReductionStatus
14951498 WVauWithEnvironmentRef(TermNode&, ContextNode&);
@@ -1653,12 +1656,12 @@
16531656
16541657 /*!
16551658 \brief 使用可选的参数指定的不定数量的元素和结尾列表构造新列表。
1656-\exception ParameterMismatch 参数不是
1657-\throw ListTypeError 参数超过一个,且最后参数不是列表。
16581659 \since build 860
16591660 */
16601661 //@{
16611662 /*!
1663+\sa LiftToReturn
1664+
16621665 结果是构造的列表的值。不保留结果中的引用值。
16631666
16641667 参考调用文法:
@@ -1991,9 +1994,16 @@
19911994 //@{
19921995 /*!
19931996 \brief 捕获一次续延,具现为一等续延作为参数调用合并子。
1997+\warning 应确保实现选项以避免未定义行为。
19941998
19951999 参考调用文法:
19962000 <pre>call/1cc \<combiner></pre>
2001+
2002+对捕获的续延,若被合并子调用,则可移除特定的对象语言活动记录。
2003+调用捕获的合并子应确保启用实现选项 NPL_Impl_NPLA1_Enable_Thunked ,
2004+ 以确保随活动记录时同时在宿主语言中移除对相应资源访问;
2005+否则,除非被抛出异常,之后在宿主语言(主调函数)中访问这些活动记录,
2006+ 总是存在未定义行为。
19972007 */
19982008 YF_API ReductionStatus
19992009 Call1CC(TermNode&, ContextNode&);
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/source/NPL/Dependency.cpp
--- a/YFramework/source/NPL/Dependency.cpp Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/source/NPL/Dependency.cpp Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Dependency.cpp
1212 \ingroup NPL
1313 \brief 依赖管理。
14-\version r6961
14+\version r7069
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 623
1717 \par 创建时间:
1818 2015-08-09 22:14:45 +0800
1919 \par 修改时间:
20- 2022-06-21 01:06 +0800
20+ 2022-07-20 22:19 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -321,7 +321,6 @@
321321 auto& m(d.GetMapRef());
322322 // TODO: Check environments allocator equality.
323323 const auto a(m.get_allocator());
324- // TODO: Support more implementations?
325324 const auto copy_parent([&](Environment& dst, const Environment& parent){
326325 auto p_env(NPL::AllocateEnvironment(a));
327326
@@ -515,10 +514,10 @@
515514 {"f", "$lambda", "formals"});
516515 AddDefineFunction(rctx, "$defl%!", {"&f", "&formals"},
517516 {"f", "$lambda%", "formals"});
518- AddDefineFunction(rctx, "$defl/e!", {"&f", "&p", "&formals",
519- }, {"f", "$lambda/e", "p", "formals"});
520- AddDefineFunction(rctx, "$defl/e%!", {"&f", "&p", "&formals",
521- }, {"f", "$lambda/e%", "p", "formals"});
517+ AddDefineFunction(rctx, "$defl/e!", {"&f", "&p", "&formals"},
518+ {"f", "$lambda/e", "p", "formals"});
519+ AddDefineFunction(rctx, "$defl/e%!", {"&f", "&p", "&formals"},
520+ {"f", "$lambda/e%", "p", "formals"});
522521 # endif
523522 }
524523 #endif
@@ -581,6 +580,8 @@
581580 RegisterUnary(ctx, "nullv?", IsEmpty);
582581 RegisterUnary(ctx, "branch?", ComposeReferencedTermOp(IsBranch));
583582 RegisterUnary(ctx, "branchv?", IsBranch);
583+ RegisterUnary(ctx, "pair?", ComposeReferencedTermOp(IsPair));
584+ RegisterUnary(ctx, "pairv?", IsPair);
584585 RegisterUnary(ctx, "reference?", IsReferenceTerm);
585586 RegisterUnary(ctx, "unique?", IsUniqueTerm);
586587 RegisterUnary(ctx, "modifiable?", IsModifiableTerm);
@@ -991,10 +992,15 @@
991992 context.Perform(
992993 # if NPL_Impl_NPLA1_Native_EnvironmentPrimitives
993994 R"NPL(
995+$def! forward! wrap
996+ ($vau/e% (() get-current-environment) (%x) #ignore
997+ $if (bound-lvalue? ($resolve-identifier x)) x (move! x));
994998 $def! $vau $vau/e (() get-current-environment) (&formals &ef .&body) d
995- eval (cons $vau/e (cons d (cons formals (cons ef (move! body))))) d;
999+ eval (cons $vau/e (cons d (cons% (forward! formals)
1000+ (cons% ef (forward! body))))) d;
9961001 $def! $vau% $vau (&formals &ef .&body) d
997- eval (cons $vau/e% (cons d (cons formals (cons ef (move! body))))) d;
1002+ eval (cons $vau/e% (cons d (cons% (forward! formals)
1003+ (cons% ef (forward! body))))) d;
9981004 )NPL"
9991005 # else
10001006 R"NPL(
@@ -1040,15 +1046,23 @@
10401046 eval (list bound-lvalue? (list $resolve-identifier s)) d;
10411047 )NPL"
10421048 # if NPL_Impl_NPLA1_Use_Id_Vau
1049+# if !NPL_Impl_NPLA1_Native_EnvironmentPrimitives
10431050 R"NPL(
10441051 $def! forward! wrap
10451052 ($vau% (%x) #ignore $if ($lvalue-identifier? x) x (move! x));
1053+ )NPL"
1054+# endif
1055+ R"NPL(
10461056 $def! list% wrap ($vau &x #ignore forward! x);
10471057 $def! rlist wrap ($vau ((.&x)) #ignore move! x);
10481058 )NPL"
10491059 # else
1060+# if !NPL_Impl_NPLA1_Native_EnvironmentPrimitives
10501061 R"NPL(
10511062 $def! forward! $lambda% (%x) $if ($lvalue-identifier? x) x (move! x);
1063+ )NPL"
1064+# endif
1065+ R"NPL(
10521066 $def! list% $lambda &x forward! x;
10531067 $def! rlist $lambda ((.&x)) move! x;
10541068 )NPL"
@@ -1057,46 +1071,54 @@
10571071 $def! $remote-eval $vau (&o &e) d eval (forward! o) (eval e d);
10581072 $def! $remote-eval% $vau% (&o &e) d eval% (forward! o) (eval e d);
10591073 $def! $deflazy! $vau (&definiend .&body) d
1060- eval (list $def! definiend $quote body) d;
1074+ eval (list% $def! (forward! definiend) $quote (forward! body)) d;
10611075 $def! $set! $vau (&e &formals .&body) d
1062- eval (list $def! formals (unwrap eval%) (move! body) d) (eval e d);
1076+ eval (list% $def! (forward! formals) (unwrap eval%) (forward! body) d)
1077+ (eval e d);
10631078 $def! $setrec! $vau (&e &formals .&body) d
1064- eval (list $defrec! formals (unwrap eval%) (move! body) d) (eval e d);
1079+ eval (list% $defrec! (forward! formals) (unwrap eval%) (forward! body) d)
1080+ (eval e d);
10651081 $def! $wvau $vau (&formals &ef .&body) d
1066- wrap (eval (cons $vau (cons formals (cons ef (move! body)))) d);
1082+ wrap (eval (cons $vau (cons% (forward! formals) (cons% ef (forward! body))))
1083+ d);
10671084 $def! $wvau% $vau (&formals &ef .&body) d
1068- wrap (eval (cons $vau% (cons formals (cons ef (move! body)))) d);
1085+ wrap (eval
1086+ (cons $vau% (cons% (forward! formals) (cons% ef (forward! body)))) d);
10691087 $def! $wvau/e $vau (&p &formals &ef .&body) d
1070- wrap (eval (cons $vau/e (cons p (cons formals (cons ef (move! body))))) d);
1088+ wrap (eval (cons $vau/e
1089+ (cons p (cons% (forward! formals) (cons% ef (forward! body))))) d);
10711090 $def! $wvau/e% $vau (&p &formals &ef .&body) d
1072- wrap (eval (cons $vau/e% (cons p (cons formals (cons ef (move! body))))) d);
1091+ wrap (eval (cons $vau/e%
1092+ (cons p (cons% (forward! formals) (cons% ef (forward! body))))) d);
10731093 )NPL"
10741094 # if NPL_Impl_NPLA1_Use_Id_Vau
10751095 R"NPL(
10761096 $def! $lambda $vau (&formals .&body) d
1077- wrap (eval (cons $vau (cons formals (cons #ignore (move! body)))) d);
1097+ wrap (eval (cons $vau
1098+ (cons% (forward! formals) (cons% #ignore (forward! body)))) d);
10781099 $def! $lambda% $vau (&formals .&body) d
1079- wrap (eval (cons $vau% (cons formals (cons #ignore (move! body)))) d);
1100+ wrap (eval (cons $vau%
1101+ (cons% (forward! formals) (cons% #ignore (forward! body)))) d);
10801102 )NPL"
10811103 # endif
10821104 // NOTE: Use of 'eqv?' is more efficient than '$if'.
10831105 R"NPL(
10841106 $def! $lambda/e $vau (&p &formals .&body) d
1085- wrap (eval
1086- (cons $vau/e (cons p (cons formals (cons #ignore (move! body))))) d);
1107+ wrap (eval (cons $vau/e
1108+ (cons p (cons% (forward! formals) (cons% #ignore (forward! body))))) d);
10871109 $def! $lambda/e% $vau (&p &formals .&body) d
1088- wrap (eval
1089- (cons $vau/e% (cons p (cons formals (cons #ignore (move! body))))) d);
1110+ wrap (eval (cons $vau/e%
1111+ (cons p (cons% (forward! formals) (cons% #ignore (forward! body))))) d);
10901112 $def! $sequence
10911113 ($lambda (&se)
10921114 ($lambda #ignore $vau/e% se &exprseq d
1093- $if (null? exprseq) #inert (eval% (cons% $aux (move! exprseq)) d))
1115+ $if (null? exprseq) #inert (eval% (cons% $aux (forward! exprseq)) d))
10941116 ($set! se $aux
10951117 $vau/e% (weaken-environment se) (&head .&tail) d
10961118 $if (null? tail) (eval% (forward! head) d)
10971119 (($vau% (&t) e ($lambda% #ignore eval% t e)
10981120 (eval% (forward! head) d))
1099- (eval% (cons% $aux (move! tail)) d))))
1121+ (eval% (cons% $aux (forward! tail)) d))))
11001122 (make-environment (() get-current-environment));
11011123 $def! collapse $lambda% (%x)
11021124 $if (uncollapsed? x) (($if ($lvalue-identifier? x) ($lambda% (%x) x) id)
@@ -1113,34 +1135,34 @@
11131135 "Syntax error in applying form.")) opt));
11141136 $def! list* $lambda (&head .&tail)
11151137 $if (null? tail) (forward! head)
1116- (cons (forward! head) (apply list* (move! tail)));
1138+ (cons (forward! head) (apply list* (forward! tail)));
11171139 $def! list*% $lambda (&head .&tail)
11181140 $if (null? tail) (forward! head)
1119- (cons% (forward! head) (apply list*% (move! tail)));
1141+ (cons% (forward! head) (apply list*% (forward! tail)));
11201142 $def! $defv! $vau (&$f &formals &ef .&body) d
1121- eval (list* $def! $f $vau formals ef (move! body)) d;
1143+ eval (list*% $def! $f $vau (forward! formals) ef (forward! body)) d;
11221144 $defv! $defv%! (&$f &formals &ef .&body) d
1123- eval (list* $def! $f $vau% formals ef (move! body)) d;
1145+ eval (list*% $def! $f $vau% (forward! formals) ef (forward! body)) d;
11241146 $defv! $defv/e! (&$f &p &formals &ef .&body) d
1125- eval (list* $def! $f $vau/e p formals ef (move! body)) d;
1147+ eval (list*% $def! $f $vau/e p (forward! formals) ef (forward! body)) d;
11261148 $defv! $defv/e%! (&$f &p &formals &ef .&body) d
1127- eval (list* $def! $f $vau/e% p formals ef (move! body)) d;
1149+ eval (list*% $def! $f $vau/e% p (forward! formals) ef (forward! body)) d;
11281150 $defv! $defw! (&f &formals &ef .&body) d
1129- eval (list* $def! f $wvau formals ef (move! body)) d;
1151+ eval (list*% $def! f $wvau (forward! formals) ef (forward! body)) d;
11301152 $defv! $defw%! (&f &formals &ef .&body) d
1131- eval (list* $def! f $wvau% formals ef (move! body)) d;
1153+ eval (list*% $def! f $wvau% (forward! formals) ef (forward! body)) d;
11321154 $defv! $defw/e! (&f &p &formals &ef .&body) d
1133- eval (list* $def! f $wvau/e p formals ef (move! body)) d;
1155+ eval (list*% $def! f $wvau/e p (forward! formals) ef (forward! body)) d;
11341156 $defv! $defw/e%! (&f &p &formals &ef .&body) d
1135- eval (list* $def! f $wvau/e% p formals ef (move! body)) d;
1157+ eval (list*% $def! f $wvau/e% p (forward! formals) ef (forward! body)) d;
11361158 $defv! $defl! (&f &formals .&body) d
1137- eval (list* $def! f $lambda formals (move! body)) d;
1159+ eval (list*% $def! f $lambda (forward! formals) (forward! body)) d;
11381160 $defv! $defl%! (&f &formals .&body) d
1139- eval (list* $def! f $lambda% formals (move! body)) d;
1161+ eval (list*% $def! f $lambda% (forward! formals) (forward! body)) d;
11401162 $defv! $defl/e! (&f &p &formals .&body) d
1141- eval (list* $def! f $lambda/e p formals (move! body)) d;
1163+ eval (list*% $def! f $lambda/e p (forward! formals) (forward! body)) d;
11421164 $defv! $defl/e%! (&f &p &formals .&body) d
1143- eval (list* $def! f $lambda/e% p formals (move! body)) d;
1165+ eval (list*% $def! f $lambda/e% p (forward! formals) (forward! body)) d;
11441166 $defw%! forward-first% (&appv (&x .)) d
11451167 apply (forward! appv) (list% ($move-resolved! x)) d;
11461168 $defl%! first (&l)
@@ -1161,23 +1183,34 @@
11611183 $defl! set-first! (&l x) assign@! (first@ (forward! l)) (move! x);
11621184 $defl! set-first@! (&l &x) assign@! (first@ (forward! l)) (forward! x);
11631185 $defl! set-first%! (&l &x) assign%! (first@ (forward! l)) (forward! x);
1164-$defl! equal? (&x &y)
1165- $if ($if (branch? x) (branch? y) #f)
1166- ($if (equal? (first& x) (first& y))
1167- (equal? (rest& x) (rest& y)) #f) (eqv? x y);
1186+$def! equal? ($lambda (&ce)
1187+(
1188+ $lambda/e (() ($lambda/e ce ()
1189+ (
1190+ $defl! peq? (&x &y)
1191+ (
1192+ $def! (px py) list (pair? x) (pair? y);
1193+ $if ($if px py #f)
1194+ ($if (equal? (first& x) (first& y)) (peq? (rest& x) (rest& y))
1195+ #f)
1196+ (eqv? px py)
1197+ );
1198+ () lock-current-environment
1199+ ))) (&x &y) $if (eql? x y) (peq? x y) #f
1200+)) (() get-current-environment);
11681201 $defl%! check-environment (&e) $sequence (eval% #inert e) (forward! e);
11691202 $defl%! check-parent (&p) $sequence ($vau/e% p . #ignore) (forward! p);
11701203 $defv%! $cond &clauses d
11711204 $if (null? clauses) #inert
11721205 (apply ($lambda% ((&test .&body) .&clauses)
1173- $if (eval test d) (eval% (move! body) d)
1174- (apply (wrap $cond) (move! clauses) d))
1175- (move! clauses));
1206+ $if (eval test d) (eval% (forward! body) d)
1207+ (apply (wrap $cond) (forward! clauses) d))
1208+ (forward! clauses));
11761209 $defv%! $when (&test .&exprseq) d
1177- $if (eval test d) (eval% (list* () $sequence (move! exprseq)) d);
1210+ $if (eval test d) (eval% (list* () $sequence (forward! exprseq)) d);
11781211 $defv%! $unless (&test .&exprseq) d
11791212 $if (eval test d) #inert
1180- (eval% (list* () $sequence (move! exprseq)) d);
1213+ (eval% (list* () $sequence (forward! exprseq)) d);
11811214 $defl! not? (&x) eqv? x #f;
11821215 $defv%! $and &x d
11831216 $cond
@@ -1189,8 +1222,8 @@
11891222 $cond
11901223 ((null? x) #f)
11911224 ((null? (rest& x)) eval% (first (forward! x)) d)
1192- (#t ($lambda% (&r) $if r (forward! r) (eval% (cons% $or (rest% (forward! x)))
1193- d)) (eval% (move! (first& x)) d));
1225+ (#t ($lambda% (&r) $if r (forward! r) (eval%
1226+ (cons% $or (rest% (forward! x))) d)) (eval% (move! (first& x)) d));
11941227 $defw%! accl (&l &pred? &base &head &tail &sum) d
11951228 $if (apply pred? (list% l) d) (forward! base)
11961229 (apply accl (list% (apply tail (list% l) d) pred?
@@ -1217,11 +1250,11 @@
12171250 ($lambda (%x &xs) (cons% ($resolve-identifier x) (move! xs))))
12181251 (idv (forward! l));
12191252 $defl! list-concat (&x &y) foldr1 cons% (forward! y) (forward! x);
1220-$defl! append (.&ls) foldr1 list-concat () (move! ls);
1253+$defl! append (.&ls) foldr1 list-concat () (forward! ls);
12211254 $defl%! list-extract-first (&l) map1 first (forward! l);
12221255 $defl%! list-extract-rest% (&l) map1 rest% (forward! l);
12231256 $defl! list-push-front! (&l &x) $if (modifiable? l)
1224- (assign! l (cons% (forward! x) (($lambda ((.l)) (move! l)) (forward! l))))
1257+ (assign! l (cons% (forward! x) (idv l)))
12251258 (raise-type-error "Modifiable object expected.");
12261259 $def! ($let $let% $let/e $let/e% $let* $let*% $letrec $letrec%) ($lambda (&ce)
12271260 (
@@ -1233,35 +1266,35 @@
12331266 ($if (eval (list $lvalue-identifier? x) d) id expire) (eval% x d);
12341267 $defl%! mk-let ($ctor &bindings &body)
12351268 list* () (list* $ctor (list-extract-first bindings)
1236- (list (move! body))) (list-extract-rest% bindings);
1269+ (list% (forward! body))) (list-extract-rest% bindings);
12371270 $defl%! mk-let/e ($ctor &p &bindings &body)
12381271 list* () (list* $ctor p (list-extract-first bindings)
1239- (list (move! body))) (list-extract-rest% bindings);
1272+ (list% (forward! body))) (list-extract-rest% bindings);
12401273 $defl%! mk-let* ($let $let* &bindings &body)
1241- $if (null? bindings) (list* $let () (move! body))
1274+ $if (null? bindings) (list* $let () (forward! body))
12421275 (list $let (list (first% ($lqual* bindings)))
1243- (list* $let* (rest% ($lqual* bindings)) (move! body)));
1276+ (list* $let* (rest% ($lqual* bindings)) (forward! body)));
12441277 $defl%! mk-letrec ($let &bindings &body)
12451278 list $let () $sequence (list $def! (list-extract-first bindings)
1246- (list* () list (list-extract-rest% bindings))) (move! body);
1279+ (list* () list (list-extract-rest% bindings))) (forward! body);
12471280 () lock-current-environment
12481281 ));
12491282 $defv/e%! $let mods (&bindings .&body) d
1250- eval% (mk-let $lambda ($lqual bindings) (move! body)) d;
1283+ eval% (mk-let $lambda ($lqual bindings) (forward! body)) d;
12511284 $defv/e%! $let% mods (&bindings .&body) d
1252- eval% (mk-let $lambda% ($lqual bindings) (move! body)) d;
1285+ eval% (mk-let $lambda% ($lqual bindings) (forward! body)) d;
12531286 $defv/e%! $let/e mods (&p &bindings .&body) d
1254- eval% (mk-let/e $lambda/e p ($lqual bindings) (move! body)) d;
1287+ eval% (mk-let/e $lambda/e p ($lqual bindings) (forward! body)) d;
12551288 $defv/e%! $let/e% mods (&p &bindings .&body) d
1256- eval% (mk-let/e $lambda/e% p ($lqual bindings) (move! body)) d;
1289+ eval% (mk-let/e $lambda/e% p ($lqual bindings) (forward! body)) d;
12571290 $defv/e%! $let* mods (&bindings .&body) d
1258- eval% (mk-let* $let $let* ($lqual* bindings) (move! body)) d;
1291+ eval% (mk-let* $let $let* ($lqual* bindings) (forward! body)) d;
12591292 $defv/e%! $let*% mods (&bindings .&body) d
1260- eval% (mk-let* $let% $let*% ($lqual* bindings) (move! body)) d;
1293+ eval% (mk-let* $let% $let*% ($lqual* bindings) (forward! body)) d;
12611294 $defv/e%! $letrec mods (&bindings .&body) d
1262- eval% (mk-letrec $let ($lqual bindings) (move! body)) d;
1295+ eval% (mk-letrec $let ($lqual bindings) (forward! body)) d;
12631296 $defv/e%! $letrec% mods (&bindings .&body) d
1264- eval% (mk-letrec $let% ($lqual bindings) (move! body)) d;
1297+ eval% (mk-letrec $let% ($lqual bindings) (forward! body)) d;
12651298 map1 move! (list% $let $let% $let/e $let/e% $let* $let*% $letrec $letrec%)
12661299 )) (() get-current-environment);
12671300 $defw! derive-current-environment (.&envs) d
@@ -1306,7 +1339,7 @@
13061339 # endif
13071340 R"NPL(
13081341 $defv! $as-environment (.&body) d
1309- eval (list $let () (list $sequence (move! body)
1342+ eval (list $let () (list% $sequence (forward! body)
13101343 (list () lock-current-environment))) d;
13111344 $defv! $bindings/p->environment (&parents .&bindings) d $sequence
13121345 ($def! (res bref) list (apply make-environment
@@ -1315,16 +1348,16 @@
13151348 (list* () list (list-extract-rest% bref))) d)
13161349 res;
13171350 $defv! $bindings->environment (.&bindings) d
1318- eval (list* $bindings/p->environment () (move! bindings)) d;
1351+ eval (list* $bindings/p->environment () (forward! bindings)) d;
13191352 $defl! symbols->imports (&symbols)
13201353 list* () list% (map1 ($lambda (&s) list forward! (desigil s))
13211354 (forward! symbols));
13221355 $defv! $provide/let! (&symbols &bindings .&body) d
13231356 eval% (list% $let (forward! bindings) $sequence
1324- (move! body) (list% $set! d (append symbols ((unwrap list%) .))
1357+ (forward! body) (list% $set! d (append symbols ((unwrap list%) .))
13251358 (symbols->imports symbols)) (list () lock-current-environment)) d;
13261359 $defv! $provide! (&symbols .&body) d
1327- eval (list*% $provide/let! (forward! symbols) () (move! body)) d;
1360+ eval (list*% $provide/let! (forward! symbols) () (forward! body)) d;
13281361 $defv! $import! (&e .&symbols) d
13291362 eval% (list $set! d (append symbols ((unwrap list%) .))
13301363 (symbols->imports symbols)) (eval e d);
@@ -1396,9 +1429,9 @@
13961429 context.ShareCurrentSource("<root:core>");
13971430 context.Perform(R"NPL(
13981431 $defw%! map-reverse (&appv .&ls) d
1399- accl (move! ls) nonfoldable? () list-extract-first list-extract-rest%
1432+ accl (forward! ls) nonfoldable? () list-extract-first list-extract-rest%
14001433 ($lambda (&x &xs) cons% (apply appv (forward! x) d) (forward! xs));
1401-$defw! for-each-ltr &ls d $sequence (apply map-reverse ls d) #inert;
1434+$defw! for-each-ltr &ls d $sequence (apply map-reverse (forward! ls) d) #inert;
14021435 )NPL");
14031436 }
14041437
@@ -1471,8 +1504,8 @@
14711504 bool eval_ref = true;
14721505
14731506 public:
1474- // XXX: Keep parameters of 'TermNode' object type, as it is more efficient, at
1475- // least in code generation by x86_64-pc-linux G++ 11.1.
1507+ // XXX: Keep parameters of 'TermNode' object type, as it is more efficient,
1508+ // at least in code generation by x86_64-pc-linux G++ 11.1.
14761509 //! \pre 间接断言:第二参数的标签可表示一等对象的值。
14771510 Promise(ContextNode& ctx, TermNode tm) ynothrow
14781511 : r_env(ctx.WeakenRecord()), tm_obj(std::move(tm)),
@@ -1799,15 +1832,15 @@
17991832 $defl/e%! &memoize mods (&x)
18001833 encapsulate% (list (list% (forward! x) ()) #inert),
18011834 $defv/e%! &$lazy mods (.&body) d
1802- encapsulate% (list (list (move! body) d) eval),
1835+ encapsulate% (list (list (forward! body) d) eval),
18031836 $defv/e%! &$lazy% mods (.&body) d
1804- encapsulate% (list (list (move! body) d) eval%),
1837+ encapsulate% (list (list (forward! body) d) eval%),
18051838 $defv/e%! &$lazy/d mods (&e .&body) d
18061839 encapsulate%
1807- (list (list (move! body) (check-environment (eval e d))) eval),
1840+ (list (list (forward! body) (check-environment (eval e d))) eval),
18081841 $defv/e%! &$lazy/d% mods (&e .&body) d
18091842 encapsulate%
1810- (list (list (move! body) (check-environment (eval e d))) eval%),
1843+ (list (list (forward! body) (check-environment (eval e d))) eval%),
18111844 $defl/e%! &force mods (&x)
18121845 ($lambda% (fwd) $if (promise? x) (do-force x fwd) (fwd x))
18131846 ($if ($lvalue-identifier? x) id move!)
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/source/NPL/Exception.cpp
--- a/YFramework/source/NPL/Exception.cpp Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/source/NPL/Exception.cpp Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Exception.cpp
1212 \ingroup NPL
1313 \brief NPL 异常。
14-\version r4840
14+\version r4842
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 936
1717 \par 创建时间:
1818 2022-01-21 01:59:50 +0800
1919 \par 修改时间:
20- 2022-07-05 04:50 +0800
20+ 2022-07-17 08:35 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -113,8 +113,8 @@
113113 ThrowListTypeErrorForInvalidType(const char* name, const TermNode& term,
114114 bool has_ref, size_t n_skip)
115115 {
116- throw ListTypeError(ystdex::sfmt("Expected a value of type '%s', got a list"
117- " '%s'.", name, TermToStringWithReferenceMark(term, has_ref, n_skip).c_str()));
116+ throw ListTypeError(ystdex::sfmt("Expected a value of type '%s', got '%s'.",
117+ name, TermToStringWithReferenceMark(term, has_ref, n_skip).c_str()));
118118 }
119119 void
120120 ThrowListTypeErrorForInvalidType(const type_info& ti,
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/source/NPL/NPLA1.cpp
--- a/YFramework/source/NPL/NPLA1.cpp Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/source/NPL/NPLA1.cpp Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1.cpp
1212 \ingroup NPL
1313 \brief NPLA1 公共接口。
14-\version r23050
14+\version r23076
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 472
1717 \par 创建时间:
1818 2014-02-02 18:02:47 +0800
1919 \par 修改时间:
20- 2022-07-12 18:03 +0800
20+ 2022-07-24 22:27 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -26,7 +26,7 @@
2626
2727
2828 #include "NPL/YModules.h"
29-#include YFM_NPL_NPLA1Forms // for NPL, EvaluationPasses, lref, ContextHandler,
29+#include YFM_NPL_NPLA1Forms // for EvaluationPasses, lref, ContextHandler,
3030 // RelaySwitched, trivial_swap, type_index, string_view, std::hash,
3131 // ystdex::equal_to, YSLib::unordered_map, YSLib::lock_guard, YSLib::mutex,
3232 // std::ref, ListReductionFailure, ystdex::sfmt, FetchArgumentN, std::next,
@@ -489,6 +489,13 @@
489489 };
490490 //@}
491491
492+//! \since build 950
493+YB_NORETURN void
494+ThrowForInvalidArgumentLists()
495+{
496+ throw ListReductionFailure("List expected in the applicative call.");
497+}
498+
492499
493500 //! \since build 881
494501 class SeparatorPass
@@ -549,7 +556,7 @@
549556 private:
550557 YB_FLATTEN void
551558 Transform(TermNode& term
552-# if defined(NPL_Impl_NPLA1_Enable_ThunkedSeparatorPass) \
559+# if NPL_Impl_NPLA1_Enable_ThunkedSeparatorPass \
553560 && NPL_Impl_NPLA1_Enable_ThunkedThreshold != 0
554561 , size_t n = 0
555562 # endif
@@ -618,6 +625,8 @@
618625 operator()(char sigil, bool ref_temp, TermTags o_tags, TermNode& o,
619626 _fCopy cp, _fMove mv) const
620627 {
628+ // NOTE: For elements binding here, %TermTags::Unique in %o_tags is
629+ // irrelavant.
621630 // NOTE: This shall be %true if the operand is stored in a term tree to
622631 // be reduced (and eventually cleanup). See also
623632 // %GParameterMatcher::Match.
@@ -639,6 +648,10 @@
639648 {
640649 if(sigil != char())
641650 {
651+ // NOTE: If %ref_temp is set, xvalues are treated as
652+ // prvalues in terms of the tags of the bound object. This
653+ // only occurs on sigil '&' as per the object language
654+ // rules.
642655 const auto ref_tags(PropagateTo(ref_temp
643656 ? BindReferenceTags(*p) : p->GetTags(), o_tags));
644657
@@ -1788,12 +1801,18 @@
17881801 }
17891802
17901803 void
1791-FormContextHandler::CheckArguments(size_t n, TermNode& term)
1804+FormContextHandler::CheckArguments(const TermNode& term)
17921805 {
1793- YAssert(!(IsList(term) && HasStickySubterm(term)),
1794- "Invalid representation found.");
1806+ AssertCombiningTerm(term);
1807+ if(YB_UNLIKELY(!IsList(term)))
1808+ ThrowForInvalidArgumentLists();
1809+}
1810+void
1811+FormContextHandler::CheckArguments(size_t n, const TermNode& term)
1812+{
1813+ AssertCombiningTerm(term);
17951814 if(YB_UNLIKELY(n != 0 && !IsList(term)))
1796- throw ListReductionFailure("List expected in the applicative call.");
1815+ ThrowForInvalidArgumentLists();
17971816 }
17981817
17991818 bool
@@ -2035,7 +2054,7 @@
20352054 ReductionStatus
20362055 ReduceCombinedBranch(TermNode& term, ContextNode& ctx)
20372056 {
2038- YAssert(IsCombiningTerm(term), "Invalid term found for combined term.");
2057+ AssertCombiningTerm(term);
20392058
20402059 auto& fm(AccessFirstSubterm(term));
20412060 const auto p_ref_fm(TryAccessLeafAtom<const TermReference>(fm));
@@ -2315,7 +2334,7 @@
23152334 #if NPL_Impl_NPLA1_Enable_TCO
23162335 yunused(EnsureTCOAction(ctx, term));
23172336 #else
2318- yunused(ctx);
2337+ yunused(ctx), yunused(term);
23192338 #endif
23202339 }
23212340
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/source/NPL/NPLA1Forms.cpp
--- a/YFramework/source/NPL/NPLA1Forms.cpp Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/source/NPL/NPLA1Forms.cpp Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Forms.cpp
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r27404
14+\version r27432
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2014-02-15 11:19:51 +0800
1919 \par 修改时间:
20- 2022-07-05 05:49 +0800
20+ 2022-07-25 01:51 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -26,14 +26,15 @@
2626
2727
2828 #include "NPL/YModules.h"
29-#include YFM_NPL_NPLA1Forms // for YSLib, std::next, ReduceOnceLifted,
30-// ResolvedTermReferencePtr, NPL::IsMovable, TryAccessReferencedTerm,
31-// ystdex::value_or, ThrowInsufficientTermsError, NPL::Deref,
32-// A1::NameTypedReducerHandler, ReduceReturnUnspecified, RemoveHead, IsBranch,
33-// AccessFirstSubterm, ReduceSubsequent, ReduceCombinedBranch,
34-// std::placeholders, std::ref, std::bind, ystdex::as_const, IsLeaf,
35-// ValueObject, ystdex::ref_eq, RelaySwitched, trivial_swap, shared_ptr,
36-// ContextHandler, YSLib::unordered_map, string, Environment, lref, TokenValue,
29+#include YFM_NPL_NPLA1Forms // for ResolvedTermReferencePtr, NPL::IsMovable,
30+// ystdex::value_or, TryAccessReferencedTerm, IsBranch,
31+// ThrowInsufficientTermsError, NPL::Deref, ReduceSubsequent,
32+// A1::NameTypedReducerHandler, ReduceOnceLifted, std::next,
33+// ReduceReturnUnspecified, CheckVariadicArity, RemoveHead, AccessFirstSubterm,
34+// ReduceOrdered, std::bind, std::ref, std::placeholders, std::declval,
35+// RetainList, RetainN, ystdex::as_const, ValueObject, ReferenceTerm, IsLeaf,
36+// ystdex::ref_eq, RelaySwitched, trivial_swap, shared_ptr, ContextHandler,
37+// YSLib::unordered_map, string, Environment, lref, TokenValue,
3738 // any_ops::use_holder, in_place_type, YSLib::HolderFromPointer,
3839 // YSLib::allocate_shared, InvalidReference, BindParameter, MoveFirstSubterm,
3940 // ResolveEnvironment, ShareMoveTerm, BindParameterWellFormed, ystdex::sfmt,
@@ -268,7 +269,7 @@
268269 {
269270 EqTermRet(term,
270271 [f] YB_LAMBDA_ANNOTATE((const TermNode& x, const TermNode& y), , pure){
271- return IsLeaf(x) && IsLeaf(y) ? f(x.Value, y.Value)
272+ return IsAtom(x) && IsAtom(y) ? f(x.Value, y.Value)
272273 : ystdex::ref_eq<>()(x, y);
273274 }, static_cast<const TermNode&(&)(const TermNode&)>(ReferenceTerm));
274275 }
@@ -637,6 +638,7 @@
637638 ResolveTerm([&](TermNode& nd, ResolvedTermReferencePtr p_ref){
638639 LiftOtherOrCopy(term, nd, NPL::IsMovable(p_ref));
639640 }, NPL::Deref(i));
641+ // XXX: This implies %EnsureValueTags.
640642 ClearCombiningTags(term);
641643 // NOTE: On %NPL_Impl_NPLA1_Enable_TCO, this assumes %term is same to the
642644 // current term in %TCOAction, which is initialized by %CombinerReturnThunk
@@ -666,7 +668,7 @@
666668
667669 SContext::Analyze(std::allocator_arg, ctx.get_allocator(), sess,
668670 sess.Process(NPL::ResolveRegular<const string>(expr)))
669- .SwapContainer(expr);
671+ .SwapContent(expr);
670672 return EvalImplUnchecked(term, ctx, no_lift);
671673 }
672674
@@ -995,7 +997,6 @@
995997
996998
997999 //! \since build 947
998-//@{
9991000 template<typename... _tParams>
10001001 void
10011002 ConsSplice(TermNode tm, TermNode& nd, _tParams&&... args)
@@ -1012,6 +1013,7 @@
10121013 // XXX: Returning term instead of the container allows to pass improper lists,
10131014 // also perserves the allocator on
10141015 // copy.
1016+//! \since build 947
10151017 YB_ATTR_nodiscard TermNode
10161018 ConsItem(TermNode& y)
10171019 {
@@ -1031,7 +1033,6 @@
10311033 ThrowListTypeErrorForNonList(nd_y, p_ref_y);
10321034 }, y);
10331035 }
1034-//@}
10351036
10361037 //! \since build 912
10371038 ReductionStatus
@@ -1621,6 +1622,8 @@
16211622 if(IsList(nd))
16221623 return VauHandler::MakeParent(MakeEnvironmentParent(
16231624 nd.begin(), nd.end(), nd.get_allocator(), !NPL::IsMovable(p_ref)));
1625+ // XXX: Currently all supported environment representations of a single
1626+ // object are in the leaf.
16241627 if(IsLeaf(nd))
16251628 return VauHandler::MakeParentSingle(nd.get_allocator(),
16261629 ResolveEnvironment(nd.Value, NPL::IsMovable(p_ref)));
@@ -1725,6 +1728,11 @@
17251728 auto i(term.begin());
17261729 auto& tm(NPL::Deref(++i));
17271730
1731+ // XXX: As %EvalImplUnchecked, with in-place term modification.
1732+ ResolveTerm([&](TermNode& nd, ResolvedTermReferencePtr p_ref){
1733+ LiftTermOrCopy(tm, nd, NPL::IsMovable(p_ref));
1734+ }, tm);
1735+ EnsureValueTags(tm.Tags);
17281736 return ReduceSubsequent(tm, ctx,
17291737 NameTypedReducerHandler([&, i, wrap, no_lift]{
17301738 return ReduceCreateFunction(term, [&]{
@@ -4768,7 +4776,12 @@
47684776 }
47694777 #endif
47704778 // NOTE: Now unwind the reducer sequence upon to the delimiter. This
4771- // switches the control to the position to the captured one.
4779+ // switches the control to the position to the captured one. Unwinding
4780+ // frames would need %NPL_Impl_NPLA1_Enable_Thunked, otherwise it would
4781+ // leat to undefined behavior when the removed frames are accessed
4782+ // later, because only thunked implementations guarantees the future
4783+ // accesses are also removed, rather than remaining in the activation
4784+ // records of the host language.
47724785 while(cur.begin() != i_top)
47734786 cur.pop_front();
47744787 #if NPL_Impl_NPLA1_Enable_TCO
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/source/NPL/NPLA1Internals.cpp
--- a/YFramework/source/NPL/NPLA1Internals.cpp Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/source/NPL/NPLA1Internals.cpp Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Internals.cpp
1212 \ingroup NPL
1313 \brief NPLA1 内部接口。
14-\version r20646
14+\version r20651
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 473
1717 \par 创建时间:
1818 2020-02-15 13:20:08 +0800
1919 \par 修改时间:
20- 2022-06-17 00:49 +0800
20+ 2022-07-12 21:28 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 非公开模块名称:
@@ -267,8 +267,8 @@
267267 term.Tags = TermTags::Unqualified;
268268 // XXX: Not using %ystdex::prefix_eraser because there is known 1 subterm to
269269 // be inserted.
270- con.insert(i, NPL::AsTermNodeTagged(con.get_allocator(), TermTags::Sticky,
271- std::move(p_sub)));
270+ con.insert(i,
271+ A1::MakeSubobjectReferent(con.get_allocator(), std::move(p_sub)));
272272 con.erase(i, con.end());
273273 return ReductionStatus::Retained;
274274 }
@@ -284,9 +284,9 @@
284284
285285 // XXX: Allocators are not used on %FormContextHandler for performance in
286286 // most cases.
287- return ReduceAsSubobjectReference(term, YSLib::allocate_shared<TermNode>(a,
288- NPL::AsTermNode(a, ContextHandler(std::allocator_arg, a,
289- FormContextHandler(RefContextHandler(h, r_env), n)))), r_env);
287+ return ReduceAsSubobjectReference(term,
288+ A1::AllocateSharedTermValue(a, ContextHandler(std::allocator_arg, a,
289+ FormContextHandler(RefContextHandler(h, r_env), n))), r_env);
290290 }
291291
292292 } // inline namespace Internals;
diff -r e1756f2eba1f -r 4d7fdf52b6d5 YFramework/source/NPL/NPLA1Internals.h
--- a/YFramework/source/NPL/NPLA1Internals.h Tue Jul 12 18:45:26 2022 +0800
+++ b/YFramework/source/NPL/NPLA1Internals.h Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Internals.h
1212 \ingroup NPL
1313 \brief NPLA1 内部接口。
14-\version r22439
14+\version r22469
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2020-02-15 13:20:08 +0800
1919 \par 修改时间:
20- 2022-07-12 12:50 +0800
20+ 2022-07-23 09:34 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 非公开模块名称:
@@ -29,13 +29,14 @@
2929 #define NPL_INC_NPLA1Internals_h_ 1
3030
3131 #include "YModules.h"
32-#include YFM_NPL_NPLA1 // for shared_ptr, ContextNode, NPL::Deref, NPLException,
33-// TermNode, ReductionStatus, Reducer, YSLib::map, lref, Environment, set,
34-// IsTyped, EnvironmentList, EnvironmentReference, pair, YSLib::forward_list,
35-// size_t, tuple, std::declval, EnvironmentGuard, MoveKeptGuard,
36-// A1::NameTypedContextHandler, TermReference, ThrowTypeErrorForInvalidType,
37-// TryAccessLeafAtom, type_id, TermToNamePtr, IsIgnore, ystdex::exclude_self_t,
38-// ParameterMismatch;
32+#include YFM_NPL_NPLA1 // for shared_ptr, ContextNode, YSLib::allocate_shared,
33+// NPL::Deref, NPLException, TermNode, ReductionStatus, Reducer, YSLib::map,
34+// lref, Environment, set, IsTyped, EnvironmentList, EnvironmentReference,
35+// pair, YSLib::forward_list, size_t, tuple, std::declval, EnvironmentGuard,
36+// MoveKeptGuard, A1::NameTypedContextHandler, TermReference, TermTags,
37+// ThrowTypeErrorForInvalidType, TryAccessLeafAtom, type_id, TermToNamePtr,
38+// IsIgnore, ParameterMismatch, IsPair, IsEmpty, IsList, NPL::AsTermNode,
39+// NPL::AsTermNodeTagged;
3940 #include <ystdex/compose.hpp> // for ystdex::get_less;
4041 #include <ystdex/scope_guard.hpp> // for ystdex::unique_guard;
4142 #include <ystdex/optional.h> // for ystdex::optional;
@@ -436,7 +437,7 @@
436437 \since build 819
437438 */
438439 TCOAction(ContextNode& ctx, TermNode& term, bool lift)
439- : req_lift_result(lift ? 1 : 0),record_list(ctx.get_allocator()),
440+ : req_lift_result(lift ? 1 : 0), record_list(ctx.get_allocator()),
440441 env_guard(ctx), term_guard(ystdex::unique_guard(GuardFunction{term})),
441442 OperatorName([&]() ynothrow{
442443 // NOTE: Rather than only the target %TokenValue value, the whole
@@ -447,9 +448,9 @@
447448 // XXX: After the move, the value is unspecified. This should be no
448449 // longer used, so it is irrelavant.
449450 }())
450- // XXX: Do not call %AssertValueTags on %term, as it is usually a
451- // combinitation instead of the representation of some object language
452- // value.
451+ // XXX: Do not call %AssertValueTags on %term, as it can be (and is
452+ // usually) a combiniation instead of the representation of some
453+ // object language value.
453454 {}
454455 // XXX: Not used, but provided for well-formness.
455456 //! \since build 819
@@ -1478,6 +1479,28 @@
14781479 };
14791480
14801481
1482+//! \since build 950
1483+//@{
1484+template<class _tAlloc, typename... _tParams>
1485+YB_ATTR_nodiscard YB_ATTR_always_inline inline shared_ptr<TermNode>
1486+AllocateSharedTerm(const _tAlloc& a, _tParams&&... args)
1487+{
1488+ return YSLib::allocate_shared<TermNode>(a, yforward(args)...);
1489+}
1490+
1491+template<class _tAlloc, typename... _tParams>
1492+YB_ATTR_nodiscard YB_ATTR_always_inline inline shared_ptr<TermNode>
1493+AllocateSharedTermValue(const _tAlloc& a, _tParams&&... args)
1494+{
1495+ return A1::AllocateSharedTerm(a, NPL::AsTermNode(a, yforward(args)...));
1496+}
1497+
1498+YB_ATTR_nodiscard inline PDefH(TermNode, MakeSubobjectReferent,
1499+ TermNode::allocator_type a, shared_ptr<TermNode> p_sub)
1500+ ImplRet(NPL::AsTermNodeTagged(a, TermTags::Sticky, std::move(p_sub)))
1501+//@}
1502+
1503+
14811504 //! \since build 913
14821505 ReductionStatus
14831506 ReduceAsSubobjectReference(TermNode&, shared_ptr<TermNode>,
diff -r e1756f2eba1f -r 4d7fdf52b6d5 doc/ChangeLog.V0.8.txt
--- a/doc/ChangeLog.V0.8.txt Tue Jul 12 18:45:26 2022 +0800
+++ b/doc/ChangeLog.V0.8.txt Mon Jul 25 05:22:59 2022 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2017-2021 FrankHB.
2+ © 2017-2022 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file ChangeLog.V0.8.txt
1212 \ingroup Documentation
1313 \brief 版本更新历史记录 - V0.8 。
14-\version r21186
14+\version r21399
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 800
1717 \par 创建时间:
1818 2017-08-10 01:58:36 +0800
1919 \par 修改时间:
20- 2021-02-23 23:24 +0800
20+ 2022-07-25 04:47 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -224,10 +224,10 @@
224224 (
225225 / @ "function %LoadGroundContext" $=
226226 (
227- + "native derivation" @ "applicative %foldr1 and \
227+ + "native implementation" @ "applicative %foldr1 and \
228228 enabled by default"
229229 ^ $dep_from ("%FoldR1" @ %NPLA1Forms),
230- / $lib "added native derivation enabled by default"
230+ / $lib "added native implementation enabled by default"
231231 @ "applicative %map1"
232232 ^ $dep_from ("%Map1" @ %NPLA1Forms),
233233 / DLI "alternative derivation" @ "applicative 'not?'"
@@ -436,7 +436,7 @@
436436 * "duplicated evaluation for matched subexpression not at the \
437437 last position" @ "derivation" @ "operative '$or?'"
438438 $since b860,
439- / $lib "added native derivation enabled by default"
439+ / $lib "added native implementation enabled by default"
440440 @ "applicative %accl" ^ $dep_from ("%AccL" @ %NPLA1Forms),
441441 (
442442 / "applicative 'unfoldable?'" -> "'nonfoldable?' allowing an \
@@ -451,7 +451,7 @@
451451 (
452452 * $comp "operative used as an argument of %accl call"
453453 @ "applicative 'unfoldable?'" $since b791;
454- / $lib "added native derivation enabled by default"
454+ / $lib "added native implementation enabled by default"
455455 @ "applicative %accr" ^ $dep_from ("%AccR" @ %NPLA1Forms)
456456 ),
457457 * "missing unwrapping on applicative arguments" @ "derivation"
@@ -924,7 +924,7 @@
924924 (
925925 / $dev $lib %Lexical $=
926926 (
927- / DLI "inlined function %Deliteralize",
927+ / DLI $src "inlined function %Deliteralize",
928928 + "copy constructor" @ "class %SourceLocation"
929929 // Also to eliminate Clang++ warning: [-Wdeprecated].
930930 ),
@@ -1035,7 +1035,7 @@
10351035 ),
10361036 * "wrong 'ynothrow'"
10371037 @ "function template %SwitchToFreshEnvironment" $since b838,
1038- / DLI "inlined constructor %EnvironmentReference",
1038+ / DLI $src "inlined constructor %EnvironmentReference",
10391039 (
10401040 / DLDI "function %PrintNode" !^ "%TraverseNodeChildAndPrint";
10411041 - $revert(b851) "function template %TraverseNodeChildAndPrint"
@@ -1055,9 +1055,8 @@
10551055 ),
10561056 / %YReader $=
10571057 (
1058- * "failed to conversion of terms with strings" @ %ReaderSetting $since b833
1059- $dep_from %YSLib.ValueNode
1060- $=
1058+ * "failed to conversion of terms with strings" @ %ReaderSetting
1059+ $since b833 $dep_from %YSLib.ValueNode $=
10611060 (
10621061 * $comp "failed conversion of strings",
10631062 * "failed conversion of %Color nodes"
@@ -1369,7 +1368,7 @@
13691368 $effective @ %(NPLA1Internals, NPLA1Forms),
13701369 / "namespace %Forms" @ %NPLA1Forms $=
13711370 (
1372- * "wrong order of pseudo keywords" @ "function 'Throw*'"
1371+ * "wrong order of pseudo keywords" @ "functions 'Throw*'"
13731372 $orig (@ %NPLA1 $since b859)
13741373 / $= (/ 'YF_API YB_NORETURN' -> 'YB_NORETURN YF_API'),
13751374 // To avoid Clang++ error.
@@ -1441,7 +1440,7 @@
14411440 ),
14421441 / %NPLA1 $=
14431442 (
1444- / DLDI "supported reduce names by named type"
1443+ / DLDI "supported reducer names by named type"
14451444 ~ "lambda-expression" @ 'NPL_Impl_NPLA1_Enable_TCO'
14461445 @ "function %ReduceOrdered",
14471446 / @ "function %QueryContinuationName" $=
@@ -1550,7 +1549,7 @@
15501549 + DLI "stashed empty action sequence"
15511550 ^ 'YSLib::forward_list';
15521551 // This improves perforamnce significantly.
1553- + $foced DLDI "swapped stashed empty action sequence"
1552+ + $forced DLDI "swapped stashed empty action sequence"
15541553 @ "friend function %swap",
15551554 + "function %shrink_to_fit"
15561555 ),
@@ -1573,7 +1572,7 @@
15731572 $dep_from "avoiding directly composed actions";
15741573 - "function template %ComposeSwitchedUnchecked";
15751574 - "function template %ComposeActions";
1576- * $re_add(b865) $comp "missing qualified 'NPL::'" @ ("call of \
1575+ * $comp $re_add(b865) "missing qualified 'NPL::'" @ ("call to \
15771576 %ComposeSwitchedUnchecked" @ "function template \
15781577 %ComposeSwitched" @ $since b856, ("call of %ComposeActions"
15791578 @ "function template %RelayNext", "call of %RelayNext"
@@ -1675,7 +1674,7 @@
16751674 - 'explicit' @ "constructor with allocator parameter and \
16761675 in-place value tag",
16771676 // To be consistent to %any.
1678- + $dev "static assert to ensure reference to the holder type \
1677+ + $dev "static assertion to ensure reference to the holder type \
16791678 convertible to 'IValueHolder&'"
16801679 @ "constructor template with holder tag",
16811680 + "constuctor template with allocator parameter and in-place \
@@ -2365,7 +2364,7 @@
23652364 %InvalidSyntax for cases of <eformal> error"
23662365 @ "functions 'Vau*'",
23672366 / "thrown exception of %InvalidSyntax derived with nested \
2368- %InvalidSyntax for cases of \<environment> error"
2367+ %InvalidSyntax for cases of <environment> error"
23692368 @ "functions %(VauWithEnvironment, LambdaWithEnvironment)"
23702369 $dep_from %NPL.Documentation
23712370 )
@@ -2803,11 +2802,12 @@
28032802 ("%LexicalAnalyzer::(PrefixHandler, Unescaper)"
28042803 @ %Lexical, "in-buffer prefix") $=
28052804 (
2806- / $impl ^ $dep_from "%UnescapeContext::VerifyBufferLength",
2805+ / $impl
2806+ ^ $dep_from "%UnescapeContext::VerifyBufferLength",
28072807 / $impl !^ "%UnescapeContext::GetSequence"
28082808 $dep_to "avoiding in-context sequence reference",
2809- + $forced "%char as 2nd parameter to split the buffer and \
2810- the current character",
2809+ + $forced "%char as 2nd parameter to split the buffer \
2810+ and the current character",
28112811 ),
28122812 + DLI "line concatenation" @ "unescaping"
28132813 $dep_to "unescaping concatenation support",
@@ -3016,16 +3016,15 @@
30163016 @ "%SHBuild-YSLib-common.txt")),
30173017 / "supported system prefix directory name instead of '/usr' \
30183018 with overridable variable %SHBuild_SystemPrefix"
3019- @ ("%SHBuild-BuildApp.sh"
3020- ^ "functions %(SHBuild_Platform_Detect, \
3019+ @ ("%SHBuild-BuildApp.sh" ^ "%(SHBuild_Platform_Detect, \
30213020 SHBuild_CheckHostPlatform)" @ "%SHBuild-common.sh",
30223021 "%SHBuild-YSLib-build.txt" ^ ("%SHBuild_GetSystemPrefix"
30233022 @ "%SHBuild-YSLib-common.txt"))
30243023 ),
30253024 / @ "%SHBuild-YSLib-build.txt" $=
30263025 (
3027- / "changed YFramework host library directory without postfix of \
3028- '-' and the name of host architecture"
3026+ / "changed YFramework host library directory without postfix \
3027+ of '-' and the name of host architecture"
30293028 $dep_to "host library directory",
30303029 // This changes effectively for %MinGW32 (from 'lib-i686' \
30313030 to 'lib') since previously this is the only formally \
@@ -3068,7 +3067,7 @@
30683067 '$SHBuild_Bin/../lib/'"
30693068 $dep_from "%SHBuild_SystemPrefix";
30703069 * "missing library prefix '-L' option for static library \
3071- building" $since b,
3070+ building" $since b556,
30723071 + "support of dynamic libfreetype detection with \
30733072 'pkg-config' if %libfreetype.a is missing in the \
30743073 sysroot 'lib' directory" @ !"platform %Win32"
@@ -3218,11 +3217,11 @@
32183217 detection is to including Clang++ specifically. The only valid \
32193218 case for %YB_IMPL_GUNCremained is the definition of %YB_ATTR.
32203219 / "simplified" @ "macro %YB_ATTR_gnu_printf" @ %YBase.YDefinition
3221- * "missing excluding Clang++" $effective
3220+ * "missing exclsion of Clang++" $effective
32223221 @ %(YBase.YStandardEx.CAssert $since b739,
32233222 YFramework.YSLib.Core.YEvent $since b792),
32243223 ),
3225- * $re_add(b866) $comp "build failure" @ "platform %Android" $since b850
3224+ * $comp $re_add(b866) "build failure" @ "platform %Android" $since b850
32263225 $dep_from %YFramework.YSLib.Core.YMessage
32273226 // This causes armv7a-linux-androideabi21-clang++ fails to compile.
32283227 ),
@@ -3318,7 +3317,7 @@
33183317 %Allocator $dep_to "seperated allocator API header",
33193318 // The order of declarations is now also consistent to WG21 \
33203319 N4830 [memory.syn].
3321- / DLDI "header inclusion %Tuple" -> "%Apply"
3320+ / DLDI "inclusion %Tuple" -> "%Apply"
33223321 ),
33233322 + DLDI 'YB_ATTR_nodiscard' @ "function template \
33243323 %uses_allocator_construction_args implementations" @ %Allocator
@@ -3326,9 +3325,8 @@
33263325 // G++ 7.1 warning: [-Wsuggest-attribute=const] is wrong here \
33273326 and %YB_STATELESS would cause crash.
33283327 (
3329- / DLDI ("simplified header inclusion %Memory" -> "%Allocator")
3330- @ %(Tree, String, List, Cache)
3331- $dep_from "seperated allocator API header";
3328+ / DLDI ("simplified inclusion %Memory" -> "%Allocator") @ %(Tree,
3329+ String, List, Cache) $dep_from "seperated allocator API header";
33323330 / DLDI "header inclusion %IteratorOperation" @ %List
33333331 )
33343332 ),
@@ -3476,14 +3474,16 @@
34763474 "function %Contains" @ "class template %GHandlerRegisterBase"
34773475 @ %Core.YFunc) @ %YSLib),
34783476 // Also to eliminate G++ 7.1 warning: [-Wsuggest-attribute=pure].
3479- + $dev $lib 'YB_ATTR_nodiscard' @ ("member function \
3477+ + $dev $lib 'YB_ATTR_nodiscard' @ ("functions or function templates \
3478+ with names %(VerifyEncoding, CheckBOM, DetectBOM)"
3479+ @ %Service.TextFile, ("member function \
34803480 %GUIApplication::GetEnvironmentHostRef" @ %Helper.GUIApplication
34813481 ("member functions %(GetFullViewHeight, GetItemHeight, \
34823482 GetItemHeightCore, GetLastLabelIndexClipped, GetUnitLocation, \
34833483 GetViewPosition, CheckPoint)" @ "class %AMUnitList"
34843484 @ %Viewer, "member function %AMUnitControlList::MakeIterator"
34853485 @ %ListControl, "member functions \
3486- %TreeList::(GetNodePath, GetNodeRef)" @ %TreeView) @ %YSLib.UI),
3486+ %TreeList::(GetNodePath, GetNodeRef)" @ %TreeView) @ %UI) @ %YSLib,
34873487 + $dev $lib 'yimpl(YB_STATELESS)' @ "member function \
34883488 %GUIApplication::GetGUIHostRef" @ %Helper.GUIApplication',
34893489 // To eliminate G++ 9.2 warning: [-Wsuggest-attribute=const].
@@ -3536,7 +3536,7 @@
35363536 / "optimized emplacement operations" @ "class %ValueObject"
35373537 @ %YObject ^ 'YB_ATTR(always_inline)'
35383538 ),
3539- * "missing %YFramework.YSLib.UI.YPanel file renaming"
3539+ * $dev "missing %YFramework.YSLib.UI.YPanel file renaming"
35403540 @ "Microsoft VC++ project files" $since b672
35413541 $= (/ "%ypanel.cpp" => "%YPanel.cpp")
35423542 ),
@@ -3795,7 +3795,7 @@
37953795 (
37963796 / "optimized move %operator=" @ "class template specializations \
37973797 %one_shot" ^ "%ystdex::swap_dependent"
3798- ~ "%ystdex::move_and_swap" @ %Functional,
3798+ ~ ("%ystdex::move_and_swap" @ %Functional),
37993799 / %Swap $=
38003800 (
38013801 / "class template %move_and_swap" -> "create_and_swap"
@@ -3898,15 +3898,10 @@
38983898 // This also avoids redundant copy.
38993899 )
39003900 ),
3901- / %UI $=
3902- (
3903- - $lib "all explicit defaulted move constructor"
3904- @ "widget classes as subclass of %Widget" @ %UI
3905- // To eliminate Clang++ 8 warning: \
3906- [-Wdefaulted-function-deleted].
3907- / "header %ypanel.h" => "%YPanel.h",
3908- / "header %form.h" => "%Form.h"
3909- ),
3901+ - $lib "all explicit defaulted move constructor"
3902+ @ "widget classes as subclass of %Widget" @ %UI,
3903+ // To eliminate Clang++ 8 warning: \
3904+ [-Wdefaulted-function-deleted].
39103905 / @ "class %ImageMetadataFindData" @ %Adaptor.Image $=
39113906 (
39123907 / "base class %noncopyable" -> "move constructor",
@@ -4016,7 +4011,7 @@
40164011 @ 'YB_IMPL_CLANGPP'
40174012 // To eliminate Clang++ warning: [-Wunused-function].
40184013 ),
4019- * $dev "missing excluding Clang++" @ "G++ workaround"
4014+ * $dev "missing exclusion of Clang++" @ "G++ workaround"
40204015 @ %Lexical $since b858
40214016 // Also to eliminate Clang++ warning: [-Wunknown-attributes].
40224017 ),
@@ -4099,7 +4094,10 @@
40994094 @ "%(SHBuild-YSLib-common.txt, SHBuild-common-options.sh)"
41004095 // See $2020-01 @ %Documentation::Workflow.
41014096 )
4102- )
4097+ ),
4098+ / $dev $repo $re_add(b826) "all edited file with module name not the same \
4099+ as base filename" ^ 'hg mv' $effective @ %YFramework.YSLib.UI.(
4100+ "%ypanel.h" => "%YPanel.h", "%form.h" => "%Form.h")
41034101 ),
41044102
41054103 b878
@@ -4202,8 +4200,8 @@
42024200 / "redirected calls"
42034201 ^ $dep_from "%ContextState::ReduceOnce",
42044202 (
4205- * "missing call of %ContextState::SetNextTermRef \
4206- from 2nd passes" $since b842,
4203+ * "missing the call to %ContextState::SetNextTermRef from \
4204+ 2nd passes" $since b842,
42074205 / $revert_ex(b842) DLI "avoided call of \
42084206 %ContextState::SetNextTermRef for empty passes sequence"
42094207 // This would cause wront term in the call of \
@@ -4287,7 +4285,7 @@
42874285 + "explicit rules to allowing different order of typechecking of \
42884286 NPLA1 operations" @ %Documentation.NPLA1,
42894287 / "merged files with glob pattern 'Workflow.*.txt'" -> %Workflow;
4290- / $foced DLD "cross references" $dep_to %(YCLib, Dependencies,
4288+ / $forced DLD "cross references" $dep_to %(YCLib, Dependencies,
42914289 ChangeLog.(PreAlpha4, PreAlpha5, 'V0.6', 'V0.7', 'V0.8'))
42924290 ),
42934291 / $forced DLD "source comments with %Documentation.Workflow" $dep_from \
@@ -4399,7 +4397,7 @@
43994397 / @ "function %LoadGroundContext" @ %Dependency $=
44004398 (
44014399 * $comp "behaviors on exception disagreed in multiple typechecking \
4402- failure between the native implementation and alternatmive \
4400+ failure between the native implementation and the alternative \
44034401 derivation" @ "applicative 'forward-list-first'" $since b875
44044402 $dep_from %Documentation.NPL
44054403 ),
@@ -4563,7 +4561,7 @@
45634561 // The divergence of counts should not be assumed normal \
45644562 since %EnvironmentReference contains the anchor pointer.
45654563 ),
4566- * $re_add(b869) "missing support irregular reprenstation for \
4564+ * $re_add(b869) "missing support of irregular reprensentation for \
45674565 reference results"
45684566 $dep_from ("function %ResolveIdentifier" @ %NPLA)
45694567 // An object of irregular representation could be sliced here.
@@ -4572,7 +4570,8 @@
45724570 (
45734571 / $revert_ex(b875) "simplified alternative derivation"
45744572 @ "applicative %first",
4575- / DLDI "simplified native derivation" @ "applications %(id, idv)"
4573+ / DLDI "simplified native implementation"
4574+ @ "applications %(id, idv)"
45764575 ^ $dep_from ("%LiftOther" @ %NPLA) ~ "%TermNode::MoveContent",
45774576 / DLDI "simplified alternative derivation"
45784577 @ "operative '$sequence'",
@@ -4612,8 +4611,9 @@
46124611 ),
46134612 * "wrong 'forward! called on applicative parameter"
46144613 @ "applicative 'map-reverse'" $since b875,
4615- * $re_add(b869) $forced "missing support irregular reprenstation \
4616- for reference results" @ "applicative '$resolve-identifier'"
4614+ * $re_add(b869) $forced "missing support of irregular \
4615+ reprensentation for reference results"
4616+ @ "applicative '$resolve-identifier'"
46174617 $since b858 $dep_from ("function %ResolveIdentifier" @ %NPLA),
46184618 // Same to %A1::EvaluateIdentifier.
46194619 * "values set not respective to reference" @ "alternative \
@@ -4660,11 +4660,11 @@
46604660 ),
46614661 / "namespace %Forms" @ %NPLA1 $=
46624662 (
4663- / "supported options tags of %TermTags::Temporary"
4663+ / "supported operand tag %TermTags::Temporary"
46644664 @ "function %MatchParameter" $=
46654665 (
4666- / DLDI "exlucded %TermTags::Temporary"
4667- @ "creatd references bound with sigil '%'"
4666+ / $revert_ex(b859) "exlucded %TermTags::Temporary" @ "tags"
4667+ @ "created collapsed references bound with sigil '%'"
46684668 $dep_to "binding temporary option tags";
46694669 / "supported binding references to xvalues with sigil '@'",
46704670 / "bound xvalues as references instead of moved temporary \
@@ -4672,18 +4672,28 @@
46724672 // This is needed in partially binding elements of a \
46734673 list and the elements in the list can be further \
46744674 bound as subterms again.
4675+ / $revert_ex(b859) "bound additional %TermTags::Temporary"
4676+ @ "binding xvalue operands with sigil '&'"
4677+ $dep_to "unified xvalues binding"
4678+ // This effectively makes a bound reference has \
4679+ %TermTags::Temporary from %TermTags::Unique in the \
4680+ operand. Adding %TermTags::Temporary is a backup \
4681+ option based on the change of b859. Now a plain \
4682+ variable access (instead of a call to \
4683+ '$resolved-identifier') is sufficient to forward \
4684+ an xvalue argument not as a list element in the \
4685+ calls to 'forward!' because the existence of \
4686+ %TermTags::Unique is preserved in references as \
4687+ %TermTags::Temporary from the evaluation of \
4688+ resolved identifiers.
46754689 ),
46764690 / "function %BindParameter" $=
46774691 (
4678- / $forced DLDI $dep_from
4679- "binding temporary option tags",
4680- / "bound additional %TermTags::Temporary"
4681- @ "binding xvalue operands with sigil '&'"
4682- $dep_to "unified xvalues binding"
4683- // Like C++, prvalue and xvalues are both bound to \
4684- deduced argument. Now '$resolved-identifier' is \
4685- not needed for 'forward!' for an xvalue not in as \
4686- a list element.
4692+ / "prevented inherited %TermTags::Temporary propagated to \
4693+ subterms";
4694+ / $forced DLDI "initial top-level operand tag"
4695+ -> "%TermTags::Temporary" ~ "%TermTag::Unique"
4696+ $dep_from "binding temporary option tags"
46874697 ),
46884698 (
46894699 / DLDI "function %Apply";
@@ -4692,9 +4702,9 @@
46924702 / "function %First" $=
46934703 (
46944704 / "supported unified forwarding",
4695- * "moved or subterm of nonmodifying lists" $since b869
4696- ^ $dep_from ("%LiftTermOrCopyUnchecked" @ %NPLA)
4697- ~ "%LiftTermOrCopy"
4705+ * "possibly moved subobjects of nonmodifiable lists"
4706+ $since b869 ^ $dep_from ("%LiftTermOrCopyUnchecked"
4707+ @ %NPLA) ~ "%TermNode::MoveContent"
46984708 ),
46994709 / DLI ("functions %(FirstVal, Eval, EvalRef, EvalString, \
47004710 EvalStringRef)", "%operator()" @ "vau handler") ^ $dep_from
@@ -4712,7 +4722,8 @@
47124722 ("%ForwardListFirst" @ %NPLA1),
47134723 / "supported unified forwarding" @ "applicative %first" $=
47144724 (
4715- / $comp "native derivation" $dep_from ("%First" @ %NPLA1),
4725+ / $comp "native implementation"
4726+ $dep_from ("%First" @ %NPLA1),
47164727 / $impl "alternative derivation" ^ "sigil '%' binding"
47174728 $dep_from "unified xvalues binding"
47184729 ),
@@ -4785,7 +4796,7 @@
47854796 // This allows explicit 'expire' to be used to list \
47864797 lvalues to make subobjects moved solely.
47874798 ),
4788- / $impl "forwarding value for reference" $=
4799+ / $impl "forwarding values for references" $=
47894800 (
47904801 * $dev "invalid %YB_PURE used" $effective @ "functions \
47914802 %(Wrap, Wrap, WrapOnce, Unwrap, Apply) and \
@@ -4912,14 +4923,14 @@
49124923 / "transferred or returned values by term move except for \
49134924 'transfer!'" $=
49144925 (
4915- / $comp "native derivations" $dep_from
4926+ / $comp "native implementations" $dep_from
49164927 ("%(LiftToReturn, MoveRValueToForward, \
49174928 MoveRValueToReturn)" @ %NPLA,
49184929 / "alternative derivation" @ "applicative 'forward!"
49194930 ^ 'move!' ~ 'transfer!'
49204931 );
4921- / $comp DLI "optimized native and alternative derivations \
4922- to return list"
4932+ / $comp DLI "optimized native and alternative \
4933+ implementations to return list"
49234934 );
49244935 / DLI "optimized trailing parameter forwarding"
49254936 @ "operatives ('$let*', '$let*%')" ^ 'move!' ~ 'idv',
@@ -5122,14 +5133,14 @@
51225133 (
51235134 / DLDI "simplified applicative 'move!'"
51245135 ^ "%Forms::CallResolvedUnary",
5125- / DLI "simplified native derivations" @ "applicatives \
5136+ / DLI "simplified native implementations" @ "applicatives \
51265137 %(deshare, collapse)" ^ "%Forms::CallRawUnary",
5127- / DLI @ "native derivations" @ "applicatives %(id, idv)" $=
5138+ / DLI @ "native implementations" @ "applicatives %(id, idv)" $=
51285139 (
51295140 / $design ^ "%Forms::CallRawUnary",
51305141 / ^ "%TermNode::MoveContent" ~ "%LiftTerm"
51315142 ),
5132- / @ "native derivation" @ "applicative %forward" $=
5143+ / @ "native implementation" @ "applicative %forward" $=
51335144 (
51345145 / DLDI ^ "%Forms::CallRawUnary",
51355146 * "wrong %ReductionStatus::Neutral status instead of \
@@ -5138,7 +5149,7 @@
51385149 @ %NPLA) ~ "%ReduceForwarded" $since b869 $dep_to
51395150 "removal of ReduceForwarded"
51405151 ),
5141- / $forced DLI "native derivation" @ "applicatives \
5152+ / $forced DLI "native implementation" @ "applicatives \
51425153 (%collapse, 'assign%!')" ^ (($dep_from "%MoveCollapsed"
51435154 ~ "%LiftCollapsedTerm") @ %NPLA),
51445155 (
@@ -5165,7 +5176,7 @@
51655176 $dep_from ("%(RegisterUnaryStrict, RegisterBinaryStrict)"
51665177 @ %NPLA1)
51675178 ),
5168- / $revert_ex(b869) DLDI "renamed internal 'TermNode&' parameter \
5179+ / $revert_ex(b869) DLDI "renamed internal 'TermNode&' variable \
51695180 names" $effective @ (("functions %(CheckEnvironment, \
51705181 EqualLeaf, EqualReference, FirstVal, MakeEncapsulationType)",
51715182 "function templates %(CallUnary, CallUnaryAs, \
@@ -5247,8 +5258,9 @@
52475258 ),
52485259 / @ "function %LoadGroundContext" @ %Dependency $=
52495260 (
5250- / "simplified native derivation" @ "applicatives (%collapse, \
5251- 'assign%!')" ^ $dep_from ("%LiftCollapsedTerm" @ %NPLA),
5261+ / "simplified native implementation"
5262+ @ "applicatives (%collapse, 'assign%!')"
5263+ ^ $dep_from ("%LiftCollapsedTerm" @ %NPLA),
52525264 + "alternative derivation" @ "applicative 'assign%!'"
52535265 ^ "applicative %collapse"
52545266 / DLI "alternative derivation" @ "applicative 'assign!'"
@@ -5269,7 +5281,7 @@
52695281 (
52705282 * $re_add(b660) DD "wrong Doxygen command '\breif' used"
52715283 ~ '\brief' @ "class template %AXYZValueTraits",
5272- * $dev "spelling error" @ "static assert message of integer \
5284+ * $dev "spelling error" @ "static assertion message of integer \
52735285 width check failure"
52745286 ),
52755287 / DLDI @ "platform %DS" @ "function %SetEnvironmentVariable"
@@ -5303,7 +5315,7 @@
53035315 @ "functions %(ReduceToList, ReduceToListValue)",
53045316 - $revert(b769) "function %CheckNorm" $dep_from
53055317 ("%EvaluateIdentifier" @ %NPLA1),
5306- * $lib "missing support to irregular representation for references \
5318+ * $lib "missing support of irregular representation for references \
53075319 to reference with irregular representation"
53085320 @ "function %ReduceForLiftedResult" $since b858
53095321 // This is still compatible because the values of the \
@@ -5455,15 +5467,16 @@
54555467 (
54565468 / $re_add(b868) DLI
54575469 "optimized derivation" @ "applicative %accl",
5458- / DLDI "native derivation" @ "applicative %idv"
5470+ / DLDI "native implementation" @ "applicative %idv"
54595471 ^ "%ReduceForLiftedResult" ~ "%LiftToReturn",
5460- / DLI "native derivation" @ "applicative %id"
5472+ / DLI "native implementation" @ "applicative %id"
54615473 ^ 'YB_ATTR_LAMBDA(const)',
5462- / DLI "native derivation" @ "applicative %forward" ^ (($dep_from
5463- "%ReduceForwarded" ~ "%LiftRValueToReturn") @ %NPLA),
5474+ / DLI "native implementation"
5475+ @ "applicative %forward" ^ (($dep_from "%ReduceForwarded"
5476+ ~ "%LiftRValueToReturn") @ %NPLA),
54645477 // This now has %ReductionStatus::Neutral if the value is \
54655478 not lifted.
5466- / DLDI "native derivation" @ "applicative %deshare"
5479+ / DLDI "native implementation" @ "applicative %deshare"
54675480 * $lib $impl "missing previous derivation of applicative \
54685481 'first@' for internal use" @ "alternative derivation"
54695482 @ "applicatives ('set-first!', 'set-first%!', \
@@ -5483,7 +5496,7 @@
54835496 / DLDI "simplified applicative 'assign%!'"
54845497 // By sharing implementation with applicative %collapse.
54855498 ),
5486- / @ "native derivations" @ "function %LoadModule_std_strings" $=
5499+ / @ "native implementations" @ "function %LoadModule_std_strings" $=
54875500 (
54885501 / DLDI "simplified variable names"
54895502 @ "applicative 'string<-'",
@@ -5491,7 +5504,7 @@
54915504 @ "applicative 'string-contains-ci?'"
54925505 )
54935506 ),
5494- / DLDI "renamed internal 'TermNode&' parameter names" $effective
5507+ / DLDI "renamed internal 'TermNode&' variable names" $effective
54955508 @ ("functions %Forms::(CheckEnvironment, 'Eval*', 'First*', \
54965509 MatchParameter, MakeEncapsulationType, 'SetFirst*', 'SetRest*')"
54975510 @ %NPLA1, "functions %(LoadGroundContext, LoadModule_std_strings)"
@@ -5600,10 +5613,10 @@
56005613 ^ 'exprseq' ~ ('vexpr' or 'body'),
56015614 // To be consistent with the current %Documentation::NPL.
56025615 / DLDI "derivation" @ "operative '$unless'" ^ '#inert' ~ 'not?',
5603- / $lib "added native derivation enabled by default"
5616+ / $lib "added native implementation enabled by default"
56045617 @ "operative '$set!'"
56055618 ^ $dep_from ("%SetWithNoRecursion" @ %NPLA1),
5606- / $lib "added native derivation enabled by default"
5619+ / $lib "added native implementation enabled by default"
56075620 @ "operative '$setrec!'"
56085621 ^ $dep_from ("%SetWithRecursion" @ %NPLA1),
56095622 / DLI "optimized derivation" @ "applicative %accr",
@@ -5668,7 +5681,7 @@
56685681 / "simplified binary type trait %has_equality_operator"
56695682 >> %TypeTraits ^ $dep_from ("%equal_t" @ %TypeTraits)
56705683 ),
5671- / $foced "inclusion %TypeOperation" @ %Examiner -> "%TypeTraits"
5684+ / $forced "inclusion %TypeOperation" @ %Examiner -> "%TypeTraits"
56725685 $dep_from ("%has_equality_operator" @ %TypeOperation),
56735686 / DLDI "simplified %list internal construction" @ %List
56745687 // To make it more like %Tree.
@@ -5939,27 +5952,31 @@
59395952 (
59405953 + DD "'yimpl' for strengthened exception specifications",
59415954 / DLDI "reordered declarations of %swap",
5942- + DD $lib 'yimpl' @ "all '= default'" @ "special member functions",
5943- // Some implicitly defaulted exception specifications are also \
5944- strengthened.
5945- / DLDI "simplified function %get_allocator and constructors with \
5946- allocator parameter" !^ "explicit cast to %allocate_type",
5947- // Different to libstdc++, there is no support for extension \
5948- of different allocators between %allocator_type and \
5949- allocator type rebound to %value_type.
5955+ + DD $lib 'yimpl' @ "all '= default'"
5956+ @ "special member functions",
5957+ // Some implicitly defaulted exception specifications are \
5958+ also strengthened.
5959+ / DLDI "simplified function %get_allocator and constructors \
5960+ with allocator parameter"
5961+ !^ "explicit cast to %allocate_type",
5962+ // Different to libstdc++, there is no support for \
5963+ extension of different allocators between \
5964+ %allocator_type and allocator type rebound to \
5965+ %value_type.
59505966 / DLI "simplified tree constructor with a single allocator \
59515967 parameter" ^ "default constructed comparison object"
59525968 ~ "comparison object copy",
59535969 // As GCC r260806.
5954- * "improper exception specficiation of allocator-extended move \
5955- constructor" $since b830 $dep_from "tree constructor fix",
5956- // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 and \
5957- LWG 3267.
5970+ * "improper exception specficiation of allocator-extended \
5971+ move constructor" $since b830
5972+ $dep_from "tree constructor fix",
5973+ // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91541 \
5974+ and LWG 3267.
59585975 * "missing support of LWG 2005" @ "function templates %insert"
59595976 $since b830
59605977 ^ $dep_from ("%has_iterator_value_type" @ %IteratorTrait),
5961- // Since ISO C++17 features are documented, this is a bug. As \
5962- GCC r264059 and GCC r264060. See \
5978+ // Since ISO C++17 features are documented, this is a bug. \
5979+ As GCC r264059 and GCC r264060. See \
59635980 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78595 and \
59645981 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87194.
59655982 + "(function, function template) %contains"
@@ -5995,8 +6012,8 @@
59956012 (
59966013 + "#error directive to exclude configuration having \
59976014 %_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE",
5998- + "%yconstexpr extended modes objects %(ios_nocreate, ios\
5999- _noreplace)",
6015+ + "%yconstexpr extended modes objects %(ios_nocreate, \
6016+ ios_noreplace)",
60006017 + "%basic_filebuf %open support"
60016018 ),
60026019 * "missing exclusion of extended modes" @ '__GLIBCXX__'
@@ -6110,7 +6127,7 @@
61106127 )
61116128 )
61126129 );
6113- * $re_add(b849) $comp "build failure" @ "platform %Android" $since b850
6130+ * $comp $re_add(b849) "build failure" @ "platform %Android" $since b850
61146131 $dep_to "unneeded workaround for incomplete C++11 implementation"
61156132 )
61166133 ),
@@ -6345,8 +6362,8 @@
63456362 '__has_builtin(__builtin_assume) \
63466363 || YB_IMPL_CLANGPP >= 35100'",
63476364 / $impl ^ 'void()' ~ 'void(0)'
6348- // To be consistent to %YStandardEx.CAssert. This header has \
6349- already no support ISO C anyway.
6365+ // To be consistent to %YStandardEx.CAssert. This header \
6366+ has already no support ISO C anyway.
63506367 ),
63516368 + "macro %YB_ATTR_QUAL",
63526369 + $dev $re_add(b862) "preceding and following '__' for attribute \
@@ -6679,7 +6696,7 @@
66796696 + "'-flto -Wl,-allow-multiple-definition' after '-s' @ "linker option"
66806697 @ "non-debug configurations" @ %ProjectGenerator.Main
66816698 ),
6682- * $re_ex(b825) $comp $build "propable build failure with LTO"
6699+ * $comp $re_ex(b825) $build "propable build failure with LTO"
66836700 @ "%release configurations" @ "platform %Win32" $since b353
66846701 $dep_from ("script LTO workaround", %Tools.ProjectGenerator.Main)
66856702 ),
@@ -6953,7 +6970,10 @@
69536970 // To eliminate Clang++ warning on '__nonnull__' attribute.
69546971 ),
69556972 / $resolve(#35) "functon template %destruct_in" @ %Placement
6956- $= (+ $workaround(#35) @ 'YB_IMPL_MSCPP < 1921')
6973+ $= (+ $workaround(#35) "workaround for failure of compilation \
6974+ due to pseudo destructor call with noexcept-specifier \
6975+ using Microsoft VC++ 2017" @ 'YB_IMPL_MSCPP < 1921')
6976+ // This is fixed in Microsoft VC++ 2019.
69576977 ),
69586978 / %YDefinition $=
69596979 (
@@ -7102,10 +7122,11 @@
71027122 @ "main function" @ %SHBuild.Main $since b657) $dep_to
71037123 "wrong use of YB_NONNULL on member functions"
71047124 $= (/ 'YB_NONNULL(1)' -> "'YB_NONNULL(2)' or 'YB_NONNULL(3)'"),
7105- / $build "Microsoft VC++ projects" $=
7106- (
7107- / $resolve(#36, #37) "retargeted toolchain to Microsoft VC++ 2019 \
7108- (vc142)" ~ "Microsoft VC++2017 (vc141)",
7125+ / $build "Microsoft VC++ projects" $effective @ %(YBase, YFramework,
7126+ Tools.(CreationTimeManager, PredefinedMacroDetector, SHBuild)) $=
7127+ (
7128+ / $resolve(#36, #37) $re_ex(b773) "retargeted platform toolset"
7129+ -> 'v142' ~ 'v141',
71097130 // There are new issues not yet reported to be resolved, though.
71107131 / $re_ex(b832) $dev $lib "updated 'WindowsTargetPlatformVersion' value \
71117132 '10.0'" ~ '10.0.17134.0'
@@ -7407,7 +7428,7 @@
74077428 'map-reverse'"), "applicatives %(accr; foldr1; map1)")
74087429 $since b829
74097430 $= (- "redundant %forward call"),
7410- / $lib "added native derivation enabled by default"
7431+ / $lib "added native implementation enabled by default"
74117432 @ "applicative 'not?'" ^ $dep_from ("%Cond" @ %NPLA1),
74127433 / $forced DLDI "simplified applicative 'resolve-identifier'"
74137434 $dep_from ("%ResolveIdentifier" @ %NPLA)
@@ -7534,8 +7555,8 @@
75347555 / @ "namespace %Forms" $=
75357556 (
75367557 / DLDI "simplified" @ ("functions %(Eval, EvalRef, \
7537- EvalString, EvalStringRef)", "%operator()"
7538- @ "vau handlers"),
7558+ EvalString, EvalStringRef)",
7559+ "%operator()" @ "vau handlers"),
75397560 / "supported move of rvalue expressions" @ "functions \
75407561 %(Eval, EvalRef, EvalString, EvalStringRef)"
75417562 ^ ("%NPL::IsMovable" @ %NPLA),
@@ -7608,7 +7629,7 @@
76087629 (
76097630 / "function %LoadGroundContext" $=
76107631 (
7611- / $lib "added native derivation enabled by default"
7632+ / $lib "added native implementation enabled by default"
76127633 @ ("applicative %list" ^ $dep_from
76137634 ("%ListAsterisk" @ %NPLA1), "applicative 'list%'"
76147635 ^ $dep_from ("%ListAsteriskRef" @ %NPLA1),
@@ -7658,7 +7679,7 @@
76587679 // The call to %LiftTermIndirection should be avoid in cases \
76597680 other than a few like applicative %deshare. This is \
76607681 basically not guaranteed in interface (and annoying to \
7661- simulate in non-native derivations). This also improves \
7682+ simulate in non-native implementations). This also improves \
76627683 performance in many cases.
76637684 ),
76647685 / @ "function template %CheckRegular" $=
@@ -7753,9 +7774,18 @@
77537774 * "missing removing %TermTags::Temporary from the \
77547775 source term" $since b857;
77557776 // Since the referent can be bound in an \
7756- environment, it may have this tag.
7777+ environment, it may have this tag. Like C++, \
7778+ prvalue and xvalues are both bound to deduced \
7779+ argument, but in NPLA1 there is no way to \
7780+ distinguish 'T&&' or 'T&', so there is only \
7781+ one option of the two. As needed by forwarding \
7782+ lvalues, preserving %TermTags::Unique is \
7783+ inappropriate.
77577784 * "bogus %TermTags::Nonmodifying added" $since b856
77587785 $dep_to "modifying qualification fix",
7786+ // Likewise, to allow forwarding lvalues of 'T&' \
7787+ but not just 'const T&', the nonmodifying tag \
7788+ shall not be implicitly implied.
77597789 / "inherited input tags"
77607790 ),
77617791 * "bogus %TermTags::Temporary initialized for references"
@@ -7858,10 +7888,10 @@
78587888 + "applicative 'wrap%'" ^ $dep_from ("%WrapRef" @ %NPLA1),
78597889 / DLDI "simplified" @ "applicative 'assign!'" ^ $dep_from
78607890 ("%NPL::IsMovable" @ %NPLA),
7861- + "native derivation" @ "applicative 'check-environment' and \
7862- enabled by default" ^ $dep_from
7891+ + "native implementation" @ "applicative 'check-environment' \
7892+ and enabled by default" ^ $dep_from
78637893 ("%CheckEnvironment" @ %NPLA1),
7864- / $lib "added native derivation enabled by default"
7894+ / $lib "added native implementation enabled by default"
78657895 @ ("applicative 'first&'" ^ $dep_from ("%FirstRef"
78667896 @ %NPLA1), "applicative 'first@'"
78677897 ^ $dep_from ("%FirstRefAt" @ %NPLA1)),
@@ -7905,14 +7935,15 @@
79057935 "%forward" $dep_from "shared temporaries fix";
79067936 // This is not effective as long as the terms operated \
79077937 are preserved.
7908- * DLDI "%ReductionStatus use" @ "native derivations did \
7909- not respect irregular representation of references"
7938+ * DLDI "%ReductionStatus use" @ "native implementations \
7939+ did not respect irregular representation of references"
79107940 $since b858
7911- $= (/ DLDI "native derivation" @ "applicatives ('id', \
7912- 'idv', 'ref&')" ^ "%ReductionStatus::Retained"
7941+ $= (/ DLDI "native implementation" @ "applicatives \
7942+ ('id', 'idv', 'ref&')"
7943+ ^ "%ReductionStatus::Retained"
79137944 ~ "%ReductionStats::Regular"),
7914- / $lib "added native derivation enabled by default" @ "applicative \
7915- %first" ^ $dep_from ("%First" @ %NPLA1)
7945+ / $lib "added native implementation enabled by default"
7946+ @ "applicative %first" ^ $dep_from ("%First" @ %NPLA1)
79167947 // Only with the bug above fixed, the native \
79177948 implementation can behave the same.
79187949 )
@@ -7938,7 +7969,7 @@
79387969 / "handled error" ^ $dep_from 'raise-invalid-syntax';
79397970 // This is also needed to make the equivalent native \
79407971 implementation simpler.
7941- / $lib "added native derivation enabled by default"
7972+ / $lib "added native implementation enabled by default"
79427973 @ "applicative %apply" ^ ("%Apply" @ %NPLA1)
79437974 )
79447975 ),
@@ -8508,14 +8539,14 @@
85088539 inner call";
85098540 - $impl "'forward' before %body"
85108541 ),
8511- / $lib "added native derivation enabled by default"
8542+ / $lib "added native implementation enabled by default"
85128543 @ "operative '$quote'",
85138544 * $comp "wrong result of applicative 'lvalue?' for named \
85148545 lvalue references" $since b828 $dep_from
85158546 "fixed lvalue resolution",
85168547 / @ "applicative 'forward'" $=
85178548 (
8518- / $lib "added native derivation enabled by default"
8549+ / $lib "added native implementation enabled by default"
85198550 ^ $dep_from ("%LiftRValueToReturn" @ %NPLA),
85208551 // See $2019-04 @ %Documentation::Workflow.
85218552 / DLI "original derivation" ^ "%unwrap" ~ '$quote'
@@ -8527,12 +8558,10 @@
85278558 // This is consistent to 'first@'. Only these \
85288559 functions can return references to reference.
85298560 (
8530- + $forced "applicative <-%" ^ $dep_from
8531- ("%Collapse" @ %NPLA);
8532-
8533- // * $comp "missing collapse" @ "alternative derivation"
8534- @ "applicative 'set-first%!'" $since b;
8535-
8561+ + $forced "applicative <-%"
8562+ ^ $dep_from ("%Collapse" @ %NPLA);
8563+ * $comp "missing collapse" @ "alternative derivation"
8564+ @ "applicative 'set-first%!'" $since b855,
85368565 * "possible cyclic reference move self or subterm"
85378566 @ "applicatives ('<-', '<-%')" $since b856
85388567 ^ $dep_from ("%LiftTerm#1" @ %NPLA)
@@ -9734,10 +9763,10 @@
97349763 ),
97359764 / %YFramework $=
97369765 (
9737- / "improved compatibility" @ "alias %ModuleProc"
9738- @ %YCLib_MinGW32.MinGW32 ^ '__stdcall',
9739- // This allows Microsoft VC++ which does not has extension for \
9740- '__stdcall' in %std::remove_reference.
9766+ / $dev $lib "improved compatibility" @ "alias %ModuleProc"
9767+ @ 'YB_IMPL_MSCPP' @ %'YCLib_(Win32)'.MinGW32 ^ '__stdcall',
9768+ // This makes Microsoft VC++ happy with the implementation of \
9769+ %LoadProc.
97419770 / %YSLib.Core.ValueNode $=
97429771 (
97439772 + "trait class MappedSetTraits" @ "class %ValueNode",
@@ -10047,7 +10076,7 @@
1004710076 "avoided MakeIndex with container"
1004810077 ),
1004910078
10050-b851,
10079+b851
1005110080 (
1005210081 / $re_add(b850) DLDI ^ "%YSLib::unchecked_any_cast"
1005310082 ~ "%ystdex::unchecked_any_cast" $effective
@@ -10224,9 +10253,9 @@
1022410253 + "function templates %(allocate_unique; allocate_shared) for \
1022510254 parameters of %std::initializer_list instances",
1022610255 + 'using std::make_shared',
10227- * "self recursive calls" @ "make_unique for parameters of \
10228- %std::initializer_list instances" $since b
10229- $= (/ ^ "%ystdex::cpp2014::make_unique"
10256+ * "self recursive calls" @ "%make_unique for parameters of \
10257+ %std::initializer_list instances" $since b574
10258+ $= (/ $impl ^ "%ystdex::cpp2014::make_unique"
1023010259 ~ "%ystdex::make_unique"),
1023110260 / @ "functiont templates %(share_copy, share_forward, \
1023210261 share_move, unique_copy, unique_forward, unique_move)" $=
@@ -10599,9 +10628,9 @@
1059910628 (
1060010629 (
1060110630 / $lib $impl "optimized %RefHolder" !^ "%ValueHolder";
10602- + $dev "static assertion of %RefHolder instances to ensure \
10603- efficient allocation" @ "constructor %ValueObject with \
10604- %OwnershipTag<> parameter"
10631+ + $dev $lib "static assertion of %RefHolder instances to \
10632+ ensure efficient allocation" @ "constructor \
10633+ %ValueObject with %OwnershipTag<> parameter"
1060510634 ^ "%ystdex::any_ops::is_in_place_storable"
1060610635 ),
1060710636 - DLDI "redundant '&&'" @ "'*_constructible' template \
@@ -10649,8 +10678,8 @@
1064910678 has to be constructed otherwise.
1065010679 ),
1065110680 (
10652- / DLI "all 2 function templates %Add"
10653- ^ "function templates %Insert" ~ "functions %Add";
10681+ / DLI "all 2 function templates %Add" ^ "%Insert"
10682+ ~ "%Add";
1065410683 // Similar to implementations of %Insert.
1065510684 - "all 2 functions %Add"
1065610685 ),
@@ -11224,7 +11253,7 @@
1122411253 b246
1122511254 $= (- 'yconstfn')
1122611255 ),
11227- / $revert_ex(b948) $comp "throwing behavior for \
11256+ / $comp $revert_ex(b948) "throwing behavior for \
1122811257 empty targets" @ "%operator()" $dep_from
1122911258 ("%ystdex::function"
1123011259 @ %YBase.YStandardEx.Function),
@@ -11341,7 +11370,7 @@
1134111370 %(CompactPixmap, []), %GetPixels" @ "class %HBitmap" $since b430)
1134211371 @ %Image) @ %Adaptor, "functions %(RenderChar, RenderCharAlpha)"
1134311372 @ %Service.CharRenderer $since b415) @ %YSLib, "member function \
11344- %RegistryKey::GetRawValue" @ %'YCLib_(MinGW32)'.Registry $since b633,
11373+ %RegistryKey::GetRawValue" @ %'YCLib_(Win32)'.Registry $since b633,
1134511374 ("static member function template %GUCSMapper<CharSet::GBK>::Decode"
1134611375 @ %MappingEx $orig (@ %StaticMapping $since b272), "static member \
1134711376 functions %GUCSMapper<CharSet::UTF_8>::(Decode, Encode), \
@@ -11350,7 +11379,7 @@
1135011379 @ %YFramework ^ "%ystdex::(replace_cast, octet)",
1135111380 // This would be ill-formed once the %byte is %std::byte or other \
1135211381 types not implicitly convertible to %char.
11353- * $re_add(b839) $comp "build failure" @ "platform %Android" $since b841
11382+ * $comp $re_add(b839) "build failure" @ "platform %Android" $since b841
1135411383 ($dep_from ("%Reducer" @ %YFramework.NPL.NPLA), $dep_all_from
1135511384 "G++ 5.3 workarounds"),
1135611385 * $comp "configuration loading failure" @ "platform %Android" $since b838
@@ -13195,7 +13224,7 @@
1319513224 / "passed allocator by value",
1319613225 + "'1' as 2nd default parameter"
1319713226 ),
13198- + "defaulted (copy, move) (constructor, %operaotr=)"
13227+ + "defaulted (copy, move) (constructor, %operator=)"
1319913228 ),
1320013229 / @ "function templates %make_unique_with" $=
1320113230 (
@@ -13370,7 +13399,7 @@
1337013399 / $re_add(b830) $forced $build "updated %LIBS for \
1337113400 %YBase.YStandardEx.MemoryResource" @ "%SHBuild-bootstrap.sh"
1337213401 $dep_from %YFramework.YCLib.Container,
13373- * "redundant escape '\' for default variable value %LIBS_RPATH \
13402+ * "redundant escaping '\' for default variable value %LIBS_RPATH \
1337413403 quoted by %SHBuild_QuoteS_" @ "%SHBuild-YSLib-common.txt"
1337513404 @ %Scripts $since b797,
1337613405 // This was buggy for a long time, but since b838 it was used.
@@ -13777,8 +13806,8 @@
1377713806 ),
1377813807 / @ "class %MappedFile" $=
1377913808 (
13780- / DLDI @ "platform %Win32" @ "constructor" ^ 'CreateFileMappingW'
13781- ~ 'CreateFileMappign',
13809+ / DLDI @ "platform %Win32" @ "constructor"
13810+ ^ 'CreateFileMappingW' ~ 'CreateFileMappign',
1378213811 (
1378313812 / "supported empty file" @ "constructors";
1378413813 // Although for non Windows or POSIX configurations like \
@@ -13943,6 +13972,7 @@
1394313972 (
1394413973 / "cached and guarded environment variables" ^ 'safeenv-*'
1394513974 ~ "environment variable saving";
13975+ // This includes functions like '$env-de!'.
1394613976 / $comp "allowed debug environment setting with nonempty variable \
1394713977 %SS_DebugEnv",
1394813978 * $comp "externally set %INCLUDES not effective"
@@ -14780,7 +14810,7 @@
1478014810 (
1478114811 / %SHBuild.Main $=
1478214812 (
14783- / "help message" $=
14813+ / @ "help message" $=
1478414814 (
1478514815 + "clearer description of ignored subdirectories in SRCPATH"
1478614816 / "clarified option '-xd,' accepted paths"
@@ -16325,7 +16355,7 @@
1632516355 ),
1632616356 / DLDI "all 2 function template %stable_unique" @ %Algorithm
1632716357 ^ "%std::iter_swap" ~ "ADL swap",
16328- * $revert(b576) "missing header inclusion '<initialization_list>'"
16358+ * $revert(b576) "missing inclusion <initialization_list>"
1632916359 @ %Container $since b576,
1633016360 (
1633116361 + DLDI "header %Memory"
@@ -16385,7 +16415,7 @@
1638516415 (
1638616416 // The not changed specialized interface include LWG 2766 \
1638716417 (swap) and WG21 P0513R0 (std::hash).
16388- / $lib "object %nullopt" ^ $dep_from
16418+ / DLD "object %nullopt" ^ $dep_from
1638916419 ("%yconstexpr_inline" @ %YDefinition) ~ "%yconstexpr",
1639016420 (
1639116421 + $lib "overrder %what";
@@ -17395,11 +17425,9 @@
1739517425 (
1739617426 * "contract violated by missing exclusion of invalid value for \
1739717427 %std::(tolower, toupper, towlower, towupper)"
17398- @ "(function, function templates) %(tolower, toupper)"
17399- $since b605;
17428+ @ "(function, function templates) %(tolower, toupper)" $since b605;
1740017429 // See ISO C11 7.4/1 and ISO C11 7.30.1/5.
17401- / "function templates %(tolower, toupper)"
17402- => "%(towlower, towupper)";
17430+ / "function templates %(tolower, toupper)" => "%(towlower, towupper)";
1740317431 + $doc "guaranteed no other overloads for each function name"
1740417432 )
1740517433 ),
@@ -17681,7 +17709,7 @@
1768117709 / "loaded derived functions" @ "function %LoadNPLContextForSHBuild"
1768217710 @ %Dependency $=
1768317711 (
17684- * $re_add(b821) $comp "unsafe applicative %cons" $since b800,
17712+ * $comp $re_add(b821) "unsafe applicative %cons" $since b800,
1768517713 // This is now also consistent with 'list'.
1768617714 + "applicative 'cons&'" ^ $dep_from ("%ConsRef" @ %NPLA1),
1768717715 // Similar to 'list&'.
@@ -18349,7 +18377,7 @@
1834918377 (
1835018378 - "parameters" @ "type %Reducer, function %ApplyTail";
1835118379 (
18352- - $foced "1st parameter" @ "functions %(ApplyTail; Rewrite)";
18380+ - $forced "1st parameter" @ "functions %(ApplyTail; Rewrite)";
1835318381 / $forced DLDI "function %RewriteGuarded"
1835418382 ),
1835518383 / $forced DLDI "function template %SetupBoundedTail",
@@ -18986,8 +19014,7 @@
1898619014 mismatched type of unevaluated symbols" $since b803 $dep_from
1898719015 (('$assert-nonempty', '$set-system-var!', '$env-de!')
1898819016 @ "%SHBuild-YSLib-common.txt" @ %Scripts)
18989- // Mangled type names \
18990- 'N6ystdex14derived_entityINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEJN3NPL7NPLATagEEEE' \
19017+ // Mangled type names 'N6ystdex14derived_entityINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEJN3NPL7NPLATagEEEE' \
1899119018 and 'NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE' are \
1899219019 shown in exception message (of %ystdex::bad_any_cast) in case \
1899319020 using libstdc++.
@@ -19369,7 +19396,7 @@
1936919396 (
1937019397 / $impl "simplified" ^ "%OpenMode::CreateExclusive"
1937119398 ~ "%OpenMode::(Create, Exclusive)";
19372- * "wrong result for %platform::ios_nocreate" $since b722
19399+ * $comp "wrong result for %platform::ios_nocreate" $since b722
1937319400 ),
1937419401 / $re_add(b793) "marked fallthrough" @ "function \
1937519402 %ExecuteShellCommand" @ "platform %Win32" @ %HostedGUI
diff -r e1756f2eba1f -r 4d7fdf52b6d5 doc/ChangeLog.V0.9.txt
--- a/doc/ChangeLog.V0.9.txt Tue Jul 12 18:45:26 2022 +0800
+++ b/doc/ChangeLog.V0.9.txt Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file ChangeLog.V0.9.txt
1212 \ingroup Documentation
1313 \brief 版本更新历史记录 - V0.9 。
14-\version r10004
14+\version r10215
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 800
1717 \par 创建时间:
1818 2020-10-12 17:19:23 +0800
1919 \par 修改时间:
20- 2022-07-12 18:45 +0800
20+ 2022-07-25 04:47 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -32,6 +32,193 @@
3232
3333 $now
3434 (
35+ / %YFramework.NPL $=
36+ (
37+ / %NPLA1Internals $=
38+ (
39+ (
40+ + "function template %AllocateSharedTerm";
41+ + "function template %AllocateSharedTermValue";
42+ / DLDI "simplified function %ReduceForCombinerRef"
43+ ),
44+ (
45+ + "function %MakeSubobjectReferent";
46+ / DLDI "simplified function %ReduceAsSubobjectReference"
47+ )
48+ ),
49+ * "misleading exception message"
50+ @ "function %ThrowListTypeErrorForInvalidType" @ %Exception
51+ $orig (@ %NPLA $since b859)
52+ // This was OK for original %AccessTerm in NPLA.cpp in b840, but \
53+ not synchrnized with %CheckRegular in b859.
54+ $= (- ' a list'),
55+ + "function %AssertCombiningTerm" @ %NPLA,
56+ / %NPLA1 $=
57+ (
58+ / DLDI @ '!NPL_Impl_NPLA1_Enable_TCO' @ "function %SetupTailContext"
59+ ^ 'yunused',
60+ // To eliminate G++ warning: [-Wunused-parameter].
61+ * DLI "wrong 'defined' condition for \
62+ %NPL_Impl_NPLA1_Enable_ThunkedSeparatorPass"
63+ @ "constructor %REPLContext#2" $since b944,
64+ // Also to eliminate G++ warning: [-Wunused-parameter].
65+ / DLI "simplified function %ReduceCombinedBranch"
66+ ^ $dep_from ("%AssertCombiningTerm" @ %NPLA),
67+ // This enhanced the assertion.
68+ / @ "class %FormContextHandler" $=
69+ (
70+ / @ "static function %CheckArguments" $=
71+ (
72+ / DLDI "simplified"
73+ ^ $dep_from ("%AssertCombiningTerm" @ %NPLA),
74+ + 'const' @ "term reference parameter"
75+ ),
76+ + "overload %CheckArguments without wrapping count"
77+ // This is intended to used for known applicatives.
78+ )
79+ ),
80+ / @ "namespace %Forms" @ %NPLA1Forms $=
81+ (
82+ + $dev $lib "check on arguments" @ "function templates \
83+ %(CallRawUnary, CallBinary)" ^ "%AssertValueTags",
84+ * DD "argument formal syntax" @ "Doxygen comment" @ ("functions \
85+ %(LambdaWithEnvironment, LambdaWithEnvironmentRef, \
86+ VauWithEnvironment, VauWithEnvironmentRef)" $since b914,
87+ "functions %(WVauWithEnvironment, WVauWithEnvironmentRef)"
88+ $since b921),
89+ / "lifted the indirect value" @ "evaluating parent term"
90+ @ "all functions with name suffix ('WithEnvironment', \
91+ 'WithEnvironmentRef')"
92+ $dep_to "indirect parent environment evaluation",
93+ // The original implementation in b909 did not support \
94+ reference values. This is now similar to %Eval.
95+ / "supported leaf access of referents with irregular \
96+ representations" @ "functions %(EqReference, EqValue)"
97+ ^ "%IsAtom" ~ "%IsLeaf",
98+ * DD "redundant '\exception' command" @ "Doxygen comment"
99+ @ "functions %(ListAsterisk, ListAsteriskRef)" $since b860,
100+ * "missing cleanup of %Value of term before evaluation"
101+ @ "functions %(EvalString, EvalStringRef)" $since b835
102+ $= (/ ^ $impl ^ "%TermNode::SwapContent"
103+ ~ "%TermNode::SwapContainer")
104+ ),
105+ / %Dependency $=
106+ (
107+ / @ "function %LoadGroundContext" $=
108+ (
109+ / DLDI "indent" @ "derivation" @ "operative '$or'",
110+ + "applicative 'pair?'",
111+ + "applicative 'pairv?'",
112+ / "forwarded argument" @ "applicative 'for-each-ltr'",
113+ // Like the change in 'map-reserve' in b948.
114+ * "missing preserving reference values" @ "alternative \
115+ derivation" @ "applicative 'list-push-front!'" $since b921
116+ $= (/ $impl "simplified" ^ "idv"),
117+ / "supported comparing referents with irregular representations"
118+ $=
119+ (
120+ / $comp @ "applicatives ('eqv', 'eqv?')"
121+ $dep_from "%Forms::(EqReference, EqValue)";
122+ / "alternative derivation" @ "applicative 'equal?'"
123+ ^ $dep_from 'pair?'
124+ // The desired behavior is already supported in native \
125+ implementation 'equal?' by %Forms::EqualTermValue in \
126+ %NPLA1Forms so there requires no change.
127+ ),
128+ * "redandant copying expression operand" @ "alternative \
129+ derivation" @ "operative '$deflazy!'" $since b873
130+ $dep_to "forwarding trailing"
131+ // It was not named 'body', hence omitted.
132+ $= (/ $impl ^ 'forward!'),
133+ // The original change applied on 'body' was 'move!'.
134+ / DLI "reduced value copy for combiner calls" @ "alternative \
135+ derivations" $dep_to "moving body preparation" $=
136+ (
137+ (
138+ / "moved alternative derivation of applicative %forward to \
139+ top" @ 'NPL_Impl_NPLA1_Native_EnvironmentPrimitives';
140+ // This is necessary for the derivation of '$vau' to \
141+ use 'forward!'.
142+ / $design "forwarded all paramter trees"
143+ $effective @ "operatives ('$vau', '$vau%', \
144+ '$deflazy!', '$set!', '$setrec!', '$wvau', '$wvau%', \
145+ '$wvau/e', '$wvau/e%, '$lambda', '$lambda%', \
146+ '$lambda/e', '$lambda/e%', '$defv!', '$defv%!', \
147+ '$defv/e!', '$defv/e%!', '$defw!', '$defw%!', \
148+ '$defw/e!', '$defw/e%!', '$defl!', '$defl%!', \
149+ '$defl/e!', '$defl/e%!')" ^ 'forward!',
150+ // This is necessary for the following changes without \
151+ undefined behavior.
152+ ),
153+ / $design "alternative derivations" @ "operatives \
154+ ('$deflazy!', '$set!', '$setrec!', '$let', '$let%', \
155+ '$let/e', '$let/e%', '$as-environment')" ^ 'list%'
156+ ~ 'list',
157+ / $design "combination for arguments from parameter tree"
158+ @ "alternative derivations" @ "operatives ('$vau', \
159+ '$vau%', '$wvau', '$wvau%', '$wvau/e', '$wvau/e%', \
160+ '$lambda', '$lambda%', '$lambda/e', '$lambda/e%')"
161+ ^ 'cons%' ~ 'cons',
162+ // For dynamic environment and the operative, this is \
163+ unnecessary.
164+ / $design "operatives ('$defv!', '$defv%!', '$defv/e!', \
165+ '$defv/e%!', '$defw!', '$defw%!', '$defw/e!', \
166+ '$defw/e%!', '$defl!', '$defl%!', '$defl/e!', \
167+ '$defl/e%!')" ^ 'list*%' ~ 'list*'
168+ $dep_from "indirect parent environment evaluation"
169+ ),
170+ / DLI "forwarding non-body trailing sequence" @ "derivation"
171+ $dep_to "forwarding trailing" ^ 'forward!' ~ 'move!' $=
172+ (
173+ / "clauses" @ "operative '$cond'",
174+ / "expression sequences" @ "operatives \
175+ ('$sequence', '$when', '$unless')",
176+ / "tail sequences" @ ("operative '$sequence'",
177+ "applicatives ('list*', 'list*%')"),
178+ / "list sequences"
179+ @ "applicatives (%append, 'map-reverse')",
180+ / "binding sequence" @ "operative '$bindings->environment'"
181+ )
182+ ),
183+ * DLDI "incomplete inactive alternative native implementations \
184+ sample of combiner definition operations" $since b921,
185+ / "supported forwarding body" @ "alternative \
186+ derivations" ^ 'forward!' ~ 'move!' $effective
187+ @ "alternative derivation" @ ("operatives ('$vau', '$vau%', \
188+ '$deflazy!', '$set!', '$setrec!', '$wvau', '$wvau%', \
189+ '$wvau/e', '$wvau/e%, '$lambda', '$lambda%', '$lambda/e', \
190+ '$lambda/e%', '$defv!', '$defv%!', '$defv/e!', '$defv/e%!', \
191+ '$defw!', '$defw%!', '$defw/e!', '$defw/e%!', '$defl!', \
192+ '$defl%!', '$defl/e!', '$defl/e%!', '$cond', '$let', '$let%', \
193+ '$let/e', '$let/e%', '$let*', '$let*%', '$letrec', '$letrec%', \
194+ '$as-environment')" @ "function %LoadGroundContext" $dep_from
195+ "moving body preparation", "operatives ('$lazy', '$lazy%', \
196+ '$lazy/d', '$lazy/d%')" @ "function %LoadModule_std_promises")
197+ $dep_to "forwarding trailing",
198+ / $comp DLDI "prevented relying on trailing prvalues" ($dep_all_from
199+ "forwarding trailing", $dep_from "applicative 'for-each-ltr'"
200+ @ "function %LoadGroundContext")
201+ // The style matter. Further, it allows the extensions of \
202+ trailing sequence not as a list prvalue.
203+ )
204+ ),
205+ / DD %Documentation.NPL $=
206+ (
207+ * "missing ordinals" @ "operands" @ "applicative 'equal?'" $since b926
208+ * "wrong name used in the description"
209+ @ "operative $bindings->environment" $since b839,
210+ * "missing update description of '<parent>'" $mismatch(
211+ YFramework.NPL.NPLA1Forms) $since b909,
212+ // The old description was imprecise for the original \
213+ implementation because only reference to the single \
214+ environment was not support and other combination of reference \
215+ (to the list or to the element of the list) were already \
216+ supported.
217+ )
218+),
219+
220+b949
221+(
35222 + DD "'\pre' commmand" @ "Doxygen comment" @ "member function \
36223 %memory_resource::deallocate" @ %YBase.YStandardEx.MemoryResource,
37224 / %YFramework.NPL $=
@@ -162,7 +349,7 @@
162349 / $forced "enabled allocator for parameter value matcher" $efficient
163350 @ ("function %CheckParameterTree" @ %NPLA1,
164351 "function %Forms::DefineWithRecursion" @ %NPLA1Forms)
165- $dep_from ("%MakeParameterValueMatcher" @ %NPLA1Internals),
352+ $dep_from ("%MakeParameterValueMatcher" @ %NPLA1Internals)
166353 // As %(MatchParameter, BindParameter, BindParamaterWellFormed).
167354 ),
168355 + "message after linking finished" @ "member function %BuildContext::Build"
@@ -219,8 +406,7 @@
219406 ),
220407 / "changed condition as %IsPair" @ "function %IsCombiningTerm"
221408 $dep_all_from "operator name out of the combining term",
222- / DLDI "simplified function %LiftOtherValue"
223- ^ "function %LiftOther",
409+ / DLDI "simplified function %LiftOtherValue" ^ "%LiftOther",
224410 / "supported list for pair terms" @ "function %TermToString"
225411 ),
226412 / %NPLA1 $=
@@ -255,8 +441,8 @@
255441 (
256442 / DLI "avoided redundant term container copy"
257443 !^ "initializer-list",
258- * "missing tagging for the irregular representation" $since
259- b947
444+ * "missing tagging for the irregular representation"
445+ $since b947
260446 $= (/ $impl
261447 ^ "%(TermTags::Sticky, NPL::AsTermNodeTagged)")
262448 // With the changes in %(ResolveReference, \
@@ -289,7 +475,12 @@
289475 'foldr1', which should be more proper with regard to the \
290476 '<list>' typecheck for the arguments.
291477 $= (/ $impl ^ "%ThrowListTypeErrorForNonlist"
292- ~ "%ThrowInsufficientTermsError")
478+ ~ "%ThrowInsufficientTermsError"),
479+ * "wrong mark for rvalues" @ "exception messages for insufficient \
480+ subterms" @ "functions %(ListExtractFirst, ListExtractRestFwd) \
481+ and functions prefixed with 'Let'" $since b940
482+ // The extraction applicatives were added with 'forward!' in \
483+ the derivations.
293484 ),
294485 / @ "function %LoadGroundContext" @ %Dependency $=
295486 (
@@ -504,10 +695,12 @@
504695 %require" @ "function %LoadModule_std_modules")) @ %Dependency)
505696 // These include almost all call sites of %TryAccessLeaf \
506697 except a few exceptions: the implementation of \
507- %(TryAccessLeafAtom, TryAccessTerm), the internal \
508- exception throwing in %ReduceCombinedBranch and %TermRange \
509- accesses. Also 'GetObject<TermReference>()' calls in \
510- %LiftPropagatedReference would be protected by these changes.
698+ %(TryAccessLeafAtom, TryAccessTerm), the access of leaf for \
699+ saved operand name before throwing %ListReductionFailure in \
700+ %ReduceCombinedBranch, and %TermRange accesses. In particular, \
701+ the 'GetObject<TermReference>()' call in \
702+ %LiftPropagatedReference would be protected by these changes \
703+ in the call sites.
511704 $= (/ $impl
512705 ^ ($dep_from "%TryAccessLeafAtom" ~ "%TryAccessLeaf") @ %NPLA),
513706 / @ "namespace %Forms" @ %NPLA1Forms $=
@@ -5151,8 +5344,8 @@
51515344 -> 'const TermNode&',
51525345 / DLI "checked term" @ "%operator()" @ "vau handler"
51535346 ^ "%Retain" ~ ("%IsBranchedList", 'throw'),
5154- // This is also more consistent to other \
5155- context handler implementations.
5347+ // This is also more consistent to other context \
5348+ handler implementations.
51565349 (
51575350 / DLI "function %RetainN" -> "inline function";
51585351 / "functions %(Retain, RetainN)" >> "namespace %A1"
@@ -7092,7 +7285,7 @@
70927285 / %NPLA1 $=
70937286 (
70947287 / DLDI "functions %(RelayForEval, RelayForCall)"
7095- !^ "function %RelayForEvalOrDirect"
7288+ !^ "%RelayForEvalOrDirect"
70967289 $dep_to "simplified evaluation relay",
70977290 / "bound subobject reference with sigil '&' for traling list \
70987291 arguments" @ "function %BindParameter"
@@ -7102,7 +7295,7 @@
71027295 / @ "namespace %Forms" @ %NPLA1Forms $=
71037296 (
71047297 / DLDI "functions %(Eval, EvalRef, EvalString, EvalStringRef)"
7105- !^ "function %RelayForEvalOrDirect"
7298+ !^ "%RelayForEvalOrDirect"
71067299 $dep_to "simplified evaluation relay",
71077300 + "function %ListConcat",
71087301 * DLDI "missing term cleanup"
@@ -8399,12 +8592,10 @@
83998592 ),
84008593 / %SHBuild.Main $=
84018594 (
8402- / @ "option table entries" $=
8403- (
8404- / $impl "reordered '-xcmd,'" $dep_to "command entry reordering"
8405- // This also makes the entries ordered alphabatically by \
8406- chance.
8407- ),
8595+ / $impl "reordered '-xcmd,'" $dep_to "command entry reordering"
8596+ @ "option table entries"
8597+ // This also makes the entries ordered alphabatically by \
8598+ chance.
84088599 / @ "help message" $=
84098600 (
84108601 (
diff -r e1756f2eba1f -r 4d7fdf52b6d5 doc/NPL.txt
--- a/doc/NPL.txt Tue Jul 12 18:45:26 2022 +0800
+++ b/doc/NPL.txt Mon Jul 25 05:22:59 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPL.txt
1212 \ingroup Documentation
1313 \brief NPL 规范和实现规格说明。
14-\version r28845
14+\version r29102
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 304
1717 \par 创建时间:
1818 2012-04-25 10:34:20 +0800
1919 \par 修改时间:
20- 2022-07-12 18:44 +0800
20+ 2022-07-25 02:33 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -752,7 +752,7 @@
752752 **注释**
753753 在实现执行的上下文,生存期概念兼容 IEC 2382 的 lifetime 定义:
754754 portion of the execution duration during which a language construct exists
755-有序对作为绑定的抽象表示,不需要被对象语言支持。
755+定义绑定的有序对作为抽象表示,不需要被对象语言支持。对象语言可支持其它具体的有序对数据结构。
756756 典型地,作用包括计算得到的值、产生的副作用以及其它可由区域和变化的状态二元组描述的实体。
757757 一等对象同时是对象。
758758 为满足可作为表达式被求值,一等实体总是能关联表达求值结果的值,称为实体的值。
@@ -845,6 +845,7 @@
845845 通过明确不可修改性拒绝支持修改操作(例如通过通过实体的类型检查(@4.7.4) 拒绝特定的修改操作),或通过不提供修改操作(例如关于 ISO C++ 的非类且非数组类型的纯右值,尽管要求非纯右值可被视为是一种类型检查),语义规则保证实体不被修改操作改变状态。
846846 (不依赖和影响实体同一性(@4.1) 的)同一个实体上的修改操作是改变操作。只有具有可变状态(@1.2.1.2) 的实体可能支持这些操作。
847847 一般地,一个实体不一定保证可区分是否具有不可变性以及具有何种不可变性(也蕴含一般不可区分可修改性),因为不可变性依赖实体的表示(@1.2.4) 进行约定。
848+按定义(@4.1) ,引起表达式的值以外的改变的作用是副作用。
848849 潜在引起实体的一些内部状态的变化的操作可不被视为影响不可变性而不被视为实体的(整体意义上的)改变操作。这种实体具有内部可变性(interior mutability) 。
849850 可引起实体变化的状态按设计上是否隐藏局部变化(@4.1.3) 分为两类:可变管理状态(mutable administrative state) 和可变数据状态(mutable data state)。
850851 可变数据状态的改变是对象的改变;可变管理状态的改变作为管理状态(@4.1.3) 的改变,不被视为对象(整体)改变的对象内部状态的改变。
@@ -878,7 +879,9 @@
878879 @4.1.5 数据结构:
879880 实体之间可能允许具有集合论意义上的包含关系。被包含的实体称为子实体(subentity) 。
880881 子实体可以是作为数据结构的一部分。这种数据结构可以是一般的图(graph) 。
881-数据结构也可在对象语言中通过实体包含关系以外的途径定义。例如,限定包含关系构成的图中的所有权关系(@4.2.2.3) 附加限制,详见 @4.2.4 。
882+数据结构也可在对象语言中通过实体包含关系以外的途径定义。
883+**注释**
884+例如,限定包含关系构成的图中的所有权关系(@4.2.2.3) 附加限制,详见自引用和循环数据结构(@4.2.4) 。
882885
883886 @4.1.6 作用使用原则:
884887 不同副作用对行为(@1.2.4) 的影响可能依赖作用之间的顺序。
@@ -1362,7 +1365,10 @@
13621365 WHNF 中除了操作符以外的子表达式是操作数(operand) 。
13631366 操作数以具有限定顺序或不限定顺序的数据结构表示,典型代表分别是操作数列表(operand list) 和操作数树(operand tree) 。
13641367 操作数树是有限的树形数据结构的 DAG(@4.2.4) (和 Kernel 类似),其具体构造和表示由派生实现定义。
1365-这种能以操作符和操作数的组合表达的计算形式是操作(operation) 。操作的结果和作用即这种可求值为 WHNF 表达式的求值结果(@4.1) 和作用(@4.1) 。
1368+这种能以操作符和操作数的组合表达的计算形式是操作(operation) 。
1369+操作的结果(result) 是表达规约步骤(@4.4) 得到的范式(@4.4.5) ;操作的作用是取得对应结果的规约步骤的作用。
1370+若操作的结果不依赖管理规约(@4.4.2) ,操作的结果和作用即这种可求值为 WHNF 表达式的求值结果(@4.1) 和作用(@4.1) 。
1371+**注释** 另见函数值(@4.5.3.1) 。
13661372
13671373 @4.4.6 组合求值:
13681374 表达式和子表达式之间的求值需满足一定约束。
@@ -2202,12 +2208,13 @@
22022208 注意此时表达式的值可能是左值,因此表达式的“值”与“右值”不等价,这与 ISO C 的一般约定不同。
22032209
22042210 @5.8.2 初始化:
2205-部分创建对象的表达式引入对象的初始化(initialization) 。
2211+对象被创建后可通过初始化(initialization) 决定其值,并可能存在其它作用(@1.2.4) 。被决定的值是初始值(initial value) 。
2212+决定初始化这些作用的表达式是初始化的初值符(initializer) 。
2213+初值符的求值可能有副作用,其求值结果指定特定被初始化的对象的初始值。
22062214 初始化包括被绑定实体(@5.7) 的初始化和作为函数值的返回值(@4.5.3.1) 对象的初始化。
2207-决定初始化这些对象的作用(@1.2.4) 的表达式是初始化的初值符(initializer) 。
2208-初值符的求值可能有副作用,其求值结果指定特定被初始化的对象的初始值(initial value) 。
22092215 初始化被绑定对象可能以修改操作(@4.1.4.2) 的形式体现,此时修改绑定具有副作用。若这样的副作用存在,每个被初始化的值后序(@4.4.3) 于对应初始的计算。
22102216 **注释**
2217+初值符的求值的副作用不属于初始化,其求值结果和对象的初始值不一定相同。
22112218 和宿主语言不同,初始化不是独立的依赖特定语法上下文的概念,但此处语义上的作用类似,一般可蕴含宿主对象的初始化。
22122219
22132220 @5.8.2.1 复制初始化和直接初始化:
@@ -2269,9 +2276,11 @@
22692276 引用值属性指定访问的它表示的对象或通过引用对被引用对象的访问假定允许具有的性质。
22702277 特定的操作使用引用值作为操作数,根据不同的属性决定行为,包括在违反属性引入的假定时引起错误(@2.5.2) 。
22712278 在本节要求以外,除非派生实现另行指定,违反这些假定不引起 NPLA 未定义行为(@5.4) 。
2272-唯一引用允许通过通过具有唯一引用属性的引用值访问关联的对象,对象可被假定不被其它引用而仅通过这个途径访问,即便实际存在其它途径的引用时可能引起不同的行为;在假定的基础上程序具有何种可能的行为是未指定的。
2273-唯一引用可被假定不被共享,被引用对象不被别名(@4.2.3.4.3) 。
2274-通过不可修改引用的左值的对象访问不包含修改(@4.1) 。否则,若没有引起错误,程序行为未定义;但除非另行指定,不引起宿主语言的未定义行为(@5.4) 。
2279+具体的引用属性满足以下语义规则:
2280+ 唯一引用允许通过通过具有唯一引用属性的引用值访问关联的对象,对象可被假定不被其它引用而仅通过这个途径访问,即便实际存在其它途径的引用时可能引起不同的行为;在假定的基础上程序具有何种可能的行为是未指定的。
2281+ 唯一引用可被假定不被共享,被引用对象不被别名(@4.2.3.4.3) 。
2282+ 通过不可修改引用的左值的对象访问不包含修改(@4.1) 。否则,若没有引起错误,程序行为未定义;但除非另行指定,不引起宿主语言的未定义行为(@5.4) 。
2283+ 具有临时对象引用属性的引用值是临时对象的引用值,其被引用对象是临时对象。
22752284 **原理** 宿主语言的互操作不被总是要求保证对象语言程序的可移植性,但不应引起实现自身的行为无法预测。
22762285 对引用值的操作传播(propagate) 特定的引用属性,当且仅当:
22772286 若操作数是具有特定引用属性的引用值,且结果是引用值时,结果具有和操作数相同的特定属性。
@@ -2302,50 +2311,56 @@
23022311 不涉及引用值的消除时,NPLA 对象的子对象的不可修改性一般也直接依赖具体元素(如不可修改引用作为列表元素)。除不可修改引用蕴含的对直接引用的被引用对象不可修改外,是否满足需要传播不可修改性依赖具体操作的语义。
23032312 **注释**
23042313 典型地,消除引用值包括:
2305-当引用值提升转换(@5.8.4) 的操作数是引用值时,消除被提升的引用值;
2306-当引用折叠(@5.8.3.5) 的操作数是引用值时,消除被折叠的引用值。
2314+ 当引用值提升转换(@5.8.4) 的操作数是引用值时,消除被提升的引用值。
2315+ 当引用折叠(@5.8.3.5) 的操作数是引用值时,消除被折叠的引用值。
23072316 和引用折叠不同,引用值提升转换不满足对不可修改引用属性的传播性质。
23082317
23092318 @5.8.3.5 引用折叠(reference collapse) :
23102319 和 ISO C++ 类似,引用值在 NPLA 中默认不被继续引用,使用引用初始化引用会引用到被引用对象(@4.2.3) 上,即引用折叠。
23112320 引用值被折叠后结果和原引用值不同,当且仅当原引用值是未折叠的引用值(@5.8.3.2) 。
23122321 和 ISO C++ 不同,NPLA 不限制派生实现利用未折叠的引用值。
2313-NPLA 一般规则不区分引用值是否完全折叠,但特定的操作可能区分未折叠的引用值。
2314-未折叠的引用值被折叠时,用于初始化的被引用对象可能仍然是未折叠的引用值。
2322+**注释** 特定的操作可能区分未折叠的引用值。
23152323 引用折叠的结果是不可修改引用,若引用值和作为引用值的被引用对象之一是不可修改引用。
2316-引用折叠的结果满足不可修改引用属性的传播性质(@5.8.3.3) 。
2317-**注释** 即引用折叠的结果是唯一引用(@5.8.3.3) ,当且仅当引用值和作为引用值的被引用对象都是唯一引用。
2318-引用折叠的结果是临时对象引用(@5.8.3.3) ,当且仅当被引用对象是临时对象引用。
2324+引用折叠的结果满足不可修改引用属性的传播性质(@5.8.3.3) 。推论:
2325+ 引用折叠的结果是唯一引用(@5.8.3.3) ,当且仅当引用值和作为引用值的被引用对象都是唯一引用。
2326+ 引用折叠的结果是临时对象引用(@5.8.3.3) ,当且仅当被引用对象是临时对象引用。
23192327 **原理**
23202328 内部表示可支持间接的引用,以允许在对象语言中实现一等引用(@4.2.3) 。
23212329 引用折叠对不可修改的传播性质的要求和 ISO C++ 的引用折叠对 const 限定符的处理类似。
23222330 引用折叠对唯一引用的要求和 ISO C++ 的右值引用仅通过被折叠的引用都是右值引用类型折叠类似。注意 ISO C++ 右值引用推断仅用于推断转发引用(forwarding reference) 参数,而非直接声明特定的右值引用类型。
23232331 和唯一引用不同,临时对象相对唯一引用更接近 ISO C++ 的声明的右值引用类型信息(而非推断值类别时使用的消亡值表达式的右值引用类型),一般不预期被折叠。使用被引用对象的临时对象标签(@6.2.2) 单独决定折叠结果更容易直接保留被引用对象的状态。
2332+**注释**
2333+未折叠的引用值被折叠时,用于初始化的被引用对象可能仍然是未折叠的引用值。
23242334
23252335 @5.8.3.6 对象的可转移条件:
23262336 根据项是否具有特定元数据的引用值可判断使用复制代替对象转移的条件(@5.8.2.3) 。
2327-对象的可转移条件的判断基于首先基于值的类型(@5.8.6) :
2337+对象的可转移(movable) 条件的判断基于首先基于值的类型(@5.8.6) :
23282338 非引用值(纯右值)总是可转移的。
23292339 否则,对象是引用值。可转移由引用值的属性(@5.8.3.3) 决定:当引用值是唯一引用且非不可修改,引用值是可转移引用,对应的被引用对象是可转移的。
23302340 **注释**
23312341 关于具体表示,参见项的可转移条件(@6.8.3.3) 。
23322342
23332343 @5.8.4 值类别转换:
2334-和宿主语言类似,具有特定值类别的表达式可转换为不同值类别的表达式:
2335-除非另行指定,泛左值总是允许作为纯右值使用。从泛左值取对应右值的操作称为左值到右值转换(lvalue-to-rvalue conversion) ;
2336-从纯右值初始化(@5.8.2) 可被对象语言作为一等对象(@4.1) 使用的临时对象(@5.8.5) 作为消亡值(@5.8.1) ,称为临时对象实质化转换(temporary materialization conversion) 。
2344+具有特定值类别的表达式可转换为不同值类别的表达式:
2345+ 除非另行指定,泛左值总是允许作为纯右值使用。从泛左值取对应右值的操作称为左值到右值转换(lvalue-to-rvalue conversion) 。
2346+ 从纯右值初始化(@5.8.2) 可被对象语言作为一等对象(@4.1) 使用的临时对象(@5.8.5) 的引用值作为消亡值(@5.8.1) ,称为临时对象实质化转换(temporary materialization conversion) 。
23372347 左值到右值转换没有副作用(@4.2.2.1) 。临时对象实质化转换没有副作用,当且仅当其中初始化临时对象时没有副作用。
23382348 临时对象实质化转换中,纯右值被实质化(materialized) 。
23392349 在求值子表达式时,按表达式具有的语义,必要时(如按 @5.8.1.1 判断上下文的值类别)进行值类别转换。
2340-为支持引用值(@5.8.3) 作为一等对象(特别是未折叠的引用值(@5.8.3.2) ),NPLA 提供比左值到右值转换更精细的引用值提升转换,即以下转换操作:
2341-若操作数是引用值,则结果是操作数引用的被引用对象(@4.2.3) ;
2342-否则,结果是操作数。
2343-根据引用值的性质,易知左值到右值转换的规约是引用值提升转换的规约的传递闭包,即:
2344-若操作数是已完全折叠的引用值(@5.8.3.5) ,则引用值提升转换等价左值到右值转换;
2345-否则,有限次的引用值提升转换等价左值到右值转换。
2346-**注释**
2350+NPLA 还提供可能使结果具有不同的值类别的引用值提升转换。以下规则确定引用值提升转换的结果:
2351+ 若操作数是引用值,则结果是操作数的被引用对象(@4.2.3) 。
2352+ 否则,结果是操作数。
2353+**原理**
2354+为支持引用值(@5.8.3) 作为一等对象(特别是未折叠的引用值(@5.8.3.2) ),NPLA 提供比左值到右值转换更精细的引用值提升转换。
2355+**注释**
2356+不同值类别表达式的转换和宿主语言中的部分标准转换类似。
23472357 关于当前实现,参见实现说明(@6.4.5) 。
23482358 提升的含义参见提升项(@6.9.4) 。
2359+根据引用值的性质,易知左值到右值转换的规约是引用值提升转换的规约的传递闭包,即:
2360+ 若操作数是已完全折叠的引用值(@5.8.3.5) ,则引用值提升转换等价左值到右值转换。
2361+ 否则,有限次的引用值提升转换等价左值到右值转换。
2362+引用值提升转换不传播(@5.8.3.3) 引用值的属性(@5.8.3.4) 。
2363+引用值提升转换不传播不可修改属性,类似 [ISO C++] 非引用值的转换在结果中不保留源操作数中的 const 类型。
23492364
23502365 @5.8.4.1 设计原理:
23512366 值类别和左值到右值转换在一些上下文的行为类似箱和自动拆箱(@4.2.3.5.3) ,不利于维护简单性(@1.5.3.2) :
@@ -2363,22 +2378,26 @@
23632378
23642379 @5.8.5 临时对象(temporary object) :
23652380 特定的 NPLA 非一等对象(@5.6) 是临时对象。
2366-NPLA 允许(但不要求对象语言支持)一等对象通过特定的求值,在中间结果中蕴含这种非一等对象。
2367-和宿主语言类似,NPLA 对象语言在特定的上下文引入其它临时对象,包括:
2381+NPLA 允许(但不要求对象语言支持)一等对象构成的表达式通过特定的求值,在中间结果中蕴含这种非一等对象。
2382+**注释** 这样的非一等对象不在源语言中可见,一般仅用于互操作(@5.3) 。
2383+NPLA 对象语言在特定的上下文引入其它临时对象,包括:
23682384 实质化转换上下文(@5.8.5.1) ;
23692385 返回值转换上下文(@5.8.5.2) 。
2370-关于临时对象的存储和所有权,参见求值和对象所有权(@5.6.2) 。
2386+**原理**
23712387 为简化规约和互操作(@5.3) 机制的设计,和 ISO C++17 不同,引入临时对象不包括延迟初始化或异常对象的创建。
2388+**注释**
2389+关于临时对象的存储和所有权,参见求值和对象所有权(@5.6.2) 。
23722390 关于避免特定相关对象的初始化(@5.8.2) 的要求,参见复制消除(@5.8.5.3) 。
2373-**注释**
2391+引入临时对象的一些上下文的和宿主语言类似。
23742392 当前设计中临时对象具有特定的表示(@6.3.2) 。
23752393
23762394 @5.8.5.1 实质化转换上下文:
2377-可要求临时对象实质化转换(@5.8.4) 的上下文包括:
2378-使用纯右值初始化按引用绑定的变量(如函数的引用类型的形式参数(@4.5.2.1) );
2379-求值函数调用以初始化返回值对象。
2380-其中,按引用绑定的变量被可选地支持。
2381-一般地,按引用绑定的变量在活动调用(@4.5.3.1) 关联的环境分配临时对象。此时,对象被调用表达式的项独占所有权,同时被绑定的环境独占资源所有权。
2395+可具有(但不保证具有)临时对象实质化转换(@5.8.4) 的上下文包括:
2396+使用纯右值初始化被绑定为引用值的变量(如函数的引用类型的形式参数(@4.5.2.1) );
2397+求值函数调用(@4.5.3.1) 以初始化函数值(@4.5.3.1) 。
2398+**注释**
2399+一般地,被绑定为引用值的变量在活动调用(@4.5.3.1) 关联的环境分配临时对象。此时,对象被调用表达式的项独占所有权,同时被绑定的环境独占资源所有权,并实现复制消除(@5.8.5.3) 。
2400+在不具有转换时,优化的实现可能消除函数调用(内联(inline) 展开)而不分配关联的环境,把临时对象分配到其它环境或者语言不保证可见的存储(如 CPU 寄存器)中,并同时实现复制消除(@5.8.5.3) 。
23822401 临时对象实质化转换引入临时对象的规则和 ISO C++17 不同:
23832402 不论表达式是否作为子表达式使其值被使用(未使用的情形对应 ISO C++ 中的 discarded-value expression ),都允许存在临时对象;
23842403
@@ -2388,18 +2407,22 @@
23882407 仅在对象被复制且复制具有副作用时,返回值转换具有等价复制的副作用。
23892408
23902409 @5.8.5.3 复制消除(copy elision) :
2391-和 ISO C++17 类似,NPLA 要求特定上下文中的复制消除,排除复制或转移操作且保证被消除操作的源和目的对象的同一性(@4.2.1.1) 。
2392-和 ISO C++17 不同,NPLA 的复制消除限于临时对象的消除,但不限制对象的类型(特定的 C++ 类类型),且除以下约定外的所有表达式求值的上下文对复制消除相同。
2393-**注释** 例如,不区分求值结果是否被作为返回值(@4.5.3.1) 或求值是否为常量表达式。
2410+NPLA 要求特定上下文中的复制消除,排除复制或转移操作且保证被消除操作的源和目的对象的同一性(@4.2.1.1) 。
23942411 复制消除仅在以下转换上下文中被要求,即直接使用被转换的源表达式中的对象作为实质化的对象而不初始化新的临时对象:
23952412 实质化转换上下文(@5.8.5.1) ;
2396-引起对象转移的返回值转换上下文(@5.8.5.2) 。
2413+引起对象转移至函数值(@4.5.3.1) 的返回值转换上下文(@5.8.5.2) 。
23972414 **注释** 在实现中,这是被求值项(@6.3.7) 指称的对象(@6.4.5) 。
23982415 非本机实现(@5.3) 函数函数体内指定的返回值不属于上述的确定返回值的上下文,但也不要求被复制消除。
2399-**注释** 这和 ISO C++17 要求 return 语句中的特定的表达式被消除不同,而不需要依赖特定上下文的语法性质。
24002416 实现仍可能根据当前环境(@5.7.3) 来判断是否在允许消除对象复制的上下文中(当前未实现),而进行复制消除。
24012417 在完成实质化转换前的不完整的求值规约(@4.4) 中的临时对象在逻辑上不需要作为一等对象(@4.1) 存在,但纯右值作为对象表示中的子项,随纯右值在宿主语言中作为对象存在,以允许互操作。
24022418 复制消除不在被初始化对象以外引入新的对象语言可见的对象。
2419+**原理**
2420+为维护语言规则的简单性(@1.5.3.2) 和使用这些规则的程序的行为的易预测性(@1.5.5.2.1) ,NPLA 的复制消除限于临时对象的消除。
2421+复制消除的目的 ISO C++17 类似。同时,提供语言支持也允许更简单地实现 C++ 互操作性。
2422+和 ISO C++17 不同的一些要求可简化语言规则和实现,例如:
2423+ 不区分求值结果是否被作为返回值(@4.5.3.1) 或求值是否为常量表达式。
2424+ 非本机实现函数的规则不要求 return 语句中的特定的表达式,而不需要依赖特定上下文的语法性质。
2425+ 同时,NPLA 不限制对象的类型(ISO C++17 则要求特定的 C++ 类类型)。
24032426
24042427 @5.8.5.4 生存期延长(lifetime extension) :
24052428 在使用纯右值初始化引用值时,延长源表达式的项指称的对象(@6.4.5) 的生存期(@5.9) 。
@@ -2713,8 +2736,10 @@
27132736 当这些序列中的每个节点表示一等对象时,即构成无环列表(acyclic list) 的表示。
27142737 推论:列表对其元素具有所有权。
27152738 无环列表不包含环(cycle) 。
2716-若节点的值数据成员同时为空值(即 ValueObject() ),则列表是真列表(proper list) 。
2739+若节点的值数据成员同时为空值(即 ValueObject() ),则节点表示真列表(proper list) 。
27172740 真列表中每个子节点是构成真列表的元素(element) 的对象的表示。
2741+真列表是列表(list) 。节点可表示同属列表的非真列表(improper list) 。除非另行指定,列表指真列表。
2742+列表的元素有限,同一个列表的不同元素之间不具有相互的所有权,生存期不相交。
27182743 按内容的结构,项节点具有如下互斥的基本分类(使用 TermNode 的 empty() 判断):
27192744 枝节点(branch node) 或非叶节点,即具有子节点的节点,表示非空列表或同时具有子节点和叶节点的非正规(@6.2.1) 的非列表;
27202745 叶节点(leaf node) ,即不具有子节点的节点,表示空列表或不具有子节点的正规的(@6.2.1) 非列表。
@@ -2732,8 +2757,8 @@
27322757 先判断是否为枝节点,再判断是否为符合预期类型的非空叶节点,分派不同的操作;
27332758 根据项表示的值(@4.1) 考虑子节点及值数据成员。
27342759 **注释**
2735-真列表以外的其它形式的一般列表(list) 数据结构及其表示另见真列表以外的其它列表(@6.3.9.1) 。
2736-如 Scheme 和 Kernel 中可能有环的非真列表(improper list) 不被支持。原理参见循环引用(@4.2.4) 。
2760+真列表以外的其它形式的一般列表数据结构及其表示参见真列表以外的其它列表(@6.3.9.1) 。
2761+如 Scheme 和 Kernel 中可能有环的非真列表不被支持。原理参见循环引用(@4.2.4) 。
27372762 关于规约后的一般表示,参见正规表示(@6.10.6) 。
27382763
27392764 @6.2.2 项的标签(tag) :
@@ -2747,7 +2772,7 @@
27472772 Temporary :临时对象(@5.8.5) 。
27482773 Sticky :粘滞位,不构成单独的一等对象表示(@6.3.4) ,用于特定的对象的表示的一部分(@6.3.9.1) 。
27492774 在 TermTagIndices 中的枚举项带有 Index 后缀,和这些枚举项一一对应。
2750-当前标签值都和引用值的对象访问对应的含义相关,参见引用值的属性(@5.8.3.3) 。
2775+当前标签值都和引用值(@5.8.3) 的对象访问对应的含义相关,参见引用值的属性(@5.8.3.3) 。
27512776
27522777 @6.2.2.1 标签值使用范围约定:
27532778 除非另行指定,标签值被初始化为默认值(非限定对象)。
@@ -2802,7 +2827,7 @@
28022827 以上操作通常仅在不涉及语义(仅涉及语法,或更基本的底层操作实现)时使用其访问项中非列表类型(@6.2.1) 的值。
28032828 涉及更具体的语义时,使用项访问操作(@6.9.2) 、项引用和项引用访问操作(@6.9.3) 的 NPLA API 代替。这些接口提供了确切的项结构检查以符合正规化表示的相关假设(@6.10.6.1) 。
28042829 **原理**
2805-原子节点定义为不能表示为一等对象有序对的节点表示。其命名来自传统 Lisp 的原子谓词。在这个定义下,原子谓词判断的原子数据类型和有序对类型互补。
2830+原子节点定义为不能表示为一等对象有序对(@6.3.9.1) 的节点表示。其命名来自传统 Lisp 的原子谓词。在这个定义下,原子谓词判断的原子数据类型和有序对类型互补。
28062831 这和多数 Lisp 方言中对原子节点谓词的定义一致。仅有少数方言如 InterLisp 存在不是原子也不是有序对的数据类型。
28072832 **注释**
28082833 修改值数据成员为环境引用的宿主类型(@6.8.2) 和项引用(@6.8.3) 的值通常使用成员 SetValue ,且在合适时使用 in_place_type 实例参数。
@@ -2861,10 +2886,10 @@
28612886 引用项(reference term) ;
28622887 使用 TermTags::Temporary 标签(@6.2.2) 标记的非引用项。
28632888 其中,前者是值数据成员为项引用(@6.8.3) 对象的项。
2864-引用项中的项引用对象引用一个(其它的)项,用于在必要时引入可被引用的一个项而不在 TermNode 中直接储存这个项的值。
2889+引用项中的项引用对象引用一个(其它的)项,即被引用项(referenced term) ,用于在必要时引入可被引用的一个项而不在 TermNode 中直接储存这个项的值。
2890+被引用项表示引用项作为引用值对应的被引用对象(@4.2.3) 。
28652891 对实现作为一等对象(@4.1) 的列表(@6.2.1) 的引用(@4.2.3) ,支持引用整个项的中间值是必要的;但项引用也支持引用非列表项。
2866-临时对象(@5.8.5) 可作为引用值的被引用对象(@4.2.3) 。
2867-因为临时对象不是一等对象(@5.8.5) ,临时对象的引用值可代替关联的被引用对象使之作为一等对象被访问,因此使用被引用对象添加 TermTags::Temporary(@6.2.2) 标签表示。
2892+临时对象(@5.8.5) 可作为引用值的被引用对象。
28682893 与此不同,非临时对象的引用值可作为一等对象而总是需要区分作为不同对象的同一性(@4.1) 。
28692894 引用值可能是左值引用(lvalue reference) 或右值引用(rvalue reference) 。
28702895 前者是排除引用项表示且不是唯一引用(@6.2.2) 的引用值;后者是以引用项表示的唯一引用或临时对象初始化的非引用项的引用值。
@@ -2874,6 +2899,10 @@
28742899 若类型是左值引用,则对应的值类别是左值;
28752900 若类型是右值引用,则对应的值类别是消亡值;
28762901 否则,对应的值类别是右值。
2902+**原理**
2903+因为临时对象不是一等对象(@5.8.5) ,临时对象的引用值可代替关联的被引用对象使之作为一等对象被访问。
2904+**注释**
2905+临时对象的引用值是被引用对象和带有临时对象引用属性的引用值(@5.8.3.3) 。
28772906
28782907 @6.3.4 一等对象的表示:
28792908 一部分项可以作为对象语言中的一等对象或值的表示(@1.2.4) ,即一等对象表示。
@@ -2952,8 +2981,8 @@
29522981
29532982 @6.3.9.1 无环非真列表(acyclic improper list) :
29542983 无环非真列表是不属于其它情形的非正规表示可表示的一等对象,具有至少一个子项表示一等对象。
2955-不考虑所有权时,无环非真列表总是能被表示为一个对象和一个非列表对象构成的有序对(pair) 。取得无环非真列表的有序对形式的表示分解这个无环非真列表。
2956-无环非真列表分解后的第二个元素可能继续可被分解。经有限次这样的分解后第二个元素不再是有序对而不能继续分解,得到完全分解。一个无环非真列表的完全分解的对象是它的元素。
2984+不考虑所有权时,无环非真列表总是能被表示为一个元素和一个非列表元素构成的有序对(pair) 。取得无环非真列表的有序对形式的表示分解(decompose) 这个无环非真列表。
2985+无环非真列表分解后的第二个元素可能继续可被分解。经有限次这样的分解后第二个元素不再是有序对而不能继续分解,得到完全分解的元素序列。除非另行指定,无环非真列表的元素是其完全分解得到的元素。
29572986 推论:无环非真列表最后一个元素不是空列表。
29582987 类似真列表(@6.2.1) :
29592988 无环非真列表不支持环;
@@ -3079,7 +3108,7 @@
30793108 为实现临时对象求值和对象所有权(@5.6.2) ,临时对象以项自身作为表示(@6.3) ,被纯右值所有,也间接被其它项所有。
30803109 特定情况下纯右值可能被环境所有,但应只通过复制等方式访问其值而不依赖所有权关系(如仅复制记号值(@6.4.6.2) )。
30813110 **注释**
3082-当前实现中临时对象实质化通常实现为空操作,因为项在先前(如返回值转换(@5.8.4.2) 的蕴含的引用值提升转换的引用项提升)已被创建。
3111+当前实现中临时对象实质化通常实现为空操作,因为项在先前(如返回值转换(@5.8.4.2) 的蕴含的引用值提升转换的引用项(@6.3.3) 提升)已被创建。
30833112 互操作可能引入不以项表达的右值而需要首先创建项。
30843113
30853114 @6.4.6 间接值使用规则:
@@ -3126,11 +3155,11 @@
31263155 使用删除策略(@5.6.4.1) 实现过程调用(@4.5.3.1) ,其中分配的资源随包含资源引用的间接值返回可能逃逸(@4.5.3.1) 。
31273156 若其被引用对象(@4.2.3) 在调用后不再存在,则引用不再有效,构成悬空引用(@5.8.3.1) 。因此,对这些间接值的访问非内存安全。
31283157 为维护内存安全保证,这些情形应被证明不存在。通过间接值的消除移除这些间接值是一种直接的方式。
3129-替代消除引用值的方式包括通过逃逸分析(escape analysis) 替换间接值,这也能减少间接值的访问而提供更优化的实现。例如,通过对环境中被绑定对象的使用进行逃逸分析(@5.7.2) 提供优化实现。
3158+替代消除间接值的方式包括通过逃逸分析(escape analysis) 替换间接值,这也能减少间接值的访问而提供更优化的实现。例如,通过对环境中被绑定对象的使用进行逃逸分析(@5.7.2) 提供优化实现。
31303159 但是,这不在 NPLA 中被要求,因为:
31313160 逃逸分析需要完整的所有权信息,这需要附加的开销,否则不总是可行(例如涉及跨多个过程的调用);
31323161 对删除策略,逃逸分析也没有提供不可替代的优化。
3133-**注释** 引用值作为间接值(@6.4.6.1) 可被消除(@5.8.3.4) 。
3162+**注释** 引用值(@6.3.3) 作为间接值(@6.4.6.1) 可被消除(@5.8.3.4) ,是消除间接值的主要实例。
31343163 用于按值传递参数时,一般使用 NPL::LiftTerm(@6.9.4.2) 和确保创建值副本的 NPL::SetContentWith(@6.2.3) 实现;前者取非引用类型的右值(@5.8.1) ,后者提升间接值确保结果不是中间值。
31353164 用于按值传递返回值时(@4.5.3.1) ,除显式分别对是否为引用值的情形进行处理,可使用 NPL::LiftToReturn(@6.9.4.3)(其中也使用以上方式实现),实现临时对象实质化转换(@5.8.4) ,详见 @6.4.6.4 。
31363165
@@ -3271,15 +3300,16 @@
32713300
32723301 @6.8.3 项引用(term reference) :
32733302 宿主语言中,类 TermReference 是项引用。
3274-项引用是泛左值(即临时对象引用以外的引用值)的内部表示的值类型对象的宿主值(@6.3.5) 。
3275-**注释** 临时对象不使用项引用,而直接使用具有临时对象标签的项表示(@6.3.2) 。
3303+项引用是泛左值(即临时对象的引用值以外的引用值)的内部表示中存储在值数据成员中的目标类型(@6.2) 。
32763304 其中,子项只被子对象引用(@6.8.3.3) 的情形使用。
3305+项引用包含能以 C++ 引用的方式访问到被引用项(@6.3.3) 的状态。
32773306 通过项引用可访问引用值的被引用对象,即间接操作(@6.9.3) 。
32783307 引用值的被引用对象(@4.2.3) 应为一等对象(@4.2.1) 或被绑定对象(@5.7.1) 。
32793308 **原理**
32803309 子对象引用使用的这种形式的表示通常因为需要更多的操作比其它引用值的类似操作低效,但这种表示可避免依赖宿主语言中的本机对象内部表示(如成员布局)的依赖。
32813310 一般地,在 C++ 的意义上不存在能满足语义的更有效的可移植表示,所以这种表示在和宿主语言的互操作(@5.3) 上是必要的。
3282-临时对象引用不使用项引用表示,允许生存期延长(@5.8.5.4) 引入的临时对象不跟随引用项(@6.3.3) 而作为被绑定对象在环境中保存。
3311+临时对象(@5.8.5) 不使用项引用,而直接使用具有临时对象标签的项表示(@6.3.2) 。这允许生存期延长(@5.8.5.4) 引入的临时对象不跟随引用项(@6.3.3) 而作为被绑定对象在环境中保存。
3312+因为不确保能单独表示一等对象,当前项引用的值以互操作(@5.3) 目的使用,而不作为宿主值(@6.3.5) 。
32833313 这同时简化动态 PTC(@5.10.4.2) 的实现。当前实现参见 TCO 临时对象管理(@7.10.7) 。
32843314 **注释**
32853315 对 NPL::TermReference 和可能使用 NPL::TermReference 访问项的相关操作详见项引用和项引用访问操作(@6.9.3) 。
@@ -3326,11 +3356,12 @@
33263356 特定的非平凡非正规表示(@6.3.9) 之一:
33273357 符合作为带有记号值的非空列表(@6.3.9.3) 。
33283358 无环非真列表(@6.3.9.1) 。
3329-这些条件可使用函数 NPL::IsCombiningTerm 判断。
3359+这些条件可使用函数 NPL::IsCombiningTerm 判断,以 NPL::AssertCombiningTerm 断言。后者对列表同时断言检查不具有粘滞位(@6.2.2) 。
33303360 函数 NPL::ClearCombiningTags 清除可能在规约合并项中遗留的标签而使之能作为一等对象的值的表示(@6.3) 。
33313361 **原理**
33323362 规约合并项支持求值算法(@4.4.1) 中函数合并(@4.5.3) 的实现。
33333363 对一般的规约合并,通常不直接蕴含 NPL::ClearCombiningTags 调用。对标签的维护通常延迟到正规化操作(@6.10.6.1) 实现。
3364+因为规约合并项的合并子和合并子参数都表示一等对象,规约合并项是列表时,不会出现粘滞位。作为非局部性的不变量,这应在整个规约中保持,因此仅在断言中检查而不在谓词中判断,以避免调用 NPL::IsCombiningTerm 时的不必要的开销。
33343365 **注释**
33353366 具有子项的枝节点满足 IsBranchedList(@6.2.3) 。
33363367 利用规约合并项的一个实例参见 NPLA1 求值算法(@7.8.2) 。
@@ -3368,7 +3399,7 @@
33683399 除非另行指定,提升项修改被替换的项的内容,其中子项、值数据成员和标签(@6.2.2) 都可能被修改。
33693400 **注释** 被提升的项往往被转移,因此一般地,需要在宿主语言中可修改(@4.1.4.2) 。若被提升的项表示对象语言的值,一般也需要在对象语言中可修改。
33703401 提升项可引入或消除(@6.4.6) 间接值(@6.4.3) 。
3371-提升项通过被引用的对象替换作为项的值数据成员的引用值而消除引用值(@5.8.3.4) ,但不保证修改其中引用的元数据(@6.8.3.1) 。
3402+提升项通过被引用的对象替换作为项的值数据成员的引用值(@6.3.3) 而消除引用值(@5.8.3.4) ,但不保证修改其中引用的元数据(@6.8.3.1) 。
33723403 提升项的求值结果(@6.10.1) 是消除引用值的结果。
33733404 提升操作辅助对项的操作,可用于实现规约函数(@6.10.5) ,包括以下各节中描述的 API 。其中:
33743405 这些函数至少的第一参数是规约函数的被规约项(@6.10.5) 引用参数,指定提升的目标,在提升时可被替换。
@@ -3408,9 +3439,9 @@
34083439 函数 NPL::LiftCollapsed
34093440 函数 NPL::MoveCollapsed
34103441 函数 NPL::LiftTermRef 提升项引用:提升项的内容为参数指定的项或引用持有者(@6.4.3.3) 构成的间接值。
3411-函数 NPL::LiftPropagatedReference 提升引用项(@6.3.3) 为引用项,实现不可修改标签的传播(@6.8.3.1) 。
3442+函数 NPL::LiftPropagatedReference 要求被提升的项是引用项(@6.3.3) ,提升引用项为引用项,实现不可修改标签的传播(@6.8.3.1) 。
34123443 函数 NPL::LiftToReference 提升项对象为引用。
3413-若项对象表示引用值则提升项,否则对 ValueObject 进行基于 ValueObject 所有权的检查(间接进行生存期检查)并取引用这个项的引用值。
3444+若项对象表示引用值(@6.3.3) 则提升项,否则对 ValueObject 进行基于 ValueObject 所有权的检查(间接进行生存期检查)并取引用这个项的引用值。
34143445 运行时进行的检查类似于强制 C++ 的一元 & 对表达式值类别(另见 @4.2.3 )的要求但更严格(尽管仍然不能保证避免未定义行为),避免临时对象(@5.8.5) 被保存为引用值。
34153446
34163447 @6.9.4.3 消除中间值的提升操作:
@@ -3671,7 +3702,7 @@
36713702 NPLA 提供只依赖项既有结构的项简单规约操作。这些操作是直接规约函数(@6.10.5.1) 。
36723703 函数 NPL::ReduceBranchToList 要求参数是枝节点(@6.2.1) ;移除第一个子项,剩余项作为列表的元素,并返回 ReductionStatus::Retained(@6.10.1) 。
36733704 函数 NPL::ReduceBranchToListValue 要求参数是枝节点;移除第一个子项,剩余项作为列表的元素,调用 NPL::LiftSubtermsToReturn(@6.9.4.2) 提升子项的值,并返回 ReductionStatus::Retained(@6.10.1) 。
3674-这保证最外的第一级引用被提升,不影响被引用项自身包含的引用。
3705+这保证最外的第一级引用项(@6.3.3) 被提升,不影响被引用项(@6.3.3) 自身包含的引用。
36753706 函数 NPL::ReduceForLiftedResult
36763707 函数 NPL::ReduceHeadEmptyList
36773708 函数 NPL::ReduceToList
@@ -4266,20 +4297,21 @@
42664297
42674298 @7.1.3 NPLA1 间接值(@6.4) 使用规则:
42684299 基本规则参见 NPLA 间接值规则(@6.4.6) 。
4269-除非另行指定,不在求值引入右值引用(@6.4.6.1) 。
4270-作为替代,可通过 NPLA API(如 NPL::IsBoundLValueTerm(@6.9.3) )间接判断绑定的对象的是否为右值引用。
4271-引入绑定的 API(@7.7.4) 可引入引用值(@6.3.3) 。已有的引用值的引用总是左值引用,否则是右值引用。
4272-除非另行指定,引用值的初始值(@5.8.2) 经过不超过一次引用折叠。
4273-除非另行指定,为在表达式的求值结果中取得折叠的引用值:
4274-当被引用对象(@4.2.3) 是被绑定对象时,引用值被折叠一次(@6.8.4.2) ;
4275-否则,引用值通过蕴含一次引用值提升转换(@5.8.4) 的方式被消除(@5.8.3.4) 一次。
4276-除非另行指定,违反不可修改引用引入的假定的修改操作引起类型错误(@4.7.4) 。
4300+除非另行指定:
4301+ 不在求值引入右值引用(@6.4.6.1) 。
4302+ **注释** 作为替代,可通过 NPLA API(如 NPL::IsBoundLValueTerm(@6.9.3) )间接判断绑定的对象的是否为右值引用。
4303+ **注释** 引入绑定的 API(@7.7.4) 可引入引用值(@6.3.3) 。已有的引用值的引用总是左值引用,否则是右值引用。
4304+ 引用值的初始值(@5.8.2) 经过不超过一次引用折叠。
4305+ 为在表达式的求值结果中取得折叠的引用值:
4306+ 当被引用对象(@4.2.3) 是被绑定对象(@6.11.1) 时,引用值被折叠一次(@6.8.4.2) 。
4307+ 否则,引用值通过蕴含一次引用值提升转换(@5.8.4) 的方式被消除(@5.8.3.4) 一次。
4308+ 违反不可修改引用引入的假定的修改操作引起类型错误(@4.7.4) 。
42774309 **原理**
42784310 访问不作为被绑定对象的子对象时,通常并非如宿主语言为支持推断参数类型的方式使用引用折叠,构造折叠的引用值默认不直接使用引用折叠(除临时对象标签外同 ISO C++ )的规则(@5.8.3.5) ,而直接由被引用对象确定。
42794311 对访问列表中的子项构成的子对象引用,这也和宿主语言的涉及成员访问的表达式类似(@6.4.6.1) :除以下不同:
42804312 元素是引用值时允许结果是唯一引用(而不是宿主语言的左值)。
4281- 这是因为在此唯一引用指定的是结果的值类型,而非类似宿主语言声明的右值引用类型。
4282- 元素具有临时对象标签时,允许标签被访问(类似宿主语言以成员访问表达式作为 decltype 的操作数的结果)。
4313+ 这是因为在此唯一引用指定的是结果的值的类型,而非类似宿主语言声明的右值引用类型。
4314+ 元素是临时对象的引用值时,允许临时对象标签(@6.2.2) 在访问中被区分(类似宿主语言以成员访问表达式作为 decltype 的操作数的结果)。
42834315 访问被绑定对象使用引用值也满足不可修改引用属性的传播性质(@5.8.3.3) ,避免被绑定对象被任意非预期地修改。
42844316 其它情形是否需要满足不可修改引用属性的传播性质和具体操作相关,因此不明确要求。
42854317 对违反不可修改引用引入的假定的修改操作要求错误避免隐式的 NPLA 未定义行为(@5.8.3.3) 。
@@ -4677,7 +4709,7 @@
46774709 不清理(@6.10.2.1) 参数;而即处理器中的第一个子项是已被清理的项(@7.2.1.1) ,可被实现使用。
46784710 调用处理器后:
46794711 根据处理器返回的规约结果进行正规化操作(@6.10.6.1) 。
4680-函数 A1::ReduceCombinedBranch 同 A1::ReduceCombined ,但调用前首先断言项满足 NPL::IsCombiningTerm 。
4712+函数 A1::ReduceCombinedBranch 同 A1::ReduceCombined ,但调用前首先断言项是规约合并项(@6.9.1) 。
46814713 函数 A1::ReduceCombinedReferent 同 A1::ReduceCombined ,但有以下不同:
46824714 使用第三参数指定的值指定表示处理器的项。
46834715 只支持项表示处理器右值(其它值都视为失败)。
@@ -4727,20 +4759,23 @@
47274759 @7.7.3 绑定操作:
47284760 绑定操作决定符号或具有符号的数据结构与项的对应关系,并初始化被绑定对象(@6.11.1) 而引入变量(@4.1) 。
47294761 作为函数语法的推广,两者分别由绑定操作使用形式参数(@4.5.2.1) 和操作数(@4.4.5.1) 指定。
4730-作为 TermNode ,操作数(@4.4.5.1) 的表示具有树的构造,即操作数树(@4.4.5.1) ,它可以具有子项。
4731-匹配的形式参数和操作数树对应也可具有树的构造,即形式参数树(formal parameter tree) 。
4762+作为 TermNode ,操作数(@4.4.5.1) 的表示具有树的构造,即操作数树(@4.4.5.1) ,它可以具有子项和值数据成员。
4763+为决定形式参数对应的操作数,形式参数和操作数树或子对象的结构被比较,即绑定匹配(match) 。匹配操作数树的形式参数对应也可具有树的构造,即形式参数树(formal parameter tree) 。
4764+被匹配的操作数是操作数树作为有序对(@6.3.9.1) 的元素。类似地,形式参数是形式参数树作为有序对的元素。
47324765 绑定操作初始化的变量的名称和值分别由形式参数树和操作数树决定。
47334766 绑定操作匹配待绑定的形式参数和操作数或它们的子项。
4767+NPLA 形式参数树具有特定的语法规则:叶节点为符号(@6.8.1) 、符号的引用值(@6.3.3) 或其它形式参数树构成的 DAG(@4.2.4) 。若构造的形式参数树不符合语法规则,引起错误(@2.5.2) ,不进行绑定。
47344768 成功的匹配决定形式参数对应的操作数或其子项,作为其实际参数(@4.5.3) 。这种对应关系是单射但不一定是满射,即匹配成功后,每个参数总存在对应的操作数或其子项,而操作数和子项允许不对应形式参数而被忽略。
4735-NPLA 形式参数树的叶节点为符号(@6.8.1) 或其引用值(@6.3.3) 。不符合要求的对象构造形式参数树时可引起错误(@2.5.2) 。
47364769 被绑定的项的操作数中的元素或值数据成员对应是项中的元素。
4737-形式参数树是 DAG 。
47384770 形式参数树中的引用值可能被间接访问一次,其余元素在匹配时被视为右值。
47394771 绑定操作的 API 详见绑定支持(@7.7.4) 。
47404772 绑定操作符合以下小节的绑定规则。其它具体行为参见对应 API (@7.7.4) 的详细描述。
47414773 **原理**
47424774 被绑定的参数可以作为函数的形式参数(@4.5.2.1) 。绑定操作对形式参数的处理也可以作为其它初始化变量的语法构造的基础。
47434775 **注释**
4776+形式参数树的节点可以是符号的引用值,但不支持多重引用(@5.8.3.2) 。
4777+关于对形式参数树的具体的语法要求,另见 `<ptree>(@9.2.2.1) 的定义。
4778+因为 NPLA1 支持的绑定构造都具有函数合并(@4.5.3) 的形式,操作数或其子项总能直接被作为函数的实际参数。
47444779 DAG 要求和 Kernel 类似,但通过无环列表(@6.2.1) 的性质蕴含而不需要另行限制。
47454780 和 Kernel 不同,操作数树同时支持作为引用的左值(@5.8.1) 和非引用的右值(@5.8.1) ,在实现上需要解析引用(类似 @6.9.2 的部分操作)。
47464781
@@ -4749,6 +4784,7 @@
47494784 绑定时不对形式参数对应的函数参数进行修改,所以不对形式参数除访问引用值外的间接处理。
47504785 绑定前不对形式参数或实际参数中的元素求值。
47514786 除非另行指定,不同变量的绑定初始化之间非决定性有序(@4.4.3) 。
4787+绑定初始化不修改(@4.1.4.2) 形式参数,但可能因初始化转移初值符而修改操作数(@5.8.2) 。
47524788 **注释**
47534789 初始化元素类似宿主语言的参数传递中可发生初始化。
47544790 若形式参数或实际参数可能由求值得到,需在匹配前另行处理。
@@ -4778,6 +4814,9 @@
47784814
47794815 @7.7.3.3 绑定匹配:
47804816 绑定匹配以一个形式参数树和操作数树作为输入,比较两者的结构并尝试关联形式参数树中的子项到操作数蕴含的对象,以创建变量绑定(@7.7.3.1) 。
4817+若绑定匹配成功,则可能进行符号为名称的对应变量的绑定初始化(@7.7.3.1) ;否则,绑定匹配失败,引起错误。
4818+绑定匹配确定每一个符号的过程先序(@4.4.3) 这个符号确定的变量的绑定初始化。
4819+绑定匹配不修改(@4.1.4.2) 形式参数,在匹配成功进行绑定初始化前不修改操作数。
47814820 使用如下算法搜索形式参数树和操作数的对应位置进行匹配:
47824821 初始化输入的形式参数树为当前形式参数,函数合并构成的操作数树作为当前操作数。
47834822 对每一对当前形式参数和当前操作数,比较两者(除非另行指定,操作数的值是引用值的,视为匹配被引用对象(@4.2.3) ,下同):
@@ -4794,7 +4833,7 @@
47944833 若形式参数不是 #ignore ,则尝试绑定操作数到以符号确定的名称的形式参数。
47954834 若符号以一个标记字符(sigil) 起始(详见引用标记字符(@7.7.3.4) ),则被绑定的变量名中去除此前缀。
47964835 若去除前缀得到的符号为空,则忽略操作数,不绑定对象。
4797-绑定匹配确定每一个符号的过程先序(@4.4.3) 这个符号确定的变量的绑定初始化。
4836+绑定匹配时不检查重复符号。若形式参数树中出现重复的符号,可被多次匹配成功。这可导致之后的绑定初始化中,只有其中某个未指定的绑定生效,其它绑定被覆盖。
47984837 **注释**
47994838 函数合并构成的操作数树包括作为合并子的第一个子项和作为操作数的之后余下的子项。
48004839 数据结构和匹配算法类似 Kernel 中用于 $define! 和 $vau 等操作子(@4.5.3.2) 的递归的匹配机制,但有以下不同(另见 @9.9.5 ):
@@ -4823,15 +4862,17 @@
48234862 当实际参数是引用值时,在可能对其它标签进行的处理(@7.7.3.5) 后,隐含一次引用折叠(@5.8.3.5) 。
48244863 存在标记字符 @ 时,绑定以实际参数作为被引用对象(@4.2.3) 的引用值,不论操作数的类型和值类别。
48254864 初始化引用值时,没有引用值的消除(@5.8.3.5) 。
4826-当前暂时不支持修改被绑定操作数。支持修改操作数的绑定的其它标记字符可能在未来支持。
4865+**注释**
4866+除复制消除(@7.7.3.5) 转移有序对操作数的子对象外,绑定时不修改被绑定操作数。
4867+支持修改操作数的绑定的其它标记字符可能在未来支持。
48274868
48284869 @7.7.3.5 非递归绑定:
48294870 非递归绑定在一次匹配之后创建对应的变量绑定。
48304871 合并使用或不使用引用标记字符(@7.7.3.4) 的情形,非结尾序列(@7.7.3.3) 的单一参数对象的绑定初始化(@7.7.3.1) 包含以下过程:
4831- 若不存在绑定标记字符 @ ,则:
4872+ 若不存在标记字符 @ ,则:
48324873 若操作数为可转移的(@5.8.3.6) 对象的引用值,则被绑定对象是按以下规则初始化的蕴含隐含的引用折叠(@7.7.3.4) 的引用值:
48334874 存在标记字符时,使用引用推断规则(@7.7.3.4) ,被绑定对象是操作数直接初始化的项引用,其标签由操作数的(引用值)的标签决定:
4834- 当有标记字符 & 、绑定非结尾列表且作为操作数的引用值的标签包含唯一引用标签(@6.2.2) 时,其中包含绑定临时对象标签(@7.7.3.2) 。
4875+ 当存在标记字符 & 、绑定非结尾列表且作为操作数的引用值的标签包含唯一引用标签(@6.2.2) 时,其中包含绑定临时对象标签(@7.7.3.2) 。
48354876 **注释** 使用 % 可避免操作数中的唯一引用标签在被绑定对象中蕴含临时对象标签的行为。
48364877 否则,被绑定对象的标签和作为操作数的引用值的标签相同。
48374878 否则,被绑定对象是操作数复制初始化(复制或转移)的值。
@@ -4850,7 +4891,7 @@
48504891 除绑定临时对象(@7.7.3.2) 外,若绑定操作数的初始化的引用值时实际引用临时对象,则行为未定义。
48514892 **注释** 不和宿主语言一样可能延长右值类类型子对象的生存期。)
48524893 具有引用标记字符的形式参数支持引入引用值并支持绑定引入临时对象的实际参数(@5.8.5) 。
4853-仅在绑定临时对象到引用时使用复制消除(@5.8.5.3) 。
4894+仅在绑定临时对象且操作数可转移或使用标记字符 % 时使用复制消除。
48544895 **原理**
48554896 绑定的默认行为对引用值特殊处理,是为了满足 G1b(@1.5.5.1) ,而不是像某些语言(如 ISO C 和 [Rust] )仅通过内建的机制提供特定左值上下文(lvalue context) 。
48564897 绑定的默认行为不使用析构性转移(@6.3.6) 的操作(类似 [Rust] 的设计),原因是考虑到绑定的副作用影响操作数(即便因为对象被销毁而不一定是修改操作)和破坏幂等性(@4.1) (特别是指定过程调用的形式参数时,参见过程抽象(@8.4.5) )违反易预测性原则(@1.5.5.2) 。
@@ -4871,6 +4912,29 @@
48714912 但是这仍然存在限制:因为没有跨过程传递的状态支持,明确具体类型还是需要程序显式指定 std::forward 的类型参数(或者宏),而不是 C++ 函数(应用子)的方式实现。
48724913 通过唯一引用标签仍可区分一个具有临时对象标签的引用值以消亡值还是纯右值初始化。
48734914 可使用不同的引用标记字符避免使引用值引入非预期的引用标签。
4915+绑定结尾序列和非结尾序列的非递归绑定规则略有不同。
4916+ 特别地,除非被绑定对象是引用值,引用标记字符(不论是否存在)同时被作用到作为一等对象的元素上。这是因为:
4917+ 此时,需要把操作数作为一等对象进行分解,使用引用标记字符或者不使用引用标记字符不破坏其它语义规则。
4918+ 和非引用结尾序列相比,使有序对的两个元素在初始化时的规则不同,但这具有合理性,因为:
4919+ 有序对作为(非真)列表时,地位不是相同的。
4920+ 有序对的元素在 NPLA 对象表示中即已不对称,地位不可交换。
4921+ 这种设计简化了一些重要的派生实现,例如 list 应用子(@11.4.1) 。
4922+ 若不依赖无引用标记字符影响被初始化的元素的规则,使用基本派生操作(@11.4.1) 中在 list 前定义的操作,list 的派生近似(和内部表示实现细节相关仍不确保完全正确):
4923+ $def! list wrap ($vau% (.x) #ignore
4924+ ($vau% (x y) d (wrap ($vau% #ignore #ignore (eval% (move! y) d)))
4925+ (eval (move! x) d))
4926+ ($def! lacc wrap ($vau% (&x) #ignore
4927+ ($if (pair? x)
4928+ (wrap ($vau% ((%x .%xs)) #ignore cons (idv (expire x)) (lacc (move! xs)))) idv) x))
4929+ (lacc ((wrap ($vau ((.@xs)) #ignore xs)) x)));
4930+ 而允许使用这些规则时,可简化为可移植的派生:
4931+ $def! list wrap ($vau (.x) #ignore move! x);
4932+ 为创建子对象引用时避免被引用对象的复制,不复制被引用对象的子项(即便被引用对象可能具有非正规表示(@6.3.9) ),且使用非引用值间接值作为被绑定对象的值数据成员。
4933+ 和引用值的间接访问可被配置运行时检查(@6.1.2.1) 不同,对通过非引用值间接值的访问不被检查(@6.4.6.2) 。但和引用值的间接访问类似,这种情形已违反内存安全(@5.6.3) ,且可能引起宿主语言的未定义行为(@5.4) 。因此,不另行保存子项。
4934+**注释**
4935+引用折叠的结果满足不可修改引用属性的传播性质(@5.8.3.3) 。其它情形也应满足 NPLA1 间接值使用规则(@7.1.3) 。因此,仅有使用标记字符 % 进行消除引用时,被消除的引用值的不可修改属性被忽略。
4936+绑定临时对象外不和 [ISO C++] 一样可能延长右值类类型子对象的生存期(@5.6.6) 。
4937+具有引用标记字符的形式参数支持引入引用值并支持绑定引入临时对象的实际参数(@5.8.5) 。
48744938
48754939 @7.7.3.6 递归绑定:
48764940 形式参数树子项和操作数树的子项成功匹配(@7.7.3.3) 后绑定子项。
@@ -4930,7 +4994,7 @@
49304994 **注释** 另见续延名称(@7.11.7) 和解释(@8.6.2) 。
49314995
49324996 @7.8 REPL API :
4933-NPLA1 提供 API 通过解释器的各个子模块组装 REPL(read-eval-print loop) 的交互式界面。
4997+NPLA1 提供 API 通过解释器的各个模块的组件组装 REPL(read-eval-print loop) 的交互式界面。
49344998 函数 A1::SetupDefaultInterpretation 初始化默认解释,包括一般事件处理例程。
49354999 默认解释初始化符合主规约函数实现对其中处理器的约定(@7.4.4) 。
49365000 函数 A1::SetupTailContext
@@ -5431,7 +5495,7 @@
54315495 @7.11.5 资源回收限制:
54325496 当前 TCO 操作压缩不保证回收(通过 #ignore 指定)被忽略外的动态环境(@4.6.1.2) 。
54335497 注意 [RnRK] §3.3 仅保证的应用子调用是尾上下文(@4.4.8) ,使用任意环境作为动态环境的操作子调用时不需要满足 PTC 。
5434-这可能有误,因为造成应用子的底层合并子和不作为底层操作子的其它操作子不一致,并且和这里的操作压缩限制一样,实际无法总是保证具有动态环境的应用子在动态环境被用用时能满足的调用 PTC 。
5498+这可能有误,因为造成应用子的底层合并子(@4.5.3.2) 和不作为底层操作子的其它操作子不一致,并且和这里的操作压缩限制一样,实际无法总是保证具有动态环境的应用子在动态环境被用用时能满足的调用 PTC 。
54355499 **注释**
54365500 事实上,Kernel 语言的实际实现一般无法保证回收非 #ignore 的动态环境,即便动态环境只被用于尾调用中。
54375501 上述无法 TCO 的情形在其它语言中因为可达性分析等可能具有实现缺陷也不会释放存储,如以下 Kernel 程序在 klisp 中实测不支持 PTC :
@@ -5522,7 +5586,7 @@
55225586 实现应保证以上差异不影响满足对象语言关于特定操作的语义要求。
55235587 以上下文处理器调用的操作应满足上下文需要的状态:
55245588 在进入调用前已使用 A1::ReduceCombined 确保存在 TCO 动作(@7.10.3) ,以允许尾上下文(@4.4.5) 求值。
5525-基本派生操作包括 Forms::First(@8.4.3) 等针对特定类型的操作。关于不同类型的其它综合操作参见 @8.4.9 。
5589+基本派生操作包括 Forms::First(@8.4.3) 等针对特定类型的操作。关于不同类型的其它综合操作参见通用基本派生操作(@8.4.9) 。
55265590 A1::Forms 的公开 API 提供合并子的本机实现时确保调用这些合并子经过遍处理器依赖的检查(@7.6.1.3) 。这可使用如保留操作(@7.6.3.1) 实现。
55275591 这些 API 不被 A1::Forms 以外的 API 及实现依赖,且符合本节的以下约定。
55285592 除非另行指定,这些形式不是特殊形式(@5.2) ,一般作为按值传递(@4.4.6.5) 的函数(@4.5.2) ;其中的值对象(@6.1.7) 表示引用时,传递引用(@4.4.6.5) ;表示访问的值不被修改时,是否传递引用未指定。
@@ -5797,6 +5861,7 @@
57975861 Forms 提供以下在对象语言中实现一等续延(@4.5.3.3) 相关操作:
57985862 Forms::Call1CC
57995863 Forms::ContinuationToApplicative
5864+一等续延的实现依赖实现选项 NPL_Impl_NPLA1_Enable_Thunked 启用异步规约(@7.9.2) ,否则应用续延的行为未定义。
58005865
58015866 @8.4.11 外部调用:
58025867 Forms 提供以下在对象语言中调用实现环境外部功能的函数:
@@ -5984,13 +6049,16 @@
59846049 规约操作中项的约束通过以 <> 中的同类名称表示。
59856050 为区分同类约束的不同项,约束的名称后(在 > 之前)的可带有以 1 起始的正整数序数。除非另行指定,这些序数仅用于区分不同的同类约束项,无其它附加含义。
59866051 本节描述的项是被用于求值(参见求值算法(@9.7.1) )的项或它们的直接文法组合。前者应能涵盖原子表达式(@3.4.2) 、其求值结果以及预期在对象语言中实现 @9.7.1 所需的 NPLA1 用户程序(@9.1) 构造。
5987-库可参照本节的方式约定通过库引入的项的文法。
5988-除非另行指定,对不确定具体项内容的对应要求同时适用于本节中和这些库中引入的项。
6052+库可参照本节的方式约定通过项的文法,以支持仅在特定库使用的操作数。
6053+除非另行指定,本节的对应要求同时适用于本节中和这些库中引入的项。
59896054
59906055 @9.2.1 元文法基本约定:
59916056 ... :Kleene 星号,重复之前修饰的项 0 次或多次。
59926057 + :重复之前修饰的项 1 次或多次。
59936058 ? :重复之前修饰的项 0 次或 1 次。
6059+**注释**
6060+... 一般在结尾出现,表示元素构成列表。
6061+和 [RnRK] 不同,不使用 . 分隔有序对,不使用元素名称的复数表示列表。
59946062
59956063 @9.2.2 实体元素文法约定:
59966064 指定具名的函数(@4.5.2) 的文法中,第一项以符号(@9.9.2) 的形式在所在的环境中提供,指定求值结果指称为合并子(@4.5.3.2) 的函数名称;
@@ -6011,7 +6079,7 @@
60116079 <symbol> :符号。
60126080 内部使用和 <string>(@9.2.2.2) 一一对应的表示,不提供符号和外部表示的其它映射关系。
60136081 <symbols> :元素为 <symbol> 的列表,形式为 (<symbol>...) 。
6014-<eformal> :表示可选提供的环境名称的 <symbol> 或 #ignore 。
6082+<eformal> :表示可选提供的环境名称的 <symbol> 或 #ignore ,或这些值的引用值。
60156083 **注释** 通常为动态环境。
60166084 <expression> :待求值的表达式。
60176085 **注释** 这是 NPL 语法(@3.4.2) 的直接实现。
@@ -6063,7 +6131,7 @@
60636131 <applicative> :应用子(@4.5.3.2) 。
60646132 <predicate> :谓词,是应用操作数的求值结果的值为 <test> 的 <applicative> 。通常实现结果是 <boolean> 的纯求值(@4.4.4) 。
60656133 <environment> :一等环境(@5.7) 。
6066-<parent> :指定环境的父环境(@5.7) 的值,包括 <environment> 或元素为 <environment> 的 <list> 。
6134+<parent> :指定环境的父环境(@5.7) 的值,包括环境引用、元素是环境引用的 <list> 或以环境引用的 <list> 作为被引用对象的 <reference> ,其中环境引用是 <environment> 或以 <environment> 作为被引用对象的 <reference> 。
60676135 <string> :字符串。宿主值类型为 string(@6.8.1) 。
60686136 字符串是包括数据字面量(@5.2.4) 求值的结果类型,以 string 类型表示,编码和表示要求同 YFramework 默认约定([Documentation::YFramework @@3.3.1]) 。
60696137 **注释** 对外部来源的 <string> 的值不要求检查,直接视为 NTCTS(@7.1.1) 。
@@ -6077,6 +6145,7 @@
60776145 非空真列表是有序对的子类型。
60786146
60796147 @9.2.2.4 文法形式补充约定:
6148+除非另行指定,指定应用子的操作形式也适用其底层合并子(@4.5.3.2) 。
60806149 除非另行指定,以 <symbols> 指定的值被作为 <definiend> 或 <formals> 使用时不引起错误。注意 <symbols> 在被其它上下文使用时仍可能引起错误。
60816150 和 [RnRK] 不同,<symbols> 形式的符号列表在绑定变量名时支持引用标记字符 & 和 %(@7.7.3.4) 。符号作为被绑定的初值符时,移除符号中发现的这些引用标记字符。
60826151 和 [RnRK] 不同,<definiend> 和 <formals> 不要求重复符号检查。另见 @7.7.3 。
@@ -6086,12 +6155,15 @@
60866155 这实质等价使用 [Shu09] 中的记法,即 <formals> 用于除和 [Shu09] 的 $define! 类似外的所有操作(包括 $set! 和 $let 等,而不论是否对应 <body> )。这些上下文中总是隐含了上述的可派生实现的要求。
60876156 和 [RnRK] 不同,<body> 不蕴含顺序求值子项。
60886157 为对 <environment> 和 <parent> 进行类型检查(@9.5.4.1) 取得环境强引用(@6.11.1) 时,可附带进行内部的检查(@9.5.4) 确保 shared_ptr<Environment>(@6.8.2) 类型的宿主值非空。
6089-**注释**
6090-和 [RnRK] 不同,NPLA1 的符号可通过代码字面量(@5.2.4) 求值得到。
60916158 **原理**
60926159 和传统 Lisp 方言(包括 [RnRS] 和 [RnRK] )的函数体不同,<body> 的各个表达式之间不蕴含顺序求值。
60936160 因此,和 [RnRK] 不同,$vau 不需要在基本操作之后再次派生。这使操作的功能更加正交。
60946161 <body> 不蕴含顺序求值也允许 <body> 中的表达式被整体求值(@9.2.2.1) 。
6162+**注释**
6163+和 [RnRK] 类似,个别的应用子和底层合并子接受不同形式的参数(尽管 [RnRK] 没有约定),例如:
6164+ [RnRK] 的 list 接受列表,但底层合并子也接受和非列表对象构成的有序对。
6165+ NPLA1 对应的函数参见 list 和 list%(@11.4.1) 。
6166+和 [RnRK] 不同,NPLA1 的符号可通过代码字面量(@5.2.4) 求值得到。
60956167
60966168 @9.3 对象语言语法:
60976169 基于 NPLA 基本语法约定参见 NPLA 约定(@5.2) 。
@@ -6433,6 +6505,7 @@
64336505 实现 PTC 时被规约时替换结果的清理(@6.4.6) 若实现支持 TCO(@7.4) 且没有实现保存未绑定操作数引起这种情形。
64346506 当前通过参考实现环境(@10) 引入的合并子已经支持了保存操作数,但若互操作(@5.3) 没有保存操作数,则可能产生问题。
64356507 应注意合并子的参数绑定引用值(@7.7.3) 在同一个尾上下文求值引起清理导致悬空引用(@9.4.3.2) 破坏内存安全(@9.4) 。
6508+**注释**
64366509 这里的求值典型地可通过显式求值引入。具体地,这主要包含使用引用值作为函数 eval 或 eval%(@11.3.7) 的参数的进行函数应用表达式求值的方式。
64376510 对合并子的直接的函数调用求值较不容易引起这种情形,因为 <body> 内使用的参数是被绑定的,其中临时对象(@5.8.5) 即便传递引用也会被转移值(@7.7.3) 。悬空引用通过其它方式(如在合并子的动态环境内显式求值)才被直接引入。
64386511 考虑在调用前使用总是不保留引用值(@10.4.3) 的 list 和 list* 而不是保留引用值(@10.4.3) 的 list% 和 list*%(@11.4.1) ,或单独调用 idv(@11.4.1) 提升被传递项中的值避免此类问题。
@@ -6525,7 +6598,7 @@
65256598 复制赋值在自赋值时的源操作数复制仍可能出错。使用基本提升操作(@6.9.4.1) 实现时,一般使用 NPL::LiftTermOrCopy 而不是检查自赋值的 NPL::LiftOtherOrCopy 。
65266599 类似宿主语言,除非另行指定,赋值操作不保留源操作数的值类别(@9.7.2) 和可修改性。
65276600 **注释**
6528-作为推论,赋值不保证子对象(@9.8.2) 的同一性不被改变;子对象的引用仍可能被赋值无效化(@9.8.6) 。
6601+作为推论,赋值不保证子对象的同一性不被改变;子对象的引用仍可能被赋值无效化(@9.8.6) 。
65296602 通过对象的子对象引用(@9.8.2) 修改对象的子对象不保证作用在对象上。
65306603
65316604 @9.8.3.2 转移:
@@ -6534,6 +6607,7 @@
65346607 **注释** 例如,使用唯一引用(@6.2.2) 初始化对象,可转移被引用对象对应的项(@6.3.6) 。
65356608 和宿主实现不同,当前实现不直接通过初始化转移宿主对象(@5.8.2.3) 。
65366609 被转移的对象在转移后具有有效但未指定(@5.6.2) 的状态。
6610+当前实现中,当项被转移后,表示的值为 () 。这和返回值转换(@6.4.6.4) 等引入实质化临时对象时可能具有的转移(@5.8.5) 的效果(仅在互操作时可见)不保证相同。
65376611 **注释**
65386612 作为推论,通过转移对象的子对象引用(@9.8.2) 修改对象的子对象不保证作用在对象上。但和其它修改不同,这同时是被转移对象后的状态的规则覆盖。
65396613
@@ -6560,7 +6634,7 @@
65606634 被引用的对象存储期已结束(此时引用值是悬空引用(@9.4.3.2) );
65616635 对象被除通过重绑定(@9.9.3.7) 、赋值(@9.8.3.1) 和另行指定的情形以外的方式修改(@9.8.3) ,而引起对象同一性的改变。
65626636 **注释**
6563-对项的重绑定或赋值仍可能因为对子项的修改蕴含被替换的对象的销毁,引起子对象的生存期结束,而使其表示的对象的引用值无效化。
6637+对项的重绑定或赋值仍可能因为对子项的修改蕴含被替换的对象的销毁,引起子对象(@9.8.2) 的生存期(@5.6.6) 结束,而使其表示的对象的引用值无效化。
65646638
65656639 @9.8.7 类型分类:
65666640 和 Kernel 不同,NPLA1 不要求支持任意类型的集合表示(@4.7) 不相交,即分区(partition) 。
@@ -6589,7 +6663,11 @@
65896663 @9.9.1.1 循环引用:
65906664 除非另行指定(如强递归绑定(@9.7.3.1) ),对象中的循环引用引起 NPLA 未定义行为(@5.4) 。
65916665 **注释**
6592-典型实现中,循环引用可引起资源泄漏如内存泄漏(@5.6.4) ;无条件遍历访问循环引用子对象(@9.8.2) 的求值不具有终止保证(@4.8.2) 。
6666+循环引用破坏一些实现的假设而引起非预期的访问。
6667+不显式访问环境的操作也可能引入循环引用(而引起未定义行为),例如:
6668+$def! l ();
6669+$def! l list% l;
6670+典型实现中,具有所有权的循环引用可引起资源泄漏如内存泄漏(@5.6.4) ;无条件遍历访问循环引用子对象(@9.8.2) 的求值不具有终止保证(@4.8.2) 。
65936671 例如 NPLA1 参考实现环境(@10) 下求值以下表达式:
65946672 $let ((nenv () make-environment)) $set! nenv self nenv
65956673 可引起被捕获的环境中存储的对象无法释放。
@@ -6694,7 +6772,7 @@
66946772 通过引用值间接访问 e 中绑定的对象时绑定保持有效(蕴含不被移除或重绑定),保持被绑定对象的生存期和 e 对其的所有权。
66956773 这避免因为上述访问违反内存安全(@5.6.3) 而引起 NPLA 未定义行为。
66966774 **注释**
6697-类似赋值(@9.8.3.1) ,重绑定不保证子对象(@9.8.2) 的同一性不被改变;子对象的引用仍可能被重绑定无效化(@9.8.6) 。
6775+类似赋值(@9.8.3.1) ,重绑定不保证子对象的同一性不被改变;子对象的引用仍可能被重绑定无效化(@9.8.6) 。
66986776
66996777 @9.9.3.8 被绑定对象的值和可观察行为(@4.1.3) :
67006778 任意隐藏环境(@9.9.3.1) 的 e 的任意同一(@9.8.1) 被绑定对象 o 应满足以下的值稳定性:
@@ -6715,7 +6793,7 @@
67156793 当前 NPLA1 对象语言不提供在已有环境撤销冻结或在冻结的环境中添加、移除绑定或重绑定(@9.9.3.7) 的方法。
67166794 若程序中使用其它方法(附加初始化或提供本机实现操作)撤销冻结或在冻结的环境中添加、移除绑定或重绑定而使对象语言安全性保证(@9.4.6) 失效,这种方法应由派生实现定义,否则程序行为未定义。
67176795 **原理**
6718-环境的冻结操作类似 [ECMAScript] 的对象的冻结操作。类似地,冻结环境不会冻结其中的变量绑定中可能存在的环境子对象。
6796+环境的冻结操作类似 [ECMAScript] 的对象的冻结操作。类似地,冻结环境不会冻结其中的变量绑定中可能存在的环境子对象(@9.9.3) 。
67196797 同 [RnRK] ,环境中的绑定不确保可完全枚举(参见其中 $bind? 的原理),所以和 ECMAScript 的惯用法不同,一般无法在实用上确保通过嵌套遍历环境子对象的实现环境的深度冻结。
67206798 和 [RnRS] 及 [RnRK] 不同,NPLA1 对象语言不仅有 set-car! 和 set-cdr! 这类针对列表对象的改变操作(@4.1.4.2) ,还有修改一等对象引用值的被引用对象的操作(参见列表基本操作(@11.3.5) 和基本派生操作(@11.4.1) )。
67216799 这意味着创建标准环境(@11.4.1) 不仅依赖隐藏环境中的绑定有效稳定性(@9.9.3.7) ,还依赖值稳定性(@9.9.3.8) 。
@@ -6757,7 +6835,7 @@
67576835
67586836 @9.9.5 合并子:
67596837 Kernel 的合并子对应 NPL 的真合并子(@4.5.3.2) 。
6760-为维护语言规则的简单性(@1.5.3) ,除非另行指定(如强递归绑定(@9.7.3.1) ),对象语言中的所有合并子都是真合并子。
6838+除非另行指定(如强递归绑定(@9.7.3.1) ),对象语言中的所有合并子都是真合并子。
67616839 尽管没有要求(@4.2.6) ,这种规约也更符合 [RnRK] 原则 G1b ;同时,这易于移植 Kernel 代码。
67626840 NPLA1 对象语言不提供其它合并子的普遍操作(不满足类似 G1b 的原则(@1.5.5.1) ),但 NPLA1 API 可支持其它合并子。
67636841 可能直接引入非真合并子的 API 包括项变换 API (@7.6.3) 。
@@ -6766,9 +6844,12 @@
67666844 在不出错时行为和不使用包装数而直接使用嵌套子对象实现的行为完全一致,但在到达实现支持的最大包装数时继续包装即包装数溢出(wrapping count overflow) ,行为可能不相同:
67676845 若某个操作使合并子超出上限,则符合非宿主资源耗尽的错误条件(@9.5.3) 。
67686846 实现支持的最大包装数应满足:若发生包装数溢出,则直接创建和包装数相同个数的合并子符合宿主资源耗尽的错误条件(@9.5.3) 。
6847+**原理**
6848+为可修改性(@1.5.3.2) ,允许非真合并子。这可在互操作(@5.3) 中表示类似合并子但在语言中不可见的非一等对象。
6849+为维护语言规则的简单性(@1.5.3.1) ,合并子默认是真合并子。
67696850 **注释**
67706851 对最大包装数的要求需要实现支持包装数是能和宿主资源的空间相较规模的值,这保证使用包装数的实现的空间效率不弱于不使用包装数而直接分配合并子包装的实现。
6771-这也表示通常用户程序的操作不会发生包装数溢出:若包装操作的次数导致包装数溢出,则直接分配合并子的替代操作也应由于宿主资源耗尽而失败。
6852+这也表示通常用户程序(@9.1) 的操作不会发生包装数溢出:若包装操作的次数导致包装数溢出,则直接分配合并子的替代操作也应由于宿主资源耗尽而失败。
67726853
67736854 @9.9.6 数值:
67746855 数值支持(@5.2.2) 的实现兼容 NPLA 数学功能(@6.14) 。
@@ -6848,11 +6929,13 @@
68486929 **注释** 用户程序可导入环境中的符号使用库中的绑定。
68496930
68506931 @10.2 模块:
6851-同 [RnRK] ,以绑定提供的语言特性被分组归类为模块(@1.5.6.4) 。
6932+NPLA1 以绑定提供的语言特性被分组归类为模块(@1.5.6.4) 。
6933+**注释** 同 [RnRK] 。
68526934 模块的源(source) 提供特性的实现,可以是本机实现或者 NPLA1 程序。对应的模块分别是本机模块和源程序(@1.2.4) 模块。
68536935 模块的源可以是实现内建的,或位于实现环境提供的外部资源(如文件系统)。
6854-因为模块以绑定的集合的形式提供,需被包含在可访问的环境,或包含环境作为子对象的其它对象中。
6936+因为模块以绑定的集合的形式提供,需被包含在可访问的环境,或包含环境作为子对象(@9.8.2) 的其它对象中。
68556937 以环境对象作为模块的源的模块化方式称为环境作为模块(environment as module) 。[RnRK] 的 get-module 的结果和参考实现扩展环境(@12) 的模块是这种方式的例子。
6938+模块可能包含子模块(submodule) 提供其特性子集。以环境作为模块时,环境子对象(@9.9.3) 可作为子模块。
68566939 从模块的源得到提供一个模块的所有绑定集合的环境对象的过程称为模块的加载(loading) 。
68576940 模块加载可能失败。失败的模块加载引起错误(@9.5.1) 。
68586941 根环境加载的失败不被直接依赖这些环境的 NPLA1 用户程序处理(而视为实现初始化的运行时错误)。
@@ -6878,9 +6961,11 @@
68786961 虽然 NPLA1 标准库不作为接口保证提供这些源,这里的假定和 ISO C++ [using.headers] 对引入标准库头的程序位置的限制类似:语言实现能有效地假定源程序中引入标准库头的上下文,因此标准库中的名称具有预期的含义。
68796962
68806963 @10.2.2 模块稳定性:
6881-同 [RnRK] 的 get-module 的约定,提供模块绑定的环境依赖已知来源的绑定而确保稳定(@9.9.3) 。
6964+提供模块绑定的环境依赖已知来源的绑定而确保稳定(@9.9.3) 。
6965+**注释** 同 [RnRK] 的 get-module 的约定。
68826966 对标准库模块,这一般表示其中的特性不能依赖用户程序运行时的非特定的当前环境,而可依赖从基础环境(@10.1) 及从基础环境派生的新环境(@9.9.3) 。
6883-除非另行指定,模块中的特性依赖提供模块绑定的环境的生存期。例如,其中的合并子(@9.9.5) 可具有静态环境是上述环境的子对象的合并子的实现。
6967+除非另行指定,模块中的特性依赖提供模块绑定的环境的生存期。
6968+**注释** 例如,其中的合并子(@9.9.5) 可具有静态环境是上述环境的子对象(@9.8.2) 的合并子的实现。
68846969 除非另行指定,标准库实现应确保其中的模块在程序的生存期中可用。这一般要求标准库实现在初始化后保存环境强引用(@6.11.1) 。
68856970 用户程序应自行保证加载的其它模块具有足够的生存期,以避免访问悬空引用(@9.4.3.2) 导致的未定义行为,特别是使用在环境中保留引用值的操作(@10.8.4) 的情形。
68866971 另见可能破坏环境稳定性的操作(@10.8.7) 。
@@ -6896,9 +6981,9 @@
68966981
68976982 @10.3.1 库接口实体:
68986983 按实体区分,NPLA1 的库特性有两类:对象和操作(@4.4.5.1) 。
6899-可实现的操作以函数(@4.5.2) 形式提供,可以是本机实现(@5.3) 的宿主语言函数或由现有操作派生的合并子(@9.9.5) 。
6984+对象语言中可实现的操作以函数(@4.5.2) 形式提供,可以是本机实现(@5.3) 的宿主语言函数或由现有操作派生的合并子(@9.9.5) 。
69006985 除此之外,派生实现可指定对操作提供对应的非常规函数(@10.6.5) 。
6901-操作的结果是对应的函数调用的求值结果,即函数值(@4.5.3.1) 。
6986+操作的结果(@4.4.5.1) 是对应的函数调用的求值结果,即函数值(@4.5.3.1) ;操作的作用即函数调用的作用(@4.4.5.1) 。
69026987 根据操作的功能描述,对应的函数可能具有非正常的控制条件(@4.8) 。此时,函数调用不取得函数值,操作不具有结果。
69036988 除非另行指定,函数调用时具有的错误条件(@9.5.3) 是非正常的控制条件;其中,以异常(@9.5.2) 实现错误条件的情形具有异常条件(@4.8.1) 。
69046989 特定的操作约定对应的函数是终止函数(@4.8.2) 或全函数(@4.8.2) ;这不适用于错误条件。
@@ -6910,6 +6995,7 @@
69106995 这些操作中的大部分具有特定的名称。这些名称符合函数名称约定(@10.7) ;其分类详见函数分类(@11.2) 。
69116996 其它操作不具有特定名称,可由上述操作间接地提供,如蕴含在某些操作涉及的函数值(@4.5.3) 中。
69126997 **注释**
6998+在对象语言中不能直接表达的操作不能作为库特性,这些操作不对应库接口实体,其结果和作用仍照更一般的规则(@4.4.5.1) 处理。
69136999 渐进复杂度常以 O 记号指定上界。
69147000 若函数调用总是取得值,指定复杂度的函数同时是全函数。
69157001
@@ -6947,7 +7033,7 @@
69477033 此处的左值引用和宿主语言中的( const 非 volatile )左值作用类似。
69487034 这等价隐含无副作用的左值到右值转换(@5.8.4) 。
69497035 **注释**
6950-左值到右值转换只作用在间接值上,不蕴含对关联对象(@6.4.3) 的子对象的转换。
7036+左值到右值转换只作用在间接值上,不蕴含对关联对象(@6.4.3) 的子对象(@9.8.2) 的转换。
69517037 例如,对列表元素是引用值的情形,提升项不是递归的(@6.9.4.3)(另见参数绑定(@8.4.5.3) 实现中的类似说明)。
69527038 另见实际参数约定(@10.6.3) 和函数值转发(@10.5.4) 。
69537039
@@ -6962,14 +7048,17 @@
69627048 @10.4.3 保留引用值:
69637049 保留间接值,包括直接保留间接值和间接保留间接值(@9.4.4.2),适用间接值是引用值的情形,对应地称为保留引用值、直接保留引用值和间接保留引用值。
69647050 除非另行指定,被保留的引用值(@9.4.4) 不被折叠(@5.8.3.5) 。
6965-**注释** 通过要求引用折叠,可保证不引入引用的引用值。
7051+**注释** 要求引用折叠可避免引入非预期的引用的引用值。
69667052 函数是否保留引用值以及保留引用值是否被折叠的要求,参见常规函数约定(@10.6) 、函数名称约定(@10.7) 和 NPLA1 参考实现环境(@10) 中的函数名称的约定(@11.2.2) 。
69677053 考虑内存安全时,因无法保证如引用值通过关联的环境(@6.8.3.1) 追溯被引用对象类似的机制可用,环境引用(@6.4.3.1) 外的非引用值间接值(@6.4.6.2) 视为不具有内存安全保证(@9.4.3) 。
6968-间接保留引用值可包含部分直接转发引用值(@10.5) 的情形。包含这种情形的操作不因此被视为直接保留引用值,即便部分引用通过直接转发引用值被保留。这保证以上两个子类不相交。
7054+间接保留引用值可包含部分直接转发引用值(@10.5.2) 的情形。包含这种情形的操作不因此被视为直接保留引用值,即便部分引用通过直接转发引用值被保留。这保证以上两个子类不相交。
69697055 直接保留引用值覆盖常规函数约定的实际参数约定(@10.6.3) ,指定参数不隐含左值到右值转换(@5.8.4) ,可按引用值直接访问。
7056+**原理**
7057+被保留的引用值可能逃逸或不逃逸而通常不能直接证明具有内存安全保证(@9.4) 。
69707058
69717059 @10.4.4 保留环境引用:
69727060 保留间接值适用环境引用(@9.4.4) 。
7061+**注释**
69737062 和保留引用值(@10.4.3) 的情形不同,因为只允许通过环境引用在对象语言中访问环境对象及其子对象(@9.4.2) ,访问环境但不保留环境引用的操作只可能在(不保证内存安全的)互操作(@9.4.1) 中出现。
69747063
69757064 @10.5 函数参数和函数值传递(@4.4.6.5) 约定:
@@ -6981,7 +7070,9 @@
69817070 这类似宿主语言中直接使用对象类型的形式参数。
69827071
69837072 @10.5.2 函数参数转发:
6984-一些函数的部分参数也可不进行左值到右值转换(@5.8.4) 。
7073+一些求值为引用值的函数的部分实际参数被保留,而不进行左值到右值转换(@5.8.4)。
7074+这些值以保留值类别不变的形式被直接作为操作数,用于调用其它合并子。这种参数被转发(forward) 。
7075+**注释**
69857076 这些参数的转发类似绑定构造支持的参数转发(@9.7.3.2) 。
69867077 参数转发的实现可判断值类别(@9.7.3) 后分别对传递非引用值(@10.5.1) 或直接传递引用值提供实现,或直接使用绑定构造。前者支持本机实现。
69877078
@@ -6993,16 +7084,18 @@
69937084
69947085 @10.5.4 函数值转发:
69957086 一些其它保留引用值的操作中,引用值来自参数,且难以通过自身的逻辑单独决定可否安全地直接返回引用值。
6996-此时,在返回之前根据特定参数是否为引用值,可选地转换结果以确定是否保留引用值,即进行转发。
6997-特定的显式转发操作转发临时对象(@5.8.5) 的引用值(@6.3.3) 使临时对象被转移,以转发的值作为返回值,可不同于使用返回值转换(@6.4.6.4) :
6998-同返回值转换,转发转移右值,复制左值;但当转发临时对象可确定唯一使用时,也转移临时对象。
7087+此时,在返回之前根据特定参数是否为引用值,可选地转换结果(@10.3.1) 以确定是否保留引用值,即进行转发。
7088+特定的显式转发操作转发临时对象(@5.8.5) 的引用值(@6.3.3) 使临时对象被转移,以转发的值作为结果,可不同于使用返回值转换(@6.4.6.4) :
7089+ 同返回值转换,转发转移右值,复制左值。
7090+ 但当转发临时对象可确定唯一使用时,也转移临时对象。
7091+**原理**
7092+函数值转发使某些操作在默认情况下满足间接值生存期规则而保持内存安全,符合适用性原则(@1.5.5.2) 。
7093+**注释**
69997094 确定是否保留引用值的机制类似 ISO C++14 中从没有括号的 id-expression 上推断返回 decltype(auto) 类型是否为引用类型。
7000-函数值转发使某些操作在默认情况下满足间接值生存期规则而保持内存安全,符合适用性原则(@1.5.5.2) 。
70017095 函数值转发的实现可通过判断是否需要转发引用而按需决定返回引用值或非引用值(@10.4.2) ,或使用标准库的相关函数(@11.2.2.4) 。前者支持本机实现。
7002-**注释**
70037096 另见对象的可转移条件(@5.8.3.6) 。
70047097 显式转发操作把右值、消亡值和带有临时对象标签(@6.2.2) 的左值引用视为被转发的目标。
7005-转发列表对象的子对象可能转移子对象。
7098+转发列表对象的子对象(@9.9.4.1) 可能转移这个对象。
70067099
70077100 @10.5.5 创建和访问对象的函数:
70087101 构造器(constructor) 是用于创建对象的函数。
@@ -7103,12 +7196,10 @@
71037196 作为一等实体的未指定值和 Kernel 类似,仍为 #inert(@9.3.1.3) ,但不提供谓词确定其未指定。
71047197 **注释** 惰性值仍可通过比较确定相等性。
71057198
7106-@10.7.3 以引用标记字符结尾的函数名:
7199+@10.7.3 引用标记字符的函数名后缀:
71077200 一些操作以结尾引用标记字符和不以引用标记字符结尾的名称提供多个变体。其中不含结尾的引用标记字符的表示操作的结果(@10.3.1) 不是引用值,要求按值传递(@8.4.5.4) 。
71087201 其它一些操作可能只提供以 % 结尾的变体。
71097202 不使用引用标记字符的函数及其函数值时,不因引入引用值违反内存安全(@9.4) 。这允许通过避免公开带有引用标记字符后缀的操作提供一个内存安全的子集,以在派生实现对语言进行裁剪。
7110-尽管设计时没有参照,使用函数结尾的引用标记字符和其它一些语言的类似特性的使用惯例也一致,如 PHP 的 function & 语法:
7111-https://www.php.net/references.return
71127203 为满足适用性(@1.5.5.2) ,同时考虑避免误用和允许使用引用避免复制,对一些操作显式使用以 % 或 & 结尾的函数名称以得到特别关注。
71137204 名称以引用标记字符结尾的操作属于以下分类之一:
71147205 可能直接保留引用值的操作:结果(@4.4.5.1) 及作用(@4.4.5.1) 依赖实际参数(需要时经过隐含的左值到右值转换)的值;
@@ -7119,14 +7210,19 @@
71197210 以 & 结尾表示函数使用不进行左值到右值转换的折叠的引用值参数,或返回折叠的引用值;
71207211 以 @ 结尾表示函数使用不进行左值到右值转换的未折叠的引用值参数,或返回未折叠的引用值。
71217212 以上引用值参数的使用指以依赖这些参数的方式构成函数的调用结果和/或决定产生的相应的副作用;返回的引用值来自引用值参数(若存在)。
7122-**注释**
7123-取得折叠的引用值的默认约定同间接值实现规则(@9.4.2) 蕴含的 NPLA1 默认规则(@7.1.3) 。
7213+**原理**
7214+尽管设计时没有参照,使用函数结尾的引用标记字符和其它一些语言的类似特性的使用惯例也一致,如 PHP 的 function & 语法:
7215+https://www.php.net/references.return
7216+**注释**
71247217 按这些规则,以 % 结尾的操作在取折叠的引用值时,可能同时实现被引用对象的转发。这相当于被访问的被引用对象作为宿主语言的 std::forward 的参数后的调用结果作为操作的结果,但此处一般仍然保证支持 PTC(@9.7.4) 。
71257218 以 & 结尾的操作取得的折叠的引用值可能是唯一引用。
71267219
71277220 @10.7.3.1 引用折叠:
7128-以上函数调用结果中的折叠的引用值对调用时引入的引用值有效。
7129-除非另行指定,不折叠(调用前的)参数中包含的引用值,依赖这些参数的函数结果仍可因此包含未折叠的引用值。
7221+取得折叠的引用值的默认约定同间接值实现规则(@9.4.2) 蕴含的 NPLA1 默认规则(@7.1.3) 。
7222+以上函数调用结果中:
7223+ 折叠的引用值对调用时引入的引用值(不论是否来自参数)有效。
7224+ 除非另行指定,不对同一个对象引用折叠多次。
7225+ **注释** 这些规则不保证结果是完全折叠的引用值(@5.8.3.2) 。返回折叠引用值的函数可因未完全折叠的引用值参数等返回未折叠的引用值。
71307226 这允许函数的内部实现引入一次引用值时,对来自每个参数的引用值至多只需要实现一次折叠。
71317227 推论:若参数都不是未折叠的引用值,调用不以 @ 结尾的函数不引入未折叠的引用值。
71327228 若指定的操作按不同操作数可涉及或不涉及和当前不同环境下的求值,提供不保留引用值和保留引用值的多个变体的操作以便保证内存安全,包括 @11.2.1 和 @11.2.2 指定的操作。
@@ -7134,7 +7230,7 @@
71347230 @10.7.3.2 与内存安全的关系:
71357231 利用区分引用标记字符结尾的操作,可指定具体关于具体操作的对象语言接口的安全保证机制(@9.4.6) 。
71367232 结尾的引用标记字符用于强调无法总是保证内存安全的危险操作(@1.5.5.2) 。
7137-不带有引用标记字符结尾的操作通过避免保留引用值(@10.4.3) 提供一定的内存安全保证,而带有引用标记字符结尾的操作较容易引起注意。
7233+不带有引用标记字符结尾的操作通过避免保留引用值(@10.4.3) 提供一定的内存安全保证(@9.4) ,而带有引用标记字符结尾的操作较容易引起注意。
71387234 这符合易预测性(@1.5.5.2.1) 。
71397235 一个典型例子是在函数中返回标识符求值(@9.7.1) 的表达式:
71407236 标识符求值后指称左值引用值(@7.8.2) ,这个引用值的有效性依赖合并子调用时创建的新环境(@9.9.3) 的可被访问;
@@ -7279,7 +7375,7 @@
72797375 直接保留引用值(@10.4.3) 操作可配合带有返回值转换(@6.4.6.4) 的操作,指定个别函数参数不再保留引用值。
72807376 **注释**
72817377 一些修改操作无效化(@9.8.6) 引用值。这些引用值若被保留且被访问,可引起未定义行为。
7282-不引起被绑定对象无效的修改操作不被视为不安全操作,即便它们无效化子对象的引用值。
7378+不引起被绑定对象无效的修改操作不被视为不安全操作,即便它们无效化子对象(@9.8.2) 的引用值。
72837379
72847380 @10.8.2 在返回值中保留环境引用的操作:
72857381 环境引用(@6.4.3.1) 被返回时,总是被保留(@10.4.4) 。
@@ -7290,7 +7386,7 @@
72907386 @10.8.3 在返回值中保留其它间接值的操作:
72917387 特定的支持强递归绑定(@9.7.3.1) 而在返回值中保留其它间接值,可能是无效的间接值(@9.4.3.3) 。
72927388 在返回值中保留其它间接值的操作的强递归绑定过程中引用共享对象(参见 $defrec!(@11.3.7) )的中间值。
7293-NPLA1 参考实现环境中,仅有在返回值中保留其它间接值的操作的实现内部可能引入引用持有者(@6.4.3.3) 。
7389+NPLA1 参考实现环境中,在返回值中保留其它间接值的操作的实现内部可能引入引用持有者(@6.4.3.3) 。
72947390
72957391 @10.8.4 在环境中保留环境引用的操作:
72967392 环境中的被绑定对象可具有环境引用子对象(@9.8.2) ,间接地在环境中保留环境引用。
@@ -7304,9 +7400,9 @@
73047400
73057401 @10.8.5 无效化被绑定对象或环境引用的操作:
73067402 特定的操作蕴含被绑定对象的存储期的结束而无效化它的引用值。
7307-若子对象引用已被绑定,这些引用值不需要通过其它不安全操作,而仅通过之后访问标识符求值(@9.7.1) 的结果(@7.8.2) 即可引起未定义行为。
7403+若子对象(@9.8.2) 的引用值已被绑定,这些引用值不需要通过其它不安全操作,而仅通过之后访问标识符求值(@9.7.1) 的结果(@7.8.2) 即可引起未定义行为。
73087404 因为环境稳定性(@9.9.3.4) 要求,NPLA1 实现环境不提供这类绑定,因此这些操作不是不安全操作。
7309-但派生实现可能在语言实现中提供不满足环境稳定性的一等环境,其中对象的子对象引用被绑定为变量,且前者可能被修改。
7405+但派生实现可能在语言实现中提供不满足环境稳定性的一等环境,其中对象的子对象的引用值被绑定为变量,且前者可能被修改。
73107406 此时,这些操作可能允许无效化引用后的被引用对象被访问,成为不安全操作。
73117407 类似地,无效化环境引用而无效化环境对象也可使其中包含的被绑定对象的引用无效化。
73127408 但环境生存期(@9.9.3.5) 要求,除非作为不满足环境稳定性的环境的被绑定对象,NPLA1 实现环境不提供唯一的环境强引用(@6.11.1) 可被用户程序(@9.1) 修改而使环境对象被销毁。
@@ -7321,7 +7417,7 @@
73217417
73227418 @10.8.7 可能破坏环境稳定性的操作:
73237419 通过引用值进行的修改操作(@9.8.3) 可因破坏环境稳定性(@9.9.3) 而引起扩展 NPLA 未定义行为(@9.1.4)(不一定违反内存安全)。
7324-这包括以下可无效化对象包含的引用值而使可通过环境访问的某个子对象的同一性被改变,从而破坏环境稳定性(@9.9.3) 的操作:
7420+这包括以下可无效化对象包含的引用值而使可通过环境访问的某个子对象(@9.8.2) 的同一性被改变,从而破坏环境稳定性(@9.9.3) 的操作:
73257421 对可能具有对象语言中可访问的子对象的对象的赋值操作(@9.8.3.1) ;
73267422 可修改被绑定对象(@6.11.1) 的操作(包括重绑定(@9.9.3.7) )。
73277423
@@ -7446,7 +7542,7 @@
74467542 assign%!
74477543
74487544 @11.1.6 可能破坏环境稳定性的操作(@10.8.7) :
7449-对可能具有对象语言中可访问的子对象的对象的赋值操作(@9.8.3.1) 包括:
7545+对可能具有对象语言中可访问的子对象(@9.8.2) 的对象的赋值操作(@9.8.3.1) 包括:
74507546 简单赋值(@10.7.4.3) 。
74517547 可直接修改被绑定对象(@6.11.1) 的操作包括:
74527548 move!(@11.3.4) 。
@@ -7632,7 +7728,7 @@
76327728 本节的操作不修改参数对象。
76337729 本节的操作的结果是 <boolean> 类型的纯右值。
76347730 用户定义的类型提供的等价谓词应满足和 NPLA1 提供的等价谓词的语义一致的等价关系,否则若谓词被求值,行为未指定。
7635-一些具有项节点作为表示的对象的子对象具有递归相等性,仅当子对象符合以下递归相等关系:
7731+一些具有项节点作为表示的对象的子对象(@9.8.2) 具有递归相等性,仅当子对象符合以下递归相等关系:
76367732 对叶节点,同 eqv? ;
76377733 否则,同 eqv? 且每个子节点对应满足 eqv?(蕴含节点数量相等)。
76387734 判断子对象递归相等性的对象相等时,其续延未指定。
@@ -7642,12 +7738,13 @@
76427738 当且仅当两个参数是指定同一对象时,比较结果是 #t 。
76437739 eq? 的复杂度是 O(1) 。
76447740 eql? <object1> <object2> :判断表示参数的项的值数据成员(@6.2) 相等。
7645-当且仅当表示两个参数是的项的值数据成员相等时,比较结果是 #t 。
7741+若参数是引用值,则被比较的项是表示它的被引用对象(@4.2.3) 的项。
7742+当且仅当被比较的项的值数据成员相等时,比较结果是 #t 。
76467743 值数据成员相等蕴含参数的动态类型(@4.7) 相同(@4.7.2) 。
76477744 eqr? <object1> <object2> :判断表示参数的项的数据成员同一。
7648-当且仅当表示两个参数是的项的值数据成员指定宿主语言中的同一对象(即引用相等)时,比较结果是 #t 。
7745+当且仅当表示被比较的项的值数据成员指定宿主语言中的同一对象(即引用相等)时,比较结果是 #t 。
76497746 eqv? <object1> <object2> :判断非枝节点(@6.2.1) 表示的值相等。
7650-若参数是引用值,则被比较的值是它的被引用对象(@4.2.3) 。
7747+若参数是引用值,则被比较的值是它的被引用对象。
76517748 当表示值的项都是枝节点时,同 eq? ;
76527749 否则,若这两个参数的类型不同(@4.7.2) ,则结果是 #f ;
76537750 否则,若这两个参数的 eql? 比较结果是 #t ,则结果是 #t 。
@@ -7718,11 +7815,14 @@
77187815 branch? <object> :判断操作数是否具有枝节点表示。
77197816 branchv? <object> :判断操作数是否为具有枝节点表示的纯右值。
77207817 同 branch? ,但不支持引用值。
7818+pair? <object> :<pair> 的类型谓词(@10.7.2.1) 。
7819+pairv? <object> :判断操作数是否为有序对纯右值。
7820+同 pair? ,但不支持引用值。
77217821 reference? <object> :判断操作数是否为引用值。
77227822 unique? <object> :判断操作数是否为唯一引用(@6.2.2) 。
77237823 modifiable? <object> :判断操作数是否为可修改对象或可修改对象的引用值。
77247824 temporary? <object> :判断操作数是否为临时对象(@5.8.5) 或临时对象的引用值。
7725-bound-lvalue? <object> :判断操作数是否为被引用的被绑定对象左值。
7825+bound-lvalue? <object> :判断操作数是否为被引用的被绑定对象(@5.7.1) 左值。
77267826 绑定临时对象的引用类型的参数不被视为左值引用。
77277827 配合 $resolve-identifier(@11.3.7) 和 % 引用标记绑定(@7.7.3.5) 的变量,可确定实际参数是否为左值;参见 $lvalue-identifier?(@11.4.1) 。
77287828 使用 bound-lvalue? 和 & 引用标记字符绑定(@7.7.3.5) 的变量,可确定实际参数是否为引用。
@@ -7743,8 +7843,7 @@
77437843 move! <object> :转移对象。
77447844 若参数是不可修改的左值,则以复制代替转移;否则,直接转移表示参数对象的项(@6.3.6) 。
77457845 结果是不经返回值转换的项。
7746-被转移对象后的项满足 @5.6.2 。
7747-当前实现中项被转移后,表示的值为 () 。这和返回值转换(@6.4.6.4) 等引入实质化临时对象时可能具有的转移(@5.8.5) 的效果(仅在互操作时可见)不保证相同。
7846+**注释** 另见转移的注意事项(@9.8.3.2) 。
77487847 transfer! <object> :转移对象。
77497848 同 move! ,但使用对象的转移(@5.8.2.3) ,而不是项的转移(@6.3.6) ,避免宿主对象转移消除而允许调用宿主对象的转移构造函数(@6.3.6.1) 。
77507849 项被转移后,和返回值转换等引入实质化临时对象时可能具有的转移的效果(仅在互操作(@1.2.3) 时可见)相同。
@@ -7756,6 +7855,7 @@
77567855 assign@! <reference> <object> :赋值(@9.8.3.1) 被引用的对象为指定对象的值,且 <object> 不隐含左值到右值转换且不被折叠。
77577856 检查 <reference> 是可修改的左值。
77587857 赋值对象直接修改(@9.8.3) 被引用的对象,但不无效化(@9.8.6) 参数指定的引用。
7858+**注释** 另见赋值的注意事项(@9.8.3.1) 。
77597859 **注释** 被赋值替换的子对象的引用可被无效化。Scheme 的 set! 在 SRFI-17 提供具有类似作用的支持,但第一操作数限于 set! 且为特定的过程调用;Kernel 没有类似的操作。
77607860
77617861 @11.3.5 列表:
@@ -7794,8 +7894,8 @@
77947894 结果是解析结果中的项。
77957895 **注释** 参数不按成员访问规则确定值类别(@6.4.6.1) ,也不按解析名称表达式的规则确保结果总是左值(@7.8.2) ,可保留消亡值(@6.4.6.1) 。
77967896 $move-resolved! <symbol> :转移解析标识符的对象。
7797-和 $resolve-identifier 类似,但直接取被绑定的对象并从环境中转移。
7798-若环境被冻结(@9.9.3.9) ,则复制绑定的对象所在的项;否则,直接转移对象的项(@6.3.6) 。
7897+和 $resolve-identifier 类似,但直接取被绑定对象(@5.7.1) 并尝试从环境中转移。
7898+若环境被冻结(@9.9.3.9) ,则复制被绑定对象;否则,直接转移对象的项(@6.3.6) 。
77997899 一般应仅用于被绑定的对象不需要再被使用时。
78007900 () copy-environment :递归复制当前环境。当前忽略父环境(@9.9.3) 中的环境列表(@6.11.1) 。
78017901 结果是新创建的环境,具有宿主值类型 shared_ptr<Environment> 。
@@ -7875,7 +7975,7 @@
78757975 和 Kernel 类似,结果是三个合并子组成的列表,其元素分别表示用于构造封装类型对象的封装(encapsulate) 构造器、判断封装类型的谓词和用于解封装(decapsulate) 的访问器。
78767976 构造器直接使用参数,在结果(构造的封装对象)中保留参数的引用值,类似(@11.2.1.1) 中带有 % 的容器构造器(@10.7.3.3) ;
78777977 访问器根据参数的值类别转发被封装的值。
7878-创建的封装类型支持判断相等(参见 eqv?(@11.3.2) ),相等定义为被封装的对象的子对象的递归相等性(@11.3.2) 。
7978+创建的封装类型支持判断相等(参见 eqv?(@11.3.2) ),相等定义为被封装的对象的子对象(@9.8.2) 的递归相等性(@11.3.2) 。
78797979 **注释**
78807980 和 [RnRK] 不同,使用构造器初始化封装的对象作为容器,具有作为其子对象的被封装的对象的所有权。
78817981 需要注意保存被构造的封装对象。
@@ -7893,13 +7993,13 @@
78937993 NPL_Impl_NPLA1_Native_EnvironmentPrimitives
78947994 NPL_Impl_NPLA1_Use_Id_Vau
78957995 NPL_Impl_NPLA1_Use_LockEnvironment
7896-不直接使用本机实现的替代实现仅供参考,可能引入和本机实现不同的未指定行为(如子对象生存期(@9.8.2) 不同),且可能有和核心特性实现相关的限制,包括:
7996+不直接使用本机实现的替代实现仅供参考,可能引入和本机实现不同的未指定行为(如子对象(@9.8.2) 的生存期(@5.6.6) 不同),且可能有和核心特性实现相关的限制,包括:
78977997 以下不同实现可引起不同的诊断:
78987998 由合并子调用的参数绑定(@8.4.5.3) 引起(@9.5.1) 的静态语法错误(@9.5.1) 。
78997999 类型检查(@9.5.4.1) 可具有不同的顺序而引起不同的类型错误。
79008000 列表元素检查的错误中的诊断消息(@1.2.4) 。
79018001 使用 TCO 实现 PTC(@9.7.4) ,可能具有不同的支持(@9.7.4.1) 和实现(如 TCO 动作消除(@7.10.9) )。
7902- 操作的语义允许时,操作的结果和调用操作的作用(@4.1) 引起改变的对象中可包含符合具体操作的约定的未指定值(但不含没有附加限制条件的未指定值(@10.7.2.3) )。
8002+ 操作的语义允许时,操作的结果和作用(@10.3.1) 引起改变的对象中可包含符合具体操作的约定的未指定值(但不含没有附加限制条件的未指定值(@10.7.2.3) )。
79038003 没有明确指定时,创建的对象的具体内部表示及其宿主类型。
79048004 续延名称(@7.11.7) 等在特定条件下具有的可观察行为的差异。
79058005 其中,影响可观察行为的差异应为操作符合性(@10.9.2) 约定的实例。
@@ -7987,9 +8087,9 @@
79878087 assign%! <reference> <object> :同 assign@!(@11.3.4) ,但 <object> 是引用值时赋值的源操作数是 <object> 折叠后的值。
79888088 assign! <reference> <object> :同 assign%! ,但 <object> 隐含左值到右值转换。
79898089 **注释** 因为左值到右值转换,即便 <object> 指定的值来自 <reference> ,也可赋值而不因此引起未定义行为。
8090+**注释** 另见赋值的注意事项(@9.8.3.1) 。
79908091 apply <applicative> <object> :在新环境(@9.9.3) 中应用。
79918092 apply <applicative> <object> <environment> :在指定环境中应用。
7992-在应用之前,应确保 <environment> 是一个而不是多个对象。
79938093 **注释** 检查 <environment> 和 [RnRK] 的参考派生不同。
79948094 apply 的函数值保留引用值。
79958095 list* <object>+ :在列表前附加元素创建列表。
@@ -8034,7 +8134,7 @@
80348134 结果构成子列表,引入子列表引用。
80358135 restv <list> :取列表第一个元素以外的元素值构成的列表。
80368136 结果是列表对象。
8037-equal? <object> <object> :判断一般相等。
8137+equal? <object1> <object2> :判断一般相等。
80388138 类似 eqv?(@11.3.2) ,但同时支持表示中具有子项作为子对象(@9.8.2) 的对象。
80398139 判断的相等定义为子对象的递归相等性(@11.3.2) 。
80408140 **注释** 类似 Kernel 和 Scheme 的 equal? 的二元谓词,但在此保证可通过 eqv? 直接构造。:
@@ -8138,7 +8238,7 @@
81388238 同 Kernel 的 $binding->environment ,但指定父环境,且具有适当的所有权。
81398239 使用 make-environment(@11.3.7) 而不是 $let/e(@11.4.1) 等绑定构造实现。
81408240 $bindings->environment <binding>... :转换绑定列表为没有父环境的具有这些绑定的环境。
8141-**注释** 类似 Kernel 的同名操作,但因为要求对内部父环境环境所有权,使用 $binding/p->environment 而不是 $let/e 等绑定构造派生。
8241+**注释** 类似 Kernel 的同名操作,但因为要求对内部父环境环境所有权,使用 $bindings/p->environment 而不是 $let/e 等绑定构造派生。
81428242 symbols->imports <symbol>... :转换符号列表为未求值的适合初始化符号导入(@10.1.2) 列表的初值符列表。
81438243 结果是包含同 desigil(@11.3.6) 的方式移除标记字符(@9.2.2.4) 后的参数作为间接子项的列表。
81448244 求值这个列表,结果是同 forward!(@11.4.1) 的方式转发每个符号的列表,其元素顺序和 <symbols>... 中的值的顺序对应。
@@ -8258,7 +8358,7 @@
82588358 **原理** 因为引入副作用可能是接口的关键功能及主要目的,此处的普遍性不限制非特定种类。
82598359 **注释** 仅具有控制作用为副作用的操作仍被视为是普遍的。因此,可具有控制作用(@4.1) 的 $if(@11.3.3) 等函数仍在根环境中提供。
82608360 **注释** 依赖一等续延(@4.5.3.3) 的控制作用(@4.1) 因续延类型而不视为足够普遍,因此根环境不直接提供一等续延(@4.5.3.3) 关联的操作。
8261-在此基础上,这些绑定被设计为环境子对象提供的子模块,因为以下的一个或多个原因:
8361+在此基础上,这些绑定被设计为环境子对象(@9.9.3) 提供的子模块(@10.2) ,因为以下的一个或多个原因:
82628362 它们可能具有非全局含义的名称而更适合隔离在不同命名空间(@4.3.4) 中以避免使用时的歧义。
82638363 它们可能仅关注(如作为操作的参数或返回类型)特定的求值得到的操作数(@9.2.2.2) 类型。
82648364 它们中的每一个模块具有足够或内聚性而不和其它子模块耦合,且绑定提供的实体关注相同的功能集合,适合被派生实现直接配置为可选的(@11.3) 特性分组。
Show on old repository browser