【问题标题】:What is a first class programming construct?什么是一流的编程结构?
【发布时间】:2009-03-14 21:43:47
【问题描述】:

当尝试在 C# 中做一些相当高级的事情(比如某种 hack)时,会提出“一流”的概念。

例如,方法是一流的编程构造,因为您可以用它来做 xyz(xyz 不是方法所做的,而是方法通常给您的,我不记得现在 xyz 是什么了),但在 .NET 1.1 中,委托无法传递给方法,因为它们不是一流的编程构造(我读过一些类似的东西)。

究竟什么是一流的编程结构?

谢谢

【问题讨论】:

    标签: .net


    【解决方案1】:

    "first-class citizen" or "first-class element" 在编程语言中的概念是由英国计算机科学家Christopher Strachey 在 1960 年代在一流函数的背景下引入的。这个原则最著名的表述可能是在 Gerald Jay Sussman 和 Harry Abelson 的 Structure and Interpretation of Computer Programs(就在 Exercise 1.40 之前):

    • 它们可以由变量命名。
    • 它们可以作为参数传递给过程。
    • 它们可能作为过程的结果返回。
    • 它们可能包含在数据结构中。

    基本上,这意味着你可以用这个编程语言元素做你可以用编程语言中的所有其他元素做的所有事情。

    【讨论】:

      【解决方案2】:

      我怀疑你找不到正式的定义 Apparently Jörg W Mittag found one :)

      鉴于这个正式的定义,我剩下的答案只是我当时对它的理解。当然,使用“一流构造”一词的每个人是否意味着完全相同的东西是另一回事。

      确定某事物是否是“一流”构造的方法是这样问自己:

      是否支持该功能并且 与其余部分完全集成 语言,或者有很多 不必要的限制 刚刚的印象 “固定”可能只是为了解决 一个特定用例,不考虑其他领域 该构造可能非常有用 如果它更充分地“成为 语言”?

      如您所见,这是一个明确的灰色区域 :)

      实际上,C# 中的委托就是一个很好的例子。在 C# 1 中,您可以将委托传递给方法,并且有很多方法可以将它们很好地集成到语言中(例如可用的转换、事件处理、+ = 和 -= 转换为 Delegate.Combine/Remove)。我会说他们一流的构造。但是,这并不与委托从 C# 2 和 3 中获得巨大的事实相矛盾,包括匿名方法、隐式方法组转换、lambda 表达式和协变。它们现在可以说是更多一流的构造......即使我会说它们是 C# 1 中的“一流”,我也能理解为什么有人可能不同意。

      IEnumerable 可能会出现类似情况。在 C# 1.0 中,foreach 支持它,但 foreach 循环不会在最后处理 IEnumerator。这部分在 C# 1.2 中已修复,但仍然只支持 消费 IEnumerables 的语言, 不创造它们。 C# 2.0 提供了迭代器块,这使得实现IEnumerable(及其通用等效项)变得微不足道。这是否意味着可迭代序列的概念不是 C# 1.0 中的“一流”构造?值得商榷,基本上……

      【讨论】:

      • 很好的解释(以及对所有其他人)。这当然是一个灰色地带:)
      • 约尔格的回答没有提供正式的定义吗?
      • @Rich:看起来像 - 没见过。有机会会编辑。
      【解决方案3】:

      究竟什么是一流的编程结构?

      如果语言支持它以类似于其他类型的对象的方式,则某事物是一流的构造。

      例如,在 C++ 中,函数不会被视为一等构造:您可以在运行时创建其他类型的对象,但不能实例化新函数。相比之下,在 C# 3 及更高版本中,函数可能会被视为引入 lambdas/匿名函数的一流构造。

      与许多其他事物一样,这自然是一个主观定义。维基百科有a good summary 提供更具体的示例,C2 也是如此。

      【讨论】:

      • 从 C++0x 开始,现在略有不同。
      • 如果 C++0x 成为真正的标准,你可以说“是”。直到那时它“可能最终成为”。 :)
      【解决方案4】:

      The C2 wiki has a good entry on first class language constructs. 基本上,这是你不必在语言中伪造的东西。

      【讨论】:

        【解决方案5】:

        我对一流编程结构的理解是,它意味着您可以以最好的方式完成事情,而不必做两三件其他事情,或者结合两个或三个其他概念。

        因此,Java 没有一流的闭包支持。但是,我们可以通过构建一个支持几乎所有您使用闭包的东西的类(使用另一个概念)然后创建该类的实例(另一个概念)或匿名扩展该类( 又一个概念)。

        与“功能”相同。在 Java 中你不能有函数,但你可以有静态方法,这是一个相似但仍然不同的概念。

        一个人(不是我)也可能争辩说 Java 的泛型支持不是一流的,因为它是一种库 hack,实际上并不是“在”该语言中的。这意味着您可以在 C# 中使用泛型执行的某些操作在 Java 中无法执行。

        【讨论】:

          【解决方案6】:

          究竟什么是一流的编程结构?

          简单的答案:它支持该语言提供的所有标准操作。在面向对象的语言中,如您所料,第一类构造是对象。事实证明,在此类语言中,出于效率或遗留原因,通常存在二等公民,通常是原始数据类型,它们不是适当的对象,并且您不能对其进行某些操作。

          例如,在 Java 中,Point 是一个成熟的对象。你可以声明一个

          List<Point> plist;

          然后将积分放入其中。 int 不是一个成熟的对象。有些事情你不能用一个 int 来做——例如,它的子类,或者除了一些预定义的运算符之外调用它的方法。您也不能将其存储在

          List<int> intlist;

          Java 可以解决这个问题,因为它有一个“盒装”类型 Integer,它是一个完整的对象。例如,您可以声明 List<Integer>。但是,使用 Integer 的效率远低于使用“int”。 Java 提供了 Integer 类型到 int 的自动装箱和拆箱(即转换),并在需要其中一种或另一种的上下文中再次返回,以帮助程序员结合两全其美。

          对于整数有两种类型——整数和整数——是令人困惑的,而且是一种黑客行为。有人告诉我,Java 的早期版本没有原语,它的所有类型都是成熟的对象。结果证明这对于它的预期用途来说太慢了(当然,早期的 Java 还是很慢!)所以添加了一些不支持正确对象语义的原语。

          在 .NET 1.1 中,委托无法传递到方法中,因为它们不是一流的编程构造(我读过一些类似的东西)。

          我对 .NET 一无所知,但您似乎有这个想法。你是对的——如果委托不能像任何其他标准对象一样被传递到方法中,它们就不是一流的编程构造。

          【讨论】:

            猜你喜欢
            • 2014-04-15
            • 2017-05-07
            • 1970-01-01
            • 1970-01-01
            • 2014-03-01
            • 1970-01-01
            • 2010-10-23
            • 2023-03-21
            • 2016-12-02
            相关资源
            最近更新 更多