[Coding翻译]编码中的大括号的故事

567 阅读6分钟

副标题:它从哪里来,怎么样,能不能持久?

原文地址:medium.com/better-prog…

原文作者:medium.com/@elye.proje…

发表时间:2020年8月27日 - 7分钟阅读

照片:Clément H on Unsplash

如果你看看我们今天的编程语言,更多的时候,你会发现编程语言中使用了这个奇妙的符号{}

它是干什么用的呢?很简单,它就是告诉编译器(或解释器)代码块的开始和结束。当然,你也可以在一个代码块中拥有代码块。

// A very simple example from C#
public class MyClass
{
    public void myFunction(bool isToPrint)
    {
        if (isToPrint) 
        {
            Console.WriteLine("Hello, world!");
        }
    }
}

有没有想过它是怎么来的?我们应该把它放在哪里?未来的趋势是什么?


它一直存在吗?

不,当计算机刚被发明出来的时候,编程语言和我们今天的编程语言是如此的不同。Michael McMillan的一个优秀的媒介博客写了它的整个历史。

《编程中的大括号简史》

我们每天都在用,但我们代码中的大括号是怎么来的?

我只是把它总结如下(归功于Michael McMillan)。

在ALGO58(1958年)的日子里

当年,积木概念被带入编程中,这是编程界的一大进步。它是通过ALGO58语言引入的。

if x > -1 then
     begin
          if x ≠ 0 then
          x := 1/x
     end;

如你所见,它使用了beginend。清楚,可见。谁看了都明白,不用怀疑什么是{}

在BPCL的时代(约10年后),C语言之父

beginend都很好。但为了使编码更简单、更高效,引入了一种更短的方法,即$($)

IF A < B
     $( LET T = A
          A := B; B := T
     $)

整齐,我们不再需要打字了。但这并没有持续那么久。

C语言(BPCL之后约1年)。

B语言的寿命很短,在1968-1969年间被C语言完全取代。发生了一些语法上的变化,其中之一就是将$($)替换为{}

if (isToPrint == true) 
{
    print("Hello, world!");
}

此后,{}被C语言的衍生语言广泛使用,如C++、C#等。


今天它的情况如何? 我想说它做得很好。大多数编程语言仍然使用{}来表示代码块,可能是基本结构,如if-else,或函数作用域,或类作用域等。这包括C#、C++、Java等语言,也包括新千年引入的语言,如Scala、Kotlin、Swift等。

然而,对于我们应该把{的开头放在哪里,编码界存在着强烈的分歧。按照Jeremy Bytes的解释,有三个阵营

《大括号应该放在哪里?》

在上周末我的一次会议上,有一个问题出现了(《干净的代码:杀人狂也读代码》)。你是否把...

阵营1:我们总是应该把它放在下一行。

这遵循了从beginend时代的惯例。

public void myFunction(bool isToPrint)
{
    if (isToPrint) 
    {
        Console.WriteLine("Hello, world!");
    }
}

原因很简单,它很容易辨认,看起来更整洁。即使是在打印的纸上,也能清晰的看到。C、C++时代,这是著名的风格,现在有了C#,就是这种风格。

阵营二:我们应该始终把它放在块开始的同一行中。

随着编程语言的进步,{不再需要放在下一行。它可以在块开始的同一行中,并节省一些行距。

public void myFunction(bool isToPrint) {
    if (isToPrint) {
        Console.WriteLine("Hello, world!");
    }
}

虽然没有Camp 1那么整洁,但看起来更紧凑。这是在Java时代推出的,从那时开始流行起来的。

阵营3:这要看是结构块还是函数块等。

这是营1和营2的混合体,如果是函数块和类块,应该在下一行。但如果是结构块(如if-elsefor-loop等),则应该在同一行。

public void myFunction(bool isToPrint) 
{
    if (isToPrint) {
        Console.WriteLine("Hello, world!");
    }
}

三号营是最不受欢迎的,因为它不稳定。

接下来会发生什么?

在某一时刻,第一阵营和第二阵营之间存在着强烈的争论,谁的做法是正确的。两个阵营似乎都能从逻辑上证明自己的观点。整齐还是紧凑?哪个会赢?

语文验收办法

根据最新的趋势和网上的参考资料,我找到的唯一坚持营1的语言是C#,因为他们在C#编码指南中说。

引入{},即Gnome C编码标准C++编码指南,呈现出风格混杂,岗位混乱的现象。然而,自Java以来发展的语言都主张朝2营风格发展,如《Java编码指南》《Scala编码指南》《Swift编码指南》《Kotlin编码指南》等(Go、R、Rust、JavaScript、Dart)

通过观察采用Camp 2方法的新语言,虽然连C和C++都没有表现出一致的偏好,但其标志着Camp 2可能是未来的主导趋势。

工具提高了可读性

虽然很多纯粹主义者仍然强烈认为代码应该写在纯文本编辑器(或打印在纸上)仍可阅读的地方,但不可否认的是IDE等工具的进步和改变了我们的代码方式。

工具让代码变得整洁,而且还很紧凑.也就是说,对于1营和2营来说,两全其美,比如,只需折叠函数或类{ },就能让代码变得整洁,不再担心找不到代码块的起点和终点在哪里。

图片由作者提供。

这有助于消除掉Camp 2方法中不那么整齐的缺点,进一步提高代码的紧凑性。

看来Camp 2的一个明显趋势会更加突出。


它会持续多久?

尽管在Camp 1或2中,{}作为表示区块开始和结束的字符,仍然被很好地保留了下来。

然而,有一些迹象表明,编程语言开始远离{}的使用。

在单行if-else中不需要使用{}

我们看一下C语言编码指南,它是这样规定的。

单个语句块不应该使用大括号。

if (condition)
	single_statement ();
else
	another_single_statement (arg1);

而我们看看Java,它有三元操作,如下图,它代替了一个简单的if-else。

// Normal
if (booleanCondition) {
    doThisIfTrue();
} else {
    doThisIfFalse();
}
// Ternary
booleanCondition? doThisIfTrue() : doThisIfFalse();

让我们看看Kotlin,它有一个Elvis操作符,有助于简化null检查。

// Normal
if (myObject != null) {
    myObject.doSomethingWithObject()
} else {
    doSomethingElse()
}
// Elvis Expression
myObject?.doSomethingWithObject ?: doSomethingElse()

功能性编程范式

在过去的几十年里,编程模式已经从程序化到面向对象再到功能化编程。

《为什么代码从程序化到面向对象再到函数式编程?》

通过实际代码示例学习不同风格的编程范式。

在函数式编程中,它鼓励人们使用函数进行工作,而不是强制性地执行其任务。一个简单的例子是for-loop。(Kotlin中的例子)

// 1. Imperative approach
for (it in 1..100) {
    print(i)
}

// 2. Simple functional approach
(1..100).forEach { it -> print(it) }

// 3. Concise functional approach
(1..100).forEach(::print)

你注意到,在最后一个样本中,它显示出{}的消失。

不含大括号的语言

有几个新语言的尝试,试图做到不使用,比如Shell Script结构代码块,不使用curly。虽然函数还是使用了curly。

if [ expression ] 
then 
   statement1
   statement2
else 
   statement3 
fi

如Python,使用缩进级别来反映代码块的开始和结束。

def tri_recursion(k):
  if(k > 0):
    result = k + tri_recursion(k - 1)
    print(result)
  else:
    result = 0
  return result

然而,编程社区长期以来一直停留在{}上,还没有准备好广泛接受一个没有它的编程社区。

尽管如此,我们看到程序员社区的趋势是朝着简洁的编码方向发展。而在工具和技术的帮助下,程序员们也越来越能接受不那么啰嗦的代码。

《已经过时的7种编码风格》

我本来是坚信他们的,但现在我已经改邪归正了。

有一天{}不再用来定义代码块的可能性可能会成为现实,虽然我认为这还需要一段时间。


www.deepl.com 翻译