fsi.exe是解释器吗?

时间:2011-12-30 15:18:02

标签: .net f# read-eval-print-loop fsi

我已经读过fsi.exe(F#Interactive)在严格意义上不是真正的“解释器”,因为它动态编译 F#代码并显示其输出。

我的印象是“解释器”一词适用于“动态”语言(即JavaScript),因此不适用于F#,因为它是一种编译语言。

这是一个公平的评估吗?或者编译语言可以“解释”吗?或者这只是一个语义问题?

感谢任何帮助。

5 个答案:

答案 0 :(得分:3)

编译和解释之间的差异很模糊。事实上,被视为“解释”的许多语言经常被编译为本机代码(例如,具有v8的JavaScript)。动态语言eval的最动态特性的一些实现只是编译的包装(例如,在SBCL中)。

当然REPL与编译或解释无关,REPL可以构建在任何执行模型之上。 fsi只是一个REPL,它使用与fsc相同的F#编译器核心。

答案 1 :(得分:2)

除了Scholastic论点之外,与FSC编译为可执行文件的代码相比,FSI执行的代码运行时没有明显的性能下降。 在这方面,F#有利地与OCaml进行比较 - 看看Harrop对OCaml toplevels的评论。

答案 2 :(得分:2)

  

我的印象是“解释器”一词适用于“动态”语言(即JavaScript),因此不适用于F#,因为它是一种编译语言。

     

这是一个公平的评估吗?

没有。 “解释器”一词指的是执行程序的方式。如果源程序是通过一个名为“interpreter”的独立程序运行它来执行的,该程序通过解释源程序中每条指令的含义来执行它,那么它就会被解释。

术语“动态编程语言”似乎没有正式的定义,只是非正式地使用它来引用动态类型语言(即缺少静态类型系统的语言,因此,推迟所有类型检查运行-time)或实现的编程语言,使其能够在运行时具有功能,例如宏,反射,REPL等。这与程序是否被解释或编译无关。例如,Common Lisp被认为是一种动态语言,OCaml被认为是一种静态语言(虽然它同时包含宏和REPL),但是解释器和编译器都可用于Common Lisp和OCaml。

  

或者编译语言可以“解释”吗?

同样,术语“编译语言”是不明确的。任何语言都可以被解释或编译。形式上,任何可执行语言都可以被解释,任何解释器都可以通过在源程序上部分专门化而变成编译器。

请注意,某些编程语言实现同时使用编译和解释,以获得两个世界中最好的一些。例如,OCaml可以使用OCaml编写的编译器将程序编译为字节码,然后由C编写的解释器解释字节码。这有几个优点:

  • 比普通的任期翻译快得多。
  • 比针对像x86这样的机器代码的本机代码编译器简单得多。
  • 编译阶段可以执行优化(例如,大步语义),解释器可以从中获益,而无需查看。
  • 简单易于在C语言中编写解释器,从而进一步提高性能。
  

或者这只是一个语义问题?

术语。

答案 3 :(得分:1)

查看interpreter Wikipedia article,我们发现:

  

解释器可能是一个程序......将源代码转换为一些有效的中间表示(代码)并立即执行此操作。

......适用于FSI。

答案 4 :(得分:1)

当您说JavaScript是“动态”时,通常表示“动态类型”,这与它通常被实现为解释语言而不是编译。与“动态类型”相反的是“静态类型”。请注意,这是一个不同的属性,然后由“弱类型”和“强类型”描述。这两个属性与解释器和编译器无关,除此之外,脚本语言(几乎总是被解释)的趋势是动态类型化的。

编译器显然是(实际上,问题正是关于作为解释器的编译器,但是为了参数而放弃这个)而不是解释器,所以如果你将一些源代码编译成一个对象文件并执行它,你会认为它显然没有被解释。但事实证明,这不是一个非常明确的界限。如果您认为 emulators 是解释器,那么无论使用何种语言,您都可以解释任何可执行文件。还有二进制翻译和JIT编译器,他们的字节码混淆了已经混乱的问题。但请注意,这里的混淆是完全语义的,解决方案可能只是一组更新的定义。

相反,您可以通过记录解释器在解释程序并将其作为编译程序播放时所执行的操作来“编译”任何解释语言。这不是完全编译,它不会比解释器更有效,但重点是被解释不是语言的内在质量。

因此,传统上编译的语言可以,有时可以实现为解释语言。那里甚至还有C语言的翻译。我相信这回答了你的问题。我认为关于F#的观点是即使它是交互式的,根据最严格的定义,它也不是真正的解释器。这是因为它编译了一些代码,然后运行它们。这并不意味着由于语言的某些属性而无法编写F#的严格解释器。