📄 csdn_文档中心_stl之父访谈录(一万二千字的大块头).htm
字号:
year1=tmpDate.getYear()
year= year1.toString().substr(1,2);
}
else
year= tmpDate.getYear();
document.write(year);
document.write(".");
document.write(month);
document.write(".");
document.write(date);
// -->
</SCRIPT>
</B> </TD></TR>
<TR bgColor=#999999>
<TD colSpan=3 height=1></TD></TR></TBODY></TABLE>
<TABLE border=0 width=770>
<TBODY>
<TR>
<TD align=middle bgColor=#fafafa class=td1 vAlign=top width=150><BR>
<SCRIPT src="CSDN_文档中心_STL之父访谈录(一万二千字的大块头).files/microsoft.js"></SCRIPT>
</TD>
<TD align=middle width=620>
<TABLE bgColor=#eeeeee border=0 cellPadding=0 cellSpacing=0 width=600>
<TBODY>
<TR bgColor=#ffffff>
<TD align=middle height=10 width=50></TD>
<TD align=right><A href="http://www.csdn.net/">CSDN</A> - <A
href="http://www.csdn.net/develop/">文档中心</A> - <FONT
color=#003399>Visual C++</FONT> </TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399 height=10><FONT
color=#ffffff>标题</FONT></TD>
<TD><B> STL之父访谈录(一万二千字的大块头)</B> myan(翻译)
</TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399><FONT color=#ffffff>关键字</FONT></TD>
<TD width=500> STL之父访谈录(一万二千字的大块头)</TD></TR>
<TR>
<TD align=middle height=5></TD>
<TD align=middle width=500></TD></TR>
<TR>
<TD align=middle bgColor=#003399 height=10><FONT
color=#ffffff>出处</FONT></TD>
<TD height=10> <A
href="http://www.sgi.com/technology/stl">http://www.sgi.com/technology/stl</A></TD></TR>
<TR>
<TD align=middle height=10></TD>
<TD height=10></TD></TR></TBODY></TABLE><!--文章说明信息结束//-->
<TABLE border=0 width=600>
<TBODY>
<TR>
<TD align=left><BR>
<P>STL之父访谈录<BR>1995年3月,Dr.Dobb's Journal特约记者, 著名技术书籍作家Al
Stevens采访了STL创始人Alexander<BR>Stepanov. 这份访谈纪录是迄今为止对于STL发展历史的最完备介绍,
侯捷先生在他的STL有关文章里<BR>推荐大家阅读这篇文章. 因此我将该文全文翻译如下:</P>
<P>Q: 您对于generic programming进行了长时间的研究, 请就此谈谈.<BR>A:
我开始考虑有关GP的问题是在7O年代末期, 当时我注意到有些算法并不依赖于数据结构的<BR>
特定实现,而只是依赖于该结构的几个基本的语义属性. 于是我开始研究大量不同的算法,<BR>
结果发现大部分算法可以用这种方法从特定实现中抽象出来, 而且效率无损. 对我来说,<BR> 效率是至关重要的,
要是一种算法抽象在实例化会导致性能的下降, 那可不够棒.<BR> <BR>
当时我认为这项研究的正确方向是创造一种编程语言. 我和我的两个朋友一起开始干起来.<BR>
一个是现在的纽约州立大学教授Deepak Kapur, 另一个是伦塞里尔技术学院教授David
Musser.<BR> 当时我们三个在通用电器公司研究中心工作. 我们开始设计一种叫Tecton的语言.
该语言<BR> 有一种我们称为"通用结构"的东西, 其实不过是一些形式类型和属性的集合体,
人们可以<BR> 用它来描述算法. 例如一些数学方面的结构充许人们在其上定义一个代数操作,
精化之,<BR> 扩充之, 做各种各样的事.<BR> <BR>
虽然有很多有趣的创意, 最终该项研究没有取得任何实用成果, 因为Tecton语言是函数型<BR> 语言.
我们信奉Backus的理念,相信自己能把编程从von Neumann风格中解放出来. 我们<BR>
不想使用副效应, 这一点限制了我们的能力, 因为存在大量需要使用诸如"状态", "副效<BR>
应"等观念的算法. </P>
<P> 我在70年代末期在Tecton上面所认识到了一个有趣的问题:
被广泛接受的ADT观念有着根本<BR> 性的缺陷. 人们通常认为ADT的特点是只暴露对象行为特征,
而将实现隐藏起来. 一项操作<BR> 的复杂度被认为是与实现相关的属性, 所以抽象的时候应予忽略. 我则认识到,
在考虑一<BR> 个(抽象)操作时, 复杂度(或者至少是一般观念上的复杂度)必须被同时考虑在内.
这一点<BR> 现在已经成了GP的核心理念之一.</P>
<P> 例如一个抽象的栈stack类型,
仅仅保证你push进去的东西可以随后被pop出来是不够的,<BR> 同样极端重要的是, 不管stack有多大,
你的push操作必须能在常数时间内完成. 如果我<BR> 写了一个stack, 每push一次就慢一点,
那谁都不会用这个烂玩艺.</P>
<P> 我们是要把实现和界面分开, 但不能完全忽略复杂度. 复杂度必须是,
而且也确实是横陈<BR> 于模块的使用者与实现者之间的不成文契约.
ADT观念的引入是为了允许软件模块相互可<BR> 替换. 但除非另一个模块的操作复杂度与这个模块类似,
否则你肯定不愿意实现这种互换.<BR> 如果我用另外一个模块替换原来的模块, 并提供完全相同的接口和行为,
但就是复杂度不<BR> 同, 那么用户肯定不高兴. 就算我费尽口舌介绍那些抽象实现的优点,
他肯定还是不乐意<BR> 用. 复杂度必须被认为是接口的一部分.</P>
<P> 1983年左右, 我转往纽约布鲁克林技术大学任教. 开始研究的是图的算法,
主要的合作伙<BR> 伴是现在IBM的Aaron Kershenbaum. 他在图和网络算法方面是个专家,
我使他相信高序(high<BR> order)的思想和GP能够应用在图的算法中.
他支持我与他合作开始把这些想法用于实际的<BR> 网络算法. 某些图的算法太复杂了, 只进行过理论分析,
从来没有实现过. 他企图建立一个<BR> 包含有高序的通用组件的工具箱, 这样某些算法就可以实现了.
我决定使用Lisp语言的一个<BR> 变种Scheme语言来建立这样一个工具箱. 我们俩建立了一个巨大的库,
展示了各种编程技术.<BR> 网络算法是首要目标. 不久当时还在通用电器的David Musser加了进来,
开发了更多的组件,<BR> 一个非常大的库. 这个库供大学里的本科生使用, 但从未商业化. 在这项工作中,
我了解到<BR> 副效应是很重要的, 不利用副效应, 你根本没法进行图操作.
你不能每次修改一个端点(vertex)<BR> 时都在图上兜圈子. 所以,
当时得到的经验是在实现通用算法时可以把高序技术和副效应结<BR> 合起来. 副效应不总是坏的,
只有在被错误使用时才是.</P>
<P> 1985年夏, 我回到通用电器讲授有关高序程序设计的课程.
我展示了在构件复杂算法时这项<BR> 技术的应用. 有一个听课的人叫陈迩, 当时是信息系统实验室的主任.
他问我是否能用Ada语<BR> 言实现这些技术, 形成一个工业强度的库, 并表示可以提供支持. 我是个穷助教,
所以尽管我<BR> 当时对于Ada一无所知, 我还是回答"好的". 我跟Dave
Musser一起建立这个Ada库. 这是很重<BR> 要的一个时期,
从象Scheme那样的动态类型语言(dynamically typed language)转向Ada这<BR>
样的强类型语言, 使我认识到了强类型的重要性. 谁都知道强类型有助于纠错. 我则发现在<BR>
Ada的通用编程中, 强类型是获取设计思想的有力工具. 它不仅是查错工具, 而且是思想工具.<BR>
这项工作给了我对于组件空间进行正交分解的观念. 我认识到, 软件组件各自属于不同的类别.<BR>
OOP的狂热支持者认为一切都是对象. 但我在Ada通用库的工作中认识到, 这是不对的. 二分查找<BR>
就不是个对象, 它是个算法. 此外, 我还认识到, 通过将组件空间分解到几个不同的方向上, 我<BR>
们可以减少组件的数量, 更重要的是, 我们可以提供一个设计产品的概念框架.</P>
<P> 随后, 我在贝尔实验室C++组中得到一份工作, 专事库研究.
他们问我能不能用C++做类似的事.<BR> 我那时还不懂C++, 但当然, 我说我行. 可结果我不行,
因为1987年时, C++中还没有模板, 这玩<BR> 艺在通用编程中是个必需品. 结果只好用继承来获取通用性,
那显然不理想.</P>
<P> 直到现在C++继承机制也不大用在通用编程中, 我们来说说为什么.
很多人想用继承实现数据结构<BR> 和容器类, 结果几乎全部一败涂地.
C++的继承机制及与之相关的编程风格有着戏剧性的局限. 用<BR> 这种方式进行通用编程,
连等于判断这类的小问题都解决不了. 如果你以X类作为基类, 设计了<BR> 一个虚函数operater==,
接受一个X类对象, 并由X派生类Y, 那么Y的operator==是在拿Y类对象与<BR> X类对象做比较.
以动物为例, 定义animal类, 派生giraffe(长颈鹿)类. 定义一个成员函数<BR> mate(),
实现与另一个哺乳动物的交配操作, 返回一个animal对象. 现在看看你的派生类giraffe,<BR>
它当然也有一个mate()方法, 结果一个长颈鹿同一个动物交配, 返回一个动物对象. 这成何体统?<BR>
当然, 对于C++程序员来说, 交配函数没那么重要, 可是operator==就很重要了.</P>
<P> 对付这种问题, 你得使用模板. 用模板机制, 一切如愿. </P>
<P> 尽管没有模板, 我还是搞出来一个巨大的算法库, 后来成了Unix System Laboratory
Standard<BR> Component Library的一部分. 在Bell Lab, 我从象Andy
Koenig, Bjarne Stroustrup(Andrew <BR> Koenig, 前ISO
C++标准化委员会主席; Bjarne Stroustrup, C++之父 -- 译者)这类专家<BR>
身上学到很多东西. 我认识到C/C++的重要, 它们的一些成功之处是不能被忽略的. 特别是我发<BR>
现指针是个好东东. 我不是说空悬的指针, 或是指向栈的指针. 我是说指针这个一般观念. 地<BR>
址的观念被广泛使用着. 没有指针我们就没法描述并行算法.</P>
<P> 我们现在来探讨一下为什么说C是一种伟大的语言.
通常人们认为C是编程利器并且获得如此成功,<BR> 是因为UNIX是用C写的. 我不同意.
计算机的体系结构是长时间发展演变的结果, 不是哪一个聪明<BR> 的人创造的.
事实上是广大程序员在解决实际问题的过程中提出的要求推动了那些天才提出这些<BR> 体系. 计算机经过多次进化,
现在只需要处理字节地址索引的内存, 线性地址空间和指针. 这个<BR>
进化结果是对于人们要求解决问题的自然反映. Dennis Ritchie天才的作品C, 正反映了演化了<BR>
30年的计算机的最小模型. C当时并不是什么利器. 但是当计算机被用来处理各种问题时, 作为<BR>
最小模型的C成了一种非常强大的语言, 在各个领域解决各种问题时都非常高效. 这就是C可移植<BR> 性的奥秘,
C是所有计算机的最佳抽象模型, 而且这种抽象确确实实是建立在实际的计算机, 而<BR> 不是假想的计算机上的.
人们可以比较容易的理解C背后的机器模型, 比理解Ada和Scheme语言背<BR> 后的机器模型要容易的多.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -