你自己的(我认为是完美的)编程语言会是什么样子?举一个小例子,解释你的新奇想法!
我真的对语法很感兴趣。
你自己的(我认为是完美的)编程语言会是什么样子?举一个小例子,解释你的新奇想法!
我真的对语法很感兴趣。
有点神秘,但这就是我想要的:
Jon 说得对,“[d]不同的任务适合不同的语言和范式。” 但是,有一些考虑因素在很大程度上与领域无关。这些主要与语法有关,但由于代码的阅读频率高于编写频率,因此我实际上认为语法很重要。
一方面,许多语言都做错了,将语法基于 C 是完全任意的。C 实际上有一个非常糟糕的语法。我只举两个例子。
第一个是毫无争议的:分号是不必要的。采取以下代码;语法是完全明确的,并且易于编译器解析。分号和显式续行都不是必需的。
answer = 42
fraction = answer * 2 /
(answer + 1)
Console.WriteLine(
"Some funny number: {0}",
fraction
)
这实际上与 Python 非常相似,但更为宽松:fraction
跨多行的定义。这是合乎逻辑的,因为第一行尚未完成。
对于类 C 语法,我必须选择的另一个重点是它们在很大程度上是隐含的变量声明。他们没有明确地宣布“我正在声明一个variable
类型Foo
”,而是害羞地低声说“<sub> Foo var
”。由于Foo
在大多数情况下甚至不是保留字,因此这里没有向程序员提供单一的视觉提示。我更喜欢 VB 的显式Dim var As Foo
,甚至认为他在这里使用的关键字非常暗淡。
(实际上,C++ 引入了许多几乎相同且通常含糊不清的语法,这些语法意味着完全不同的东西,从变量初始化到函数声明,实际上让事情变得更糟了)。
我的语言必须具备的另一件事是静态类型。动态类型确实有它的用途,但它们非常罕见。即使是大多数“脚本语言”也并不真正需要它们。我认为这经常与具有更多用途的隐式类型混淆。以(再次)Python 为例。为什么它不提供静态类型?它已经是强类型的,静态类型检查只会随之而来,并且会大大减少调试。显式变量声明也是如此。我看不到隐含的变量声明提供了哪些优势。
所以我们已经有了一个语言的大纲:
此外,我非常喜欢某些 C++ 概念,例如通用模板、RAII(即避免垃圾而不是收集垃圾)、不变性和通过迭代器定义的值范围的概念。我在其他地方说过,我相信迭代器是有史以来最基本的创新之一。给他们一点口红,你甚至不会认出丑陋的 C++ 野兽:
for i in MyVector:
print(i)
而不是
for (typename vector<T>::const_iterator i = MyVector.begin();
i != MyVector.end();
++i)
cout << *i << endl;
当然,我知道许多语言都提供了上述语法。但是它们都只提供了 C++ 强大的迭代器概念的淡化版本(使用 C++ 术语,大多数语言知道的唯一一种迭代器是输入迭代器,它基本上是最不强大的迭代器)。
在这一点上,我可能应该说所有这些想法的唯一版权是我的,正在申请专利(特别是对于不真正比较对象引用的MayOrMayNotBe
操作员)。
我没有“完美”编程语言的概念,因为要执行的任务不止一个。
不同的任务适合不同的语言和范式。
它看起来像 C#。我很想拥有微软!
我完美的语言可以让我根据需要增加功能。如果我需要编写一个没有类的小型直接实用程序,我可以。如果我需要使用类,我也可以这样做,如果我想编写一个完全面向对象的解决方案,我也可以这样做。链接器足够聪明,可以让我创建小型快速命令行实用程序(没有运行时依赖项)或我能想象的最大的臃肿 OOP GUI 应用程序。
问题是我喜欢的东西有相反的目标,因此我总是被迫使用完全不同的语言。我目前不按特定顺序使用 PowerShell、VBScript、PowerBasic、Java 和 C#(有时还有 VB .NET、VB 6、C++、Python 和 Perl)。
现在,如果我可以在创建这些小型应用程序时使用一种类似 C# 的语言来完成这一切,该语言具有全局函数且没有运行时依赖项,但让我在需要时充分利用 .NET Framework 和 Java SDK 的强大功能,我' d快乐。
完美的编程语言往往出现在科幻小说中。例如:
这一切仍然归结为同样的基本困境。任何不强迫人类学习技能的编程语言都会限制思想自由。自然语言也不好,因为它有很多歧义。
我不介意将自由与力量和最少的语法结合起来。我最近开始学习 lisp,到目前为止它似乎非常好。
Amazon Mechanical Turk 支持的大规模并行性。
job = "Upvote this answer"
@price = "$0.01"
fork(10000, job, @price)
我是 C 宏的忠实粉丝,但我认为如果你能用你正在使用的相同语言编写宏或“元代码”可能会很好。(C 是一个不好的例子;这在脚本语言中可能很好。)
在这些示例中,我使用大括号来标识元代码。您将能够通过“预处理器”运行源代码以扩展元代码。否则它只会在运行时扩展一次。
print "Your product ID is: ", { print '"', generateGUID(), '"' }
或者
lookupTable[] = {
/* insert code to generate table here
*
* This lets you modify the algorithm easily
* but speeds up the final program.
*
* This would be especially appropriate in
* cases where you would otherwise type out
* the table as a literal (yuck)
*/
}
有时我们必须编写几行非常重复的代码;现在想不出一个好的例子,但这种想法在这种情况下也会很有帮助。
这与采用 Eiffel 和 C# 的最佳想法并没有太大区别(因为,很明显,我没有提出更好的知识——我一开始没有学过 CS)。
但是,我主要的实际问题是超越经典的“源代码文本”方法。我知道这是(或听起来像)一个 IDE 的东西,但为什么我不能有一个可配置的代码视图,其中包含诸如前置条件/主体/后置条件之类的列,而不是“线性”形式 (i):
function f
// f's preconditions
// f's body
// f's postconditions
end
function g
// g's preconditions
// g's body
// g's postconditions
end
为什么不 (ii) - 想象这是一张桌子(带边框):
f f's parameters f's prec f's body f's postc f's comments
g g's parameters g's prec g's body g's postc g's comments
而且,为什么我不能在样式 (i) 中选择函数“开始”和“结束”(大括号、关键字...)的方式?为什么我不能立即显示或隐藏私人或受保护成员?为什么我不能立即看到包含所有继承功能的“平面版本”?等等
重点不是拥有一个您可以编辑的神圣代码文件,然后是多个“酷视图”,而是能够以 (i)、(ii) 以及对您最有用的任何形式编辑和添加代码。
在某种程度上,在这里谈论“IDE”似乎是题外话。但是OTOH,我认为这迟早会改变我们编写和阅读代码的方式。这将最终影响语言的发展方式。未来的目标将不仅是提高可读性,还要提高“可理解性”和交互性。
多媒体。
我希望能够涂鸦一些图形符号,快速绘制连接,然后切换到其他模式,例如需要精确的打字。
我还认为编程语言应该支持不会用英语思考的人(是的,甚至美国人......开玩笑!)。我学了足够多的日语并尝试学习一些印尼语——我希望看到一种语言支持具有不同语法结构和顺序的人。
我在最近参加的一个关于网络未来的论坛上提出了一个问题,问一位来访的中国教授,他是否认为中文书面语言比英语更有可能实现一个可行的语义网络。他对这个概念很感兴趣。
我读过的很多 SF 都谈到了未来的计算机交互 UI:
Python 对我来说非常接近理想...
一种没有结构或变量,只有一个功能的语言。
doEverything();//根据已经预测的输入自动生成所有内容
我设想一种语言必须被告知输入和变量以及执行顺序的精确限制,因此可以编译成快速的多线程(或可集群)软件。
这里有一个有趣的想法:想象一个“函数”中的所有“语句”都可以按任何顺序执行。如果某些东西依赖于其他东西,您需要显式地“调用”依赖项。这将使并行设计成为语言的一个组成部分。
不幸的是,我没有投入足够的想象力来想出更具体的东西。
Clojure已经非常接近了……
我不确定我梦寐以求的语言会是什么样子,但我对 C 风格的语言有一点改进。我写过多少次这样的东西:
Node foundNode = null; // need stupid null value here to keep track if it was not found
foreach (Node testNode in nodes) {
if (testNode.YesItsMe) {
foundNode = testNode;
break;
}
}
if (foundNode == null) {
// create new instance
foundNode = new Node(blabla);
}
我知道有更优雅的功能方法,但有时你仍然会得到这样的代码。一个简单的“守卫”声明在这里会有所帮助:
Node foundNode; // no need to initialize anymore
foreach (Node testNode in nodes) {
if (testNode.YesItsMe) {
foundNode = testNode;
break;
}
} guard { // we get here if break was never called
// create new instance
foundNode = new Node(blabla);
}
我理想的编程语言,代码会很聪明,它会告诉我它是否与另一段代码有问题,我们会坐下来交谈,它会告诉我它的问题是什么,这样我们就可以解决它......我称之为“情感人++”
我想要一种使工具非常容易正确编写的编程语言。提取方法、着色、自动完成、编译等。
我希望这种情况发生,同时仍然易于编写和阅读。
它看起来与 Scheme 完全一样。只有它会编译为 IL 和 Java 字节码和程序集,所以我可以使用所有这些库。
一种设计语言以满足特定目标。语法和语义应遵循所需的功能。
就我而言,我想要一种具有细粒度并行性的语言,即每粒度的开销非常低,以允许并行化小块代码。
我在 x86 SMP 系统上设计并实现了它,它作为大型软件分析工具的基础已经使用了大约 10 年。
重点是让我(我们)轻松指定并行性:
(|| A B)
并行执行 A 和 B,并让编译器生成所有使这成为可能的 crud。我们不关心语法是否是中缀的,所以我们采用 LISP 风格来避免参数。
这篇论文简要讨论了尽管我们做出了决定,但我们未能成功地避免对语法的争论。
我将从主要功能开始:
目前我发现的最接近我的愿望清单的是Clojure,它满足了大多数这些要求。
由于 OP 指的是语法,我将给出一些代码示例:
适当的变量 arity 函数,支持大型参数列表:
(+ 1 2 3 4 5)
=> 15
(apply + (range 10000))
=> 49995000
在运行时交互式访问编译器:
(def function-string "+")
(def function (compile-string function-string))
(function 7 8 9)
=> 24
分布式代码执行(MapReduce 风格)。请注意,这意味着语言/库能够采用本地定义some-long-running-function
并透明地将其分发到集群中的所有节点,以便在运行时执行。
(def my-cluster
(create-compute-cluster :nodes 100 :service "Amazon"))
(defn some-long-running-function [input]
....)
(def reduction-function
(fn [a b]
(do-something-to-reduce a b)))
(def lots-of-inputs (range 10000))
(distributed-map-reduce
my-cluster
some-long-running-function
inputs
reduction-function)
=> (whatever the result of the mapreduce is over the cluster)
正确的类型推断(即编译器计算出 my-function 总是返回一个 String 并相应地进行优化/推断:
(def my-function [name]
(str "Hello " name "!"))
(my-function "Bob")
=> "Hello Bob!"
(compile-time-type my-function)
=> [java.lang.String :not-null]
我的最佳语言看起来很像 Nemerle(减去任意限制)。真的归结为元编程设施;我应该能够以我认为合适的任何方式(句号)任意扩展或修改语言以完美地适应域。
给我宏,让我可以按照我的意愿处理所有代码的 AST,我可以构建我的完美语言。
它将是机器可读/可写的,它将由智能软件编写,该软件通过语音接收指令。
唔。这是困难的一个。我的口味倾向于易于人类理解的轻量级脚本风格的语言(尽管我相信这适用于更大的应用程序)。见代码片段:
function Foo takes x as string, y as boolean //can add returns [return type] if one wishes to be explicit
//explicit variable declaration
z as number
//explicit cast from boolean to number
z is y as number
//implicit variable declaration
bar is 3 * 5
//function call
print x
return z / bar //since we casted z to a number, it returns a number
我希望看到一个函数能够包含任意数量的引用参数并将它们传递给嵌套函数调用。在 .net 中,可以通过以下方式对任何固定数量的通用参数执行此操作(显示了两个额外参数版本):
// 我忘记了代表的 C# 语法,因为我通常在 vb 中编码 委托 void RefAction<T1, T2, T3>(ref T1 p1, ref T2 t2, ref T3 p3); 点 myPoints[]; void DoSomethingWithIndexedPoint<XT1, XT2>(int index, RefAction<Point, XT1, XT2) theAction, 参考 XT1 xp1, 参考 XT2 xp2) { theAction(myPoints[index], xp1, xp2); }
我的首选语法类似于:
委托 void RefAction<T1, T2, T3>(ref T1 p1, ref T2 t2, ref T3 p3); 点 myPoints[]; void DoSomethingWithIndexedPoint<ref ...>(int index, RefAction<Point, ref ...>, ref ...) theAction, 参考 XT1 xp1, 参考 XT2 xp2) { theAction(myPoints[index], ...); }
其中“...”将由编译器以任何合适的方式自动扩展。这样的设施可以在许多情况下使用 Lambda,而不必生成闭包实例,并且还可以执行以下代码:
Interlocked.CompareExchange(SomeObject["George"], SomeValue, SomeOtherValue);
编译器可以将其重写为类似于:
SomeObject.ActUponProperty("乔治", (ref dest, ref p1, ref p2) => {Interlocked.CompareExchange(dest, p1, p2);}, 一些价值,一些其他价值);
请注意,由于 lambda 表达式不会使用任何实例成员或变量,而不是作为 ref 参数传递的那些,它可以实现为静态函数并且不需要生成闭包。