为什么F#具有交互模式而不是C#?


32

F#带有交互式REPL,开箱即用。C#没有任何种类,实际上如果不建立完整的项目就很难玩(尽管LINQpad可以工作,并且也可以通过powershell来完成)。

这些语言在本质上有什么不同,这些语言允许F#拥有交互式控制台,但是很难为C#实现它?


由于多年以后,人们仍然会提出这个问题,我应该指出,现在有很多选择。您可以使用Powershell(预装在每台现代Windows机器上)与.Net框架一起使用。或者,您可以使用LINQpad原型化任意c#代码。或者,您可以使用ScriptC,也可以使用在线jsfiddle类型的环境,例如Complify.netJsil。很多选择。


4
C#确实有一个REPL。它称为即时窗口,已经使用了一段时间。它具有一定的局限性,自C#3.0起,其中一些局限性就变得越来越明显,因为它不支持新的语言功能,但它仍然是成熟的REPL。
Allon Guralnek


我记得Roslyn演示项目在2012年左右发布,其中包含针对VS2010的REPL
James

@DanielHakimi:感谢您的评论,我不知道这是否包含在VS2015中,我只认为您可以在调试时使用即时窗口。VS2015现在包含“ C#交互式”工具窗口,可通过“视图”->“其他Windows”->“ C#交互式”访问,该窗口似乎是完整的基于Roslyn的REPL,与调试环境分开。

Answers:


56

这些语言在本质上有什么不同,这些语言允许F#拥有交互式控制台,但是很难为C#实现它?

是。

F#是ML编程语言的后代,而ML编程语言又受到Lisp和Scheme等语言的严重影响。这些语言从第一天开始就被设计为具有三个不错的特性。

首先,这些语言实际上并没有像您在C#中那样对待语句。而是,几乎所有事物都是具有表达式,因此在几乎每种情况下,评估然后打印价值机制都是有意义的。

其次,这些语言不鼓励带有副作用的编程,因此您可以进行评估而不必担心会弄乱全局状态。

第三,您使用这些语言所做的大部分工作都是“顶级的”。通常没有任何封闭的“类”或“命名空间”或其他上下文。

相比之下,C#强调使用产生副作用的语句进行编程控制流,并且这些语句始终位于多个嵌套容器中-命名空间,类,方法等。

因此,所有这些使C#拥有REPL 变得更加困难,但当然并非不可能。我们只需要弄清楚出现在普通上下文之外的语句和表达式的语义是什么,以及改变名称绑定的突变的语义是什么,等等。

为什么F#具有交互模式而不是C#?

因为F#团队认为拥有REPL循环是他们的优先事项之一。C#团队历来没有。除非功能是符合预算的最高优先级功能,否则功能不会实现。到目前为止,C#REPL尚未排在我们的清单顶部。

Roslyn项目具有C#REPL(并且最终还将具有VB REPL,但尚未准备好。)您可以下载它的预览版,以查看您的喜欢程度。

http://www.microsoft.com/zh-cn/download/details.aspx?id=27746


7
Python有一个不错的REPL,它确实有语句,副作用和名称空间。Javascript,Bash等也是如此。许多违反您标准的语言都可以使用REPL。
Lie Ryan

2
欢迎回到埃里克!希望我们能从您那里得到更多答案。
SolutionYogi

16
@LieRyan我想你错过了整点。交互式REPL循环的唯一“条件”是有人坐下来写一个。在F#中,它具有较高的优先级且相对容易,而在C#中则是较低的优先级且相对较难,因此F#较早地获得了优先级,而C#则没有。
KutuluMike

有趣。我要补充一点,在VS2010发行之前为.NET框架构建如此多的编译器(我认为有四个C#,四个VB.NET,两个J#和两个C ++ / CLI)获得的经验必定会影响全新的编译器的使用方式生成了一种全新的.NET语言。我确定它是以Roslyn风格构建的,并且围绕如何启用“即服务即编译”方案进行了大量思考,这似乎是您将来开发所有.NET编译器和编译器修订版的方向。在我看来,F#的诞生不可避免地在其编译器的编写方式中发挥了作用。
Allon Guralnek

好答案。关于Python与C#:{}语法语言不能很好地适应REPL,基于缩进的语言在这里有很大的进步。没想到我曾经想过或说过:缩进语法比{}语法更好。对于REPL以及代码的可读性。因此,只要没有C#元语法可以用{}代替缩进,REPL的经验就不会像F#或Python那样流畅。
citykid 2014年


2

我相信这主要是历史性的事情。REPL环境始终与功能语言(包括ML家族语言)相关联,并且F#忠于该传统。请记住,交互式环境是来自功能背景的用户所理所当然的东西,缺少这种功能将使VS和-扩展名-F#处于不利地位。

另一方面,在OOP社区中没有这样的功能是司空见惯的。

但是,REPL可用于许多非功能性语言,包括C,Java或C#。同样,虽然它与成熟的REPL相比还相去甚远,但VS中的Autos功能表明它肯定可以在C#中使用。


1
这是我所见过的最合理的解释。最初,有Fortran和Lisp,而Lisps则代表。Lisp乞g ...好吧,您明白了。Lisp沿袭语言具有重复性,而Fortran沿袭语言则没有。
亚伦2012年

@Aaron LISP是1959年,但是REPL归功于1973年的LISP机器。到那时,已经有很多语言在出现。尤其是PASCAL和Smalltalk。
Sprague

1

我相信C#主要是面向对象的。要编写最简单的代码,您应该将其分为多个类。要使用REPL,您需要编写大量代码。

F#主要是功能性的,没有这个问题,您可以轻松地编写甚至简单的复杂代码,然后将其转换为对象。

编写一行函数比编写跨越许多行的类要容易。


1
没有什么可以阻止您使用REPL语句中的外部文件中定义的函数/类。OOP更详细的事实本身并不妨碍REPL功能。
scrwtp 2012年

1
Python非常面向对象,并且具有语法上显着的换行符,确实具有不错的REPL。Scala是静态类型的,编译的并且是面向对象的,确实具有REPL。REPL对于诸如导入现有类和调用某些方法之类的简短事情最为有用。语言的详细程度不是问题。例如,SQL非常冗长,但是每个SQL数据库都附带一个REPL(“查询工具”)。
9000
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.