几乎我所知道的每一种语言基本上都是一个主题的变体:你创建变量和函数,然后使用条件和其他结构来操作它们。我了解函数式编程之类的语言与“传统”语言有些不同,但在本质上它们几乎相同。您仍在使用变量(在某种程度上,即使它们是不可变的等等),并创建函数。
是否有任何语言或系统完全摒弃了我们现在倾向于使用的东西并采用完全不同的方法?
11 回答
尽管您对函数式编程的高调驳斥,但我认为您需要再次查看它,只是这次阅读是为了理解和学习,而不是使用确认偏差将其驳回为“更多相同”。以函数式风格编写代码与以命令式风格编写代码有着天壤之别。但是,如果它对您来说还不够不同,为什么不看看其中的任何一个呢?:
- 以Prolog和 (IIRC) Mercury等语言为代表的逻辑编程。
- 像Forth这样的连接语言非常令人迷惑。
- 函数级编程(与函数式编程相反!)如果这会冒犯您的计算,请摆脱变量。 如今, J几乎是你在这个领域的唯一选择。
- 数组编程与上述非常密切相关。看看APL中的经典示例(尽管J和K都内置了 this 的元素)。
基本上,只需查看数十种可用的编程范式中的任何一种,并阅读描述以进行理解和启发,而不是通过确认偏差来解雇。为每一种语言学习一种语言,这种语言对于你正在使用的“不同”的模糊定义来说完全不同,并且玩得开心。
在图形语言方面已经有过几次尝试。National Instruments的LabVIEW系统可能是最成功的。它使用数据流图和作用于数据的组件。
图形语言的另一种尝试是UML。我猜这个陪审团已经出局了。在标准委员会参与并将其变成适合所有人的东西之前,这可能是一个好主意。
大量机电系统由PLC控制,PLC采用梯形逻辑编程。它本质上是一门用于创建高度可靠的有限状态机的学科,但与过程语言几乎没有相似之处。
然后是深奥、晦涩和替代的语言,它们在很大程度上没有任何实际用途,只是提醒人们图灵完备并不要求语言是明智的。有些人可能会将图灵机本身归入这一类别,但BrainF*ck和Piet在这群人中对我来说真的很突出。
深奥的语言无论何时也是一个有趣的练习,因为它根本没有流量控制。
编辑:我差点忘了Befunge。它的源文本是一个 ASCII 字符网格,其中每个单元格都是一个操作码。执行在四个方向中的任何一个方向上运行,因此可以以四个不同的顺序流过单个操作码。它是另一种深奥的语言,并且被设计为尽可能难(在 1993 年)为其编写编译器。并不是说这实际上阻止了某人这样做。
我指出的几种语言都是深奥的语言。这些通常是具有小(通常只有一两个)用户社区的语言。它们的创建有多种原因,探索图灵完备意味着什么的界限以及一个程序如何代表一个程序是引用的更严重的原因。
所有深奥语言的鼻祖是INTERCAL,它创建于 1972 年。它是一种表面上类似于 COBOL 的语言,但它的许多怪癖要求程序足够礼貌(但不要太礼貌)才能继续执行。支持礼貌,PLEASE DO
是 的一种礼貌形式DO
。一个值得注意的扩展是COME FROM
语句,它可以导致控制从指定位置流到这里。
本身不是一种语言,但模拟计算机在某些方面与更流行的数字计算机完全不同。
好吧,还有皮特。那是很不一样的。(下面是 Piet 中的 Hello World。)尽管如此,您可能会争辩说您正在处理包含一些整数的数据结构(在本例中为堆栈),然后您正在从堆栈中添加和删除内容,操纵值等,所以实际上它仍然是一样的。
这取决于您要问什么,但答案可能是否定的。
原因是当前所有图灵完备的计算机语言都是图灵完备的。这意味着这些语言中的任何一种都可以被该组中的任何其他语言模拟。那么任何编程语言都可以有一个编译器或解释器,可以在我们当前的计算机上运行(近似)。这些在架构上确实具有代码和数据的概念。
因此,如果您认为函数式编程和命令式(“传统”)编程是相同的,因为它们在计算机上运行,那么就没有其他选择了。
代码和数据转化为函数和数据结构(变量)。它们确实允许变化:
另一方面,如何表达程序也可能会有所不同。使用函数组合作为基础可能会将您引向串联编程的方向,尽管数据流编程(包括许多图形语言)和函数式编程也同样支持它。
最后一组表达语言的方法是那些建模为数据结构上的优化或搜索过程的方法:
这都有些学术性。我的建议是尝试确定不同的含义。很可能,函数式编程对于您的目的来说已经足够不同了。
编辑:我刚刚注意到您使用了“使用条件和其他结构来操纵它们”这样的表达方式。控制流构造不必是与代码和数据不同的构造。例如,条件if
可以表示为 afilter
或循环可以表示为 a map
。给定高阶函数和惰性求值,您可以不使用显式if
or for
,仅使用函数和数据结构。这并不意味着你实际上失去了这样做的能力。如果你想看到类似的东西,你可能会对Haskell感兴趣。
此外,请参阅其他看起来不同的语言的答案,例如图形语言和 esortic 语言,同时仍使用控制结构方法应用于数据结构的函数。
好问题。让我们退后一步。在我的第一个问题中,我将尝试解释,您正在寻找的不是一种新语言,而是一种新架构,我敢肯定,您至少知道重要的那些。
20 年前,计算机程序是使用“串行”逻辑构建的,例如 Basic 程序:
10 INPUT "PASSWORD: ";A$
20 IF A$="PASSWORD" THEN GOTO 40
30 PRINT "TRY AGAIN" : GOTO 10
40 PRINT "WELCOME"
MS-DOS 程序也一样:它们运行一段时间,然后等待用户输入,然后再次运行。在 Unix 系统上,即使是多任务系统,游戏也非常相似,不止一个用户可以这样运行程序。
有两个突破波:
- 事件驱动系统:程序流程发生了根本变化(事件处理程序、回调、侦听器);
- Web 系统,尤其是 AJAX:程序运行在不同的机器上(分布式处理、客户端-服务器架构、服务)。
同时,编译和程序构造发生了变化,但我认为少了一些:
- 元编程(基于 IDE 的代码生成器、预处理器),
- 堵塞技术,
- 动态库。
此外,编程目标环境发生了很大变化:
- 虚拟机(Java),
- 解释器平台(PHP),
- 系统服务,
- 构架,
- 门户系统(Drupal)。
一些大而肥的程序变成了平台:
- Lotus Notes(自己的语言,现在:Java),
- MS Excel (Visual Basic)。
我没有提到任何新语言,但即使使用相同的语言,它也可以有如此不同的编程,比如为手机编写 J2ME 游戏和为 Oracle SQL 编写存储过程,两者都是用 JAVA。
也许您正在寻找的不是编程语言。比如说,任务是在浏览器中显示一个数据列表,某种表格。Web 应用程序应如下所示:
- PHP 脚本执行 SQL 查询,模板系统将获得的数据插入到准备好的 HTML 模板中。
- PHP 脚本将从 SQL 获得的数据放入 XML,然后浏览器使用 XSLT 转换将其转换为最终的 HTML。
- JavaScript 应用程序从 PHP 脚本请求数据,该脚本将 SQL 结果以 JSON 格式发回,然后 JS 应用程序呈现最终的 HTML。
HTML+XSLT 是一种编程语言吗?不是。它们是否执行与 PHP 在服务器端执行的任务或 JS 在客户端执行的任务相同的任务?绝对的。是通用平台吗?是的,所有浏览器都支持它。
我认为,有足够多的低级编程语言,我的意思是过程、OOP 或其他图灵完备的语言。新的(少于编程的)语言的目标是更有效:更快的代码生成、更灵活的应用程序、社区工作支持、可扩展性、更容易维护、可重用性等。
(我在这里拆分我的答案;在下一部分中,我将向您展示一个,我正在玩一段时间。)
通读http://en.wikipedia.org/wiki/Programming_paradigm以及右侧链接框中链接的所有页面。根据您的看法,有些是完全不同的,或者它们都基本相同。
查看Forth,这是一个相当不同的系统,其中几乎所有内容都与操作堆栈有关。它几乎就像一个非常原始的小型 VM。
正如我所说,今天有很多平台或环境可以编程。对于某些平台,您可以从一长串语言中进行选择,例如 Microsoft .NET,可以使用 VisualBasic、C# 等进行编程;其他情况下,非常不同的平台使用相同的语言,例如在 Android 中使用的 JAVA、Oracle SQL server 存储过程等。
此外,还有一些非编程语言,它们涵盖了一个领域,或者它们表达了某种配置,这与真正的编程语言相比要简单得多,但可以比编程语言更好地使用。一个例子:PLC 的梯形逻辑编程。
数据流编程就是这种编程之一。让我们看看维基百科,什么是 Dataflow Programming(也称为 Flow-Based Programming):
在计算机科学中,基于流的编程 (FBP) 是一种编程范式,它将应用程序定义为“黑盒”进程的网络,这些进程通过消息传递在预定义的连接之间交换数据,其中连接是在进程外部指定的。这些黑盒流程可以无休止地重新连接以形成不同的应用程序,而无需在内部进行更改。因此,FBP 自然是面向组件的。
来自:http ://en.wikipedia.org/wiki/Flow-based_programming ,另见http://en.wikipedia.org/wiki/Dataflow_programming
维基百科的文章很棒,我已经回答了一些其他问题,所以我不想重复自己。相反,我描述的是用于异步数据流服务器的语言。
有3个语言元素。
组件声明
cmp:比较
这指的是一个名为“cmp”的组件实例,它是一种比较类型。
消息定义
src.out >> cmp.value cmp.gt >> dst1.in cmp.lt >> dst2.in cmp.eq >> dst3.in
点之前的单词是组件实例的名称,点之后的单词是端口名称,左侧的组件-端口对是源,右侧是目标。(端口是用于发送或接收消息的组件的引脚。请参阅 Wkikpedia 文章。)
特性
cmp.base = 8
这定义了组件实例的端口值。
(把这些行放在一起,我们得到一个简短的数据流程序,这意味着:一个值来自 src,cmp 检查它的值,如果大于 8,则将其传递给 dst1,如果小于 8,则传递给 dst2,如果小于 8,则传递给 dst3正好是 8。)
我认为,这种语言符合您的标准,它不是程序性的,没有传统的变量,没有子程序,没有循环。
有趣的是,有一些严肃的项目,它们实现了数据流编程,但他们甚至没有提到它:
(我的数据流项目还没有网页,它正在建设中。)
可以显示数据流程序,也可以将其编辑为图形(请参阅 SynthEdit)。
最重要的不是语言,而是你用它做什么。许多语言会将您推向某个方向,例如 Haskell 之类的纯函数式语言将使命令式编程几乎不可能,但只要您不花时间学习范式,大多数语言看起来都与机器相同实际运行的语言,评估条件并将值分配给内存空间。
范式为您提供了您正在寻找的抽象。好的面向对象或功能代码看起来与您描述的完全不同。你不需要语言来做到这一点。我见过用纯 C 编写的出色的面向对象代码和用 C++ 编写的函数式代码。尽管为正确的工作使用正确的语言会有很大帮助。不幸的是,事情也反过来了。如果您不花时间理解范例,您仍然会在 Scheme 或 Smalltalk 中编写命令式代码。
研究图灵机。Wikipedia 文章列出了一些可以运行程序的模拟器。至少在美学上会有所不同。