宝宝囟门什么时候闭合| 吃完饭恶心想吐是什么原因| 肠道紊乱吃什么药| 轧戏什么意思| 地铁不能带什么东西| 麻是什么原因| 戾气重是什么意思| 数字9像什么| 办健康证需要什么| 做生意的人最忌讳什么| 心肌桥是什么病| 郑少秋为什么娶沈殿霞| 手术室为什么在三楼| 什么app可以买烟| 什么情况下做胃镜| 顶臀径是指什么| 梦见买袜子是什么意思| 厚颜无耻是什么生肖| 修复胃粘膜吃什么药| kcal是什么意思| 什么减肥药效果最好而且不反弹| 一什么骆驼| 中元节出什么生肖| 手指关节疼痛看什么科| 什么是沉香木| 左侧肋骨疼是什么原因| 今年9岁属什么| 曲马多是什么药| 五行属性是什么| 五海瘿瘤丸主要治什么病| 剁椒鱼头属于什么菜系| 总是想吐是什么原因| 白俄罗斯和俄罗斯有什么区别| 怠工是什么意思| 胃疼想吐是什么原因| 东南西北五行属什么| 荨麻疹要用什么药| 亲子鉴定去医院挂什么科| 守夜是什么意思| 东吴是现在的什么地方| 米线用什么做的| 黑白猫是什么品种| 外甥和舅舅是什么关系| 四不像是指什么动物| 风热感冒用什么药| 熬夜为什么会胖| 失眠去药店买什么药| 妊娠纹长什么样| pre是什么的缩写| 易经和周易有什么区别| 带状疱疹是什么症状| 天伦之乐是什么意思啊| 什么杯子不能装水| 什么是宫腔镜检查| 嘴唇发白是什么原因| 尿酸高可以吃什么| 老觉得饿是什么原因| 黑桃a是什么酒| 小孩拉肚子吃什么药效果好| 胆囊结石挂什么科| 他达拉非是什么药| 什么材质的拖鞋不臭脚| 三眼花翎是什么意思| 右肝钙化灶是什么意思| 检测hpv挂什么科| 肚子疼用什么药好| 男生腿毛旺盛说明什么| 梦见皮带断了什么预兆| 红楼梦结局是什么| 老师家访的目的是什么| 为什么伴娘要未婚| 黑猫警长叫什么名字| 李子有什么功效| 四十岁月经量少是什么原因| mango是什么意思| 羊肉和什么一起炖最好| 道地是什么意思| 第二学士学位是什么意思| 孙悟空最后成了什么佛| 9.23什么星座| 藿香正气水不能和什么药一起吃| 倍他乐克是什么药| rococo是什么牌子| 5.20是什么星座| 吃什么助眠| 60岁男人喜欢什么样的女人| 荆芥俗名叫什么| 棒子面是什么| 猎德有什么好玩的| 起飞是什么意思| 行大运是什么意思| 学信网上的报告编号是什么| 冰糖是什么做的| 暗忖是什么意思| 促排药什么时候开始吃| ca199偏高是什么意思| 僵尸肉吃了有什么危害| 疣是什么东西| 乙类药品是什么意思| 砚是什么意思| 什么减肥最好最快| 胎儿左心室点状强回声是什么意思| 肠道湿热吃什么药| 缺锌有什么表现和症状| 生蒜头吃了有什么好处和坏处| vsop是什么意思| 什么都不需要| 五红汤什么时候喝最好| 谢邀什么意思| 莱赛尔纤维是什么面料| 5.4是什么星座| 欲望什么意思| 凝望什么| 植物园里有什么| 你想要什么我都会给| 低血压是什么意思| 查传染病四项挂什么科| 吃了什么药不能喝酒| 男人说做朋友代表什么| 黎山老母什么级别神仙| 什么是百分数| 怀孕两天会有什么反应| 阑尾粪石是什么| 早上九点半是什么时辰| 盐酸对人体有什么危害| pnh是什么病的简称| 胆囊炎看什么科室| 10月出生是什么星座| 粥样动脉硬化是什么意思| 三净肉是什么| 鸭嘴鱼吃什么食物| 元首是什么意思| 不景气是什么意思| 谢娜什么星座| 眩晕症是什么原因造成的| 贝母和川贝有什么区别| 什么不同成语| 端午节为什么吃粽子| 什么的雨| 子宫内膜不均匀是什么意思| gv是什么意思| 搬新家送什么礼物好| 胡塞武装是什么| 端午节干什么| 右下腹疼痛什么原因| 梦见网鱼是什么征兆| 脑子萎缩是什么原因造成的| 足金是什么意思| 扛扛的是什么意思| 双鱼座的上升星座是什么| 隐血阳性什么意思| 十月二十九是什么星座| 肝脏在什么位置图片| 胆管结石用什么药能把它除掉| 大公鸡衣服是什么牌子| 咳嗽痰多用什么药| 衣冠禽兽什么意思| 来褐色分泌物是什么原因| 小儿呕吐是什么原因引起的| 25岁属什么生肖| 爸爸的外婆叫什么| 丝瓜炒什么| 有甲状腺结节不能吃什么| 4月9号是什么星座| 奇怪的什么| omega3是什么意思| 3月30日什么星座| 红海为什么叫红海| 二哥是什么意思| 爸爸的爸爸的爸爸叫什么| 626什么意思| 烂舌头是什么原因| 双向什么意思| 命中注定是什么意思| 身份证借给别人有什么危害性| 梦见小孩生病什么预兆| 男人喝藏红花有什么好处| 结核t细胞阳性说明什么| 1994年什么命| 卡路里是什么意思| 孟姜女属什么生肖| 什么是菊粉| 什么病才查凝血四项呢| kumpoo是什么牌子| 结膜炎角膜炎用什么眼药水| 客之痣是什么意思| 碱中毒是什么引起的| 焦虑吃什么药| 肛瘘挂什么科| 茱萸是什么| 肠胃不舒服挂什么科| 一个口一个甫念什么| 3月26日是什么节日| 无利不起早是什么意思| 涤纶是什么面料优缺点| 什么是天乙贵人| 向日葵代表什么象征意义| 点头之交是什么意思| 羊肉不放什么调料| 毛囊是什么| 五七是什么意思| 喉结大是什么原因| 炝锅是什么意思| 虚荣心是什么意思| 黑豆有什么功效| 婴儿流鼻涕吃什么药| 四川耙耳朵是什么意思| 懿字五行属什么| 因果循环是什么意思| 无性恋什么意思| 手指关节疼痛是什么原因| 是什么数学符号| 副高是什么级别| 左侧头疼是什么原因| 阳虚和阴虚有什么区别| 夏天喝什么水最好| 左下腹疼痛挂什么科| 白粉是什么| 葡萄柚是什么水果| 湿疹为什么要查肝功能| 八珍胶囊适合什么人吃| 今年22岁属什么生肖| 真实写照的意思是什么| 负离子什么意思| 搞基是什么意思| 什么时候有胎心胎芽| 什么是区块链技术| 肝昏迷是什么意思| 口力念什么| 梦见炒菜是什么意思| 脚踝水肿是什么原因| 硝酸咪康唑乳膏和酮康唑乳膏有什么区别| 利普刀是什么手术| 颈椎压迫神经挂什么科| 转奶是什么意思| 糖尿病人吃什么| 1.22是什么星座| 胃阳不足吃什么中成药| momax是什么牌子| 如花似玉是什么生肖| rimowa是什么品牌| 跑步大腿痒是什么原因| 名声是什么意思| cr5是什么意思| 二月出生是什么星座| 夏天都有什么花| 老鼠怕什么| 亚蒂息肉是什么意思| 舌头烧灼感吃什么药| bhpc是什么牌子| 吃头孢不能吃什么| 18年是什么婚| 佛心是什么意思| 什么产品美白效果最好最快| 贴切的意思是什么| 褪黑素什么时候吃| 为什么腹部隐隐作痛| 喉咙痛吃什么药| 日本料理都有什么菜| 右胳膊麻木是什么征兆| 夜里咳嗽是什么原因| 双顶径是什么| 清热去湿热颗粒有什么功效| 萧墙是什么意思| 百度

主题旅游新探:游乐园,再多点新乐子

[article index] [] [@mattmight] [rss]
百度 领导小组成员分别围绕推进机关党建工作信息化建设进行了发言,提出了很好的意见建议。

For the Halloween lecture in my advanced compilers class, I scare students with C++ template meta-programming.

To prove that C++ templates are Turing-complete, we constructed a higher-order functional programming language out of them.

The language supports higher-order functions, literal values (raw types), natural numbers (as types), booleans and conditionals.

Specifically, we made an SICP-like eval/apply interpeter out of templates.

This embedded language shows that any computable function can be computed at compile-time in C++.

How: Template specialization

The Turing-completeness of templates in C++ is an accident arising from the collision of two features: templates and template specialization.

These two features allow C++ templates to act like an untyped term-rewriting language.

A template declares a data type parameterized by some constants and by some types; for example:

template <typename A>
struct ListNode
{
  A data ;
  ListNode<A>* next ;
} ; 

A template specialization allows the programmer to override the definition of a template for some combination of template parameters.

For example, we could override the definition of ListNode when parameterized with the type unsigned int:

template <>
struct ListNode<unsigned int>
{
  /* Don't let them use unsigned ints. */
  int data ;
  ListNode<int>* next ;
} ;

The standard example of why you would want to specialize is so that you could have Vector<bool> implemented as a true bit-vector, instead of wasting one word per element.

Factorial example

The canonical example of compile-time computation is factorial in templates:

template <int N>
struct Factorial 
{
  enum { value = N * Factorial<N-1>::value };
};
 
template <>
struct Factorial<0> 
{
  enum { value = 1 } ;
};

Without the template specialization, a reference to Factorial<4>::value would re-write itself forever, eventually causing the template equivalent of a stack overflow.

Note the use of enumerations to force compile-time evaluation of the member constant value.

With this template in place, code could refer to Factorial<4>::value and get 24 computed at compile-time.

Encoding and pattern-matching data structures

In C++ template meta-programming, types are used to encode structured data, and specializations are used to destructure that data with pattern-matching.

For example, we could encode the natural numbers using a Zero type, and a Succ<Number> template type:

struct Zero 
{
  enum { value = 0 } ;
} ;

template <typename N>
struct Succ 
{
  enum { value = N::value + 1 } ;
} ;

We could then make a template that matches the value 1 encoded as Succ<Zero>:

template <typename N>
struct MatchOne
{
  enum { value = 0 } ;
} ;


template <>
struct MatchOne<Succ<Zero> >
{
  enum { value = 1 } ;
} ;

so that the following code works:

cout << MatchOne<Zero >::value << endl; 
// Prints: 0

cout << MatchOne<Succ<Zero> >::value << endl; 
// Prints: 1

cout << MatchOne<Succ<Succ<Zero> > >::value << endl; 
// Prints: 0

Proving Turing-completeness

To prove Turing-completeness, we have to show that C++ templates can be implemented by a Turing machine (gcc takes care of this), and that C++ templates can implement a Turing machine.

It's well known that the λ-calculus (which actually predates the Turing machine) is Turing-complete, so just have to show that C++ templates can implement the λ-calculus.

In fact, in an effort to make this (a little) more than a toy exercise, the evaluator can handle conditionals, booleans and literal values too.

One could actually do some programming with this language.

The commented code below explains how this is done.

We don't have to utilize much of the C++ language to pull this off.

We don't need templates that generate templates, embedded templates or even templates that accept templates.

We use templates, template specialization, struct, typename and typedef.

And, it's barely 200 lines of code with comments included.

An abstract syntax in templates

We'll use integers for variables names (although we can easily provide aliases for them).

We need to use instantiated template types to represent program terms:

// Anonymous functions:
template 
struct Lambda {} ;

// Function call/Application:
template 
struct App {} ; 

// References:
template 
struct Ref {} ;

// Conditionals:
template 
struct If {} ;

// Literals:
template 
struct Lit {} ;

Environments as templates

Environments, which map names to values, are type-level linked lists:

// EmptyEnv is the empty environment:
struct EmptyEnv ;

// Bindings<Name,Value,Env> is a type than encodes the environment Env
// extended with a binding for Name => Value:
template <int Name, typename Value, typename Env>
struct Binding {} ;

The template metafunction EnvLookup accepts a name and an environment to yield a value:

// EnvLookup<Name,Env> :: result looks up the value of Name in Env:
template <int Name, typename Env>
struct EnvLookup {} ;

template <int Name>
struct EnvLookup <Name,EmptyEnv> {} ; // Name not found.

template <int Name, typename Value, typename Env>
struct EnvLookup <Name, Binding<Name,Value,Env> > 
{
  Value typedef result ;
} ;

template <int Name, int Name2, typename Value2, typename Env>
struct EnvLookup <Name, Binding<Name2,Value2,Env> >
{
  typename EnvLookup<Name,Env> :: result typedef result ;
} ;

EnvLookup illustrates an important convention: to define a type-level meta-function, we typedef its return value to the field result.

Accessing the field result forces the expansion and yields the return value.

Type-level values

Of course, run-time "values" in a template meta-program are actually types:

// Closures:
template 
struct Closure {} ;

// Booleans:
struct True {} ;
struct False {} ;

Eval and apply as meta-functions

Finally, we define eval and apply as type-level meta-functions:

// Eval<Exp,Env> :: result is the value of expression Exp in
// environment Env.
template <typename Exp, typename Env>
struct Eval {} ;

// Apply<Proc,Value> :: result is the value of applying Proc to Value.
template <typename Proc, typename Value>
struct Apply {} ;



// Literals evaluate to themselves:
template <typename T, typename Env>
struct Eval <Lit<T>, Env>
{
  T typedef result ;
} ;

// Variable references are looked up in the current environment:
template <int Name, typename Env>
struct Eval <Ref<Name>, Env>
{
  typename EnvLookup<Name, Env> :: result typedef result ;
} ;

// Lambda terms evaluate into closures:
template <int Name, typename Body, typename Env>
struct Eval <Lambda<Name,Body>, Env>
{
  Closure<Lambda<Name, Body>, Env> typedef result ;
} ;

// Applications apply the value of the function expression to the
// value of the argument expression:
template <typename Fun, typename Arg, typename Env>
struct Eval<App<Fun, Arg> , Env> {
  typename Apply<typename Eval<Fun,Env> :: result ,
                 typename Eval<Arg,Env> :: result > :: result 
           typedef result ;
} ;

// Branch true:
template <typename Then, typename Else, typename Env>
struct Eval<If<True,Then,Else>,Env> {
  typename Eval<Then,Env> :: result typedef result ;
} ;

// Branch false:
template <typename Then, typename Else, typename Env>
struct Eval<If<False,Then,Else>,Env> {
  typename Eval<Else,Env> :: result typedef result ;
} ;

// Evaluate the condition:
template <typename Cond, typename Then, typename Else, typename Env>
struct Eval<If<Cond,Then,Else>,Env> {
  typename Eval<If<typename Eval<Cond,Env> :: result, 
                   Then,
                   Else>,
                Env> :: result 
           typedef result ;
} ;


// Transition to the body of the lambda term inside the closure:
template <int Name, typename Body, typename Env, typename Value>
struct Apply<Closure<Lambda<Name,Body>, Env>, Value> {
  typename Eval<Body, Binding<Name,Value,Env> > :: result 
           typedef result ;
} ;

All together

Now, we can construct and execute simple template meta-programs:

  // Testing ((lambda (x) x) 2):
  enum { X } ;
  
  int x = Eval<App<Lambda<X,Ref<X> >,Lit<Succ<Succ<Zero>
     > > >,EmptyEnv> :: result :: value ;

  assert(x == 2) ;


  // Testing (if #f 0 1):
  int y = Eval<If<Lit<False>,Lit<Zero>,Lit<Succ<Zero>
     > >,EmptyEnv> :: result :: value ;
  
  assert(y == 1) ;

Code

The code is available.

Resources and related pages

  • C++ Templates: The Complete Guide is the definitive guide to C++ templates and template meta-programming:
    It's written by two C++ standards committee members. The afternotes in each chapter which mention the proceedings of the standards committee are fascinating. In case you're wondering, the Turing-completeness of templates was first an accident, and then a feature.
  • There's another implementation of a lambda-calculus-based language for C++ templates out there.
  • Structure and Interpretation of Computer Programs, the classic MIT textbook, covers eval/apply interpreters in Chapter 4:

Exercise

If you would like to practice some of the principles on display in this article, I'm providing a challenge problem: implementing addition as a template meta-program.

The stub code is available.

You need to create (two) specializations of the Add struct to make it work.


血糖高吃什么水果 什么情况会胎停 儿童受凉咳嗽吃什么药 甘油三酯高是什么原因造成的 血小板有什么作用
导语是什么 地面铺什么最环保 塔罗牌逆位是什么意思 晚上睡觉睡不着是什么原因 谷草谷丙比值偏高代表什么
布丁是用什么做的 公开遴选公务员是什么意思 梦见黑色的蛇是什么意思 老人大小便失禁是什么原因造成的 蓁字五行属什么
国企属于什么编制 全日制专科是什么意思 1966年是什么命 牙痛 吃什么药 喝什么解渴
喝最烈的酒下一句是什么hcv8jop3ns3r.cn 昕字取名什么寓意hcv9jop5ns1r.cn 鼻窦炎有什么症状表现cl108k.com 为什么会得肿瘤hcv8jop5ns3r.cn 飞机上不能带什么东西hcv7jop5ns1r.cn
彩超挂什么科hcv8jop4ns6r.cn 鱿鱼炒什么好吃xinjiangjialails.com 盆腔炎吃什么药最好hcv8jop9ns5r.cn 大爷是什么意思hcv9jop5ns8r.cn 痛风不能吃什么蔬菜hcv8jop0ns3r.cn
10a是什么意思hcv9jop5ns3r.cn land rover是什么车hcv9jop1ns3r.cn 晕轮效应是什么意思hcv9jop2ns0r.cn 佛度有缘人是什么意思hcv9jop7ns2r.cn 六味地黄丸是治什么病hcv8jop5ns8r.cn
熊喜欢吃什么食物bjhyzcsm.com 推手是什么意思aiwuzhiyu.com sars是什么病毒hcv9jop6ns7r.cn 戌时是什么时候hcv9jop5ns7r.cn 中国的国服是什么服装hcv9jop7ns0r.cn
百度