Language agnostic 预处理器在现代语言中过时了吗?

Language agnostic 预处理器在现代语言中过时了吗?,language-agnostic,preprocessor,language-design,Language Agnostic,Preprocessor,Language Design,我正在为我正在创建的一种简单的宠物语言制作一个简单的编译器,它来自一个C背景(尽管我是用Ruby编写的),我想知道是否需要一个预处理器 你觉得怎么样?在现代语言中,“哑”预处理器仍然是必要的吗?C#的条件编译功能会被视为“预处理器”吗?每一种不包含预处理器的现代语言是否都有适当替换它所需的实用程序?例如,C++预处理器现在大多过时了(尽管仍然依赖于模板)。 < P>预处理器是一种廉价的方法,以一种丑陋的方式向语言提供不完整的元编程设施。 更喜欢真正的元编程或Lisp风格的宏。我认为预处理器是保持

我正在为我正在创建的一种简单的宠物语言制作一个简单的编译器,它来自一个C背景(尽管我是用Ruby编写的),我想知道是否需要一个预处理器


你觉得怎么样?在现代语言中,“哑”预处理器仍然是必要的吗?C#的条件编译功能会被视为“预处理器”吗?每一种不包含预处理器的现代语言是否都有适当替换它所需的实用程序?例如,C++预处理器现在大多过时了(尽管仍然依赖于模板)。

< P>预处理器是一种廉价的方法,以一种丑陋的方式向语言提供不完整的元编程设施。
更喜欢真正的元编程或Lisp风格的宏。

我认为预处理器是保持语言表达能力差的支柱


我看到过很多对预处理器的滥用,我非常讨厌它们

C的预处理可以做一些非常好的事情,但是如果你看一下它所使用的东西,你就会意识到它通常只是为了添加另一个抽象层次

  • 不同平台上不同操作的预处理?它基本上是一个独立于平台的抽象层
  • 可以轻松添加复杂代码的预处理?抽象,因为语言不够通用
  • 在代码中添加扩展的预处理?抽象,因为您的代码/语言不够灵活
所以我的答案是:如果您的语言足够高级,就不需要预处理器。我不会说预处理是邪恶的或无用的,我只是说语言越抽象,我就越没有理由认为它需要预处理

*什么是足够高的层次?当然,这完全是主观的


编辑:当然,我只是指宏。使用预处理器与其他代码文件接口或定义常量是有害的。

预处理器是编译的一个独立阶段。 虽然预处理在某些情况下是有用的,但它可能导致的头痛和错误使其成为一个问题

在C语言中,预处理器主要用于:

  • 包括数据——虽然功能强大,但最常见的用例不需要这样的功能,“导入”/“使用”功能(如Java/C#)使用起来更干净,很少有人需要剩余的用例
  • 定义常量-为什么不提供一个“const”语句呢
  • 宏-虽然C风格的宏非常强大(它们可以包含诸如returns之类的语句),但它们也会损害可读性。泛型/模板更简洁,虽然在某些方面功能较弱,但更易于理解
  • 条件编译——这可能是预处理器最合法的用例,但对于可读性来说,这又是一件痛苦的事情。在特定于平台的源代码中分离特定于平台的代码,并使用公共if语句,最终会更好地提高可读性

  • 因此,我的答案是,尽管预处理器功能强大,但它会损害可读性和/或不是处理某些问题的最佳方法。较新的语言倾向于认为代码维护非常重要,并且由于这些原因,预处理器看起来过时了。

    < P>这是你的语言,这样你就可以在语言本身中建立任何你想要的能力,而不需要预处理器。我认为不需要预处理器,它在语言的基础上增加了一层复杂性和模糊性。大多数现代语言没有预处理器,而C++中,只有当你没有其他选择时才使用它。p>
    顺便说一下,我相信D在没有预处理器的情况下处理条件编译。

    这完全取决于您提供的其他功能。例如,如果我有一个常量int N,你是否提供给我取N个变量?如果有N个成员变量,用一个参数来构造它们?创建N个函数?执行N个不一定在循环中工作的操作(例如,传递N个参数)?N模板参数?条件编译?不是整数的常数


    C预处理器在适当的人手中是如此强大,你需要制作一种非常强大的语言来保证它的正确性。

    预处理器是不必要的。对于真正的元编程,您应该有类似MetaML或Template Haskell或Healthy macrosála Scheme的东西。对于快速和肮脏的东西,如果您的用户绝对必须拥有它,那么总会有
    m4

    然而,现代语言应该支持与C的
    #行
    指令等价的指令。
    这些指令使编译器能够定位原始源代码中的错误,即使该源代码嵌入到解析器生成器或词法生成器或可读程序中。换句话说,

    • 设计语言,使其不需要预处理器
    • 不要把你的语言和一个幸运的预处理器捆绑在一起
    • 但是,如果其他人有自己的理由使用预处理器(解析器生成是一种流行的方法),请提供对准确错误消息的支持

    我想说的是,尽管您应该避免使用预处理器,但它仍然是必要的

    例如,在C++中,为了编写一个单元测试库,必须有一个预处理器。他们以两种不同的方式使用它:一种用于断言扩展1,另一种用于在测试用例2中嵌套部分2

    但是,在C++中编译前的计算不应该被滥用,在这里可以使用const表达式和模板元编程。


    对不起,我没有足够的声誉来发布两个以上的链接,所以我把这个放在这里:

  • github.com/philsquared/Catch/blob/master/docs/assertions.md
  • github.com/philsquared/Catch/blob/master/docs/test-cases-and-sections.md

  • 其他人已经指出了很多