Ces*_*Gon 8 c# dependencies programming-languages libraries
我一直想知道如何从编程语言到其库来管理依赖项.以C#为例.当我开始学习计算时,我会假设(错误地证明)语言本身是独立于最终可用于它的类库而设计的.也就是说,首先定义语言关键字集(例如for,class或throw)加上语法和语义,并且可以从语言中使用的库是单独开发的.我曾经认为,这些库中的特定类不应该对语言的设计产生任何影响.
但这不起作用,或者不是一直都行不通.考虑throw.C#编译器确保后面的表达式throw解析为异常类型.Exception是一个库中的类,因此它根本不应该是特殊的.除了C#编译器为其指定特殊语义之外,它将与其他任何类一样.这是非常好的,但我的结论是语言的设计确实取决于类库中特定元素的存在和行为.
另外,我想知道如何管理这种依赖.如果我要设计一种新的编程语言,我会用什么技术将语义映射throw到特定的类Exception?
所以我的问题是两个:
谢谢.
编辑.感谢那些指出我的第二个问题非常含糊的人.我同意.我想要学习的是编译器存储的所需类型的引用.例如,它是否通过某种唯一ID找到类型?发布新版本的编译器或类库时会发生什么?我知道这仍然很模糊,我不期待一个精确的单段答案; 相反,非常欢迎指向文学或博客文章.
Eri*_*ert 11
我想要学习的是编译器存储的所需类型的引用.例如,它是否通过某种唯一ID找到类型?
显然,C#编译器在源代码和元数据中维护一个可用的所有类型的内部数据库; 这就是编译器被称为"编译器"的原因 - 它编译有关源和库的数据集合.
例如,当C#编译器需要检查抛出的表达式是从System.Exception派生还是与System.Exception相同时,它会假装执行全局命名空间查找System,然后执行查找Exception,查找类,然后进行比较生成的类信息为表达式推导出的类型.
编译器团队使用这种技术,因为无论我们是编译源代码System.Exception还是在元数据中,或者我们正在编译mscorlib本身并且System.Exception在源代码中,它都可以工作.
当然,作为性能优化,编译器实际上有一个"已知类型"列表,并提前填充列表,这样就不必每次都要花费大量的时间进行查询.您可以想象,您必须查找内置类型的次数非常多.填充列表后,System.Exception只需从列表中读取类型信息,而无需进行查找.
发布新版本的编译器或类库时会发生什么?
会发生什么:一大堆开发人员,测试人员,经理,设计人员,编写人员和教育工作者聚在一起,花费几百万工时,确保编译器和类库在发布之前都能正常工作.
这个问题再次模糊不清.新的编译器发布会发生什么?很多工作,这就是必须发生的事情.
我知道这仍然很模糊,我不期待一个精确的单段答案; 相反,非常欢迎指向文学或博客文章.
我写了一篇博客,其中包括C#语言及其编译器的设计.它位于http://ericlippert.com.
我会假设(可能是错误地)语言本身是独立于最终可用于它的类库而设计的.
在C#的情况下,你的假设是完全错误的.C#1.0,CLR 1.0和.NET Framework 1.0都是一起设计的.随着语言,运行时和框架的发展,每个人的设计人员密切合作,以确保分配正确的资源,以便每个人都能按时发布新功能.
我不明白你完全错误的假设来自哪里; 这听起来像是编写高级语言的低效方式,也是错过最后期限的好方法.
我可以看到编写像C这样的语言,这对于汇编程序来说基本上是一种更令人愉快的语法,没有库.但是,async-await如果没有那个人和Task<T>你在房间里设计,你怎么可能写?这似乎是一种令人沮丧的运动.
我是否认为语言设计与其基类库紧密耦合?
在C#的情况下,是的,绝对的.为了正常工作,C#语言假定有许多类型可用且已记录.
我曾经和一个开发人员度过了一个非常令人沮丧的时刻,在我发现他编写了他自己的IEnumerable<T>方法与真实方法略有不同IEnumerable<T>之前,他们对foreach循环有一些完全疯狂的问题.解决他的问题:不要那样做.
如何在编译器和运行时内管理这些依赖项?
我不知道如何开始回答这个不可思议的模糊问题.