Synth Daily

可视化编程困于形式

视觉编程长期以来受限于“节点-连线”的固定形式,因为它过于关注外观,而忽略了驱动形式的底层功能。遵循“形式追随功能”这一核心设计原则,真正有效的视觉编程应该先弄清楚其内在逻辑,让视觉表现自然而然地产生。文章以 CellPond 为例,说明其复杂的视觉效果源于一个简单的底层虚拟机。要突破当前困境,我们不应再尝试将传统的文本编程概念可视化,而应探索如何利用人类视觉皮层强大的模式识别能力来直接建模问题,包括实体、关系以及状态的转换,最终目标是找到一种仅在视觉上才有意义的全新计算语法。

核心问题:困于形式,而非功能

许多伟大的创作,无论是艺术还是技术,其外在形式都由其内在逻辑(即功能)驱动。然而,视觉编程领域似乎陷入了一个误区:过于执着于形式,尤其是“节点-连线”的图表模式,而忽略了真正应该驱动它的底层功能。

当你把底层的东西理顺了,用户界面(UI)自己就想通了。

这个领域之所以停滞不前,是因为设计者们试图凭空创造一种形式,而不是先深入理解其功能,再让形式自然浮现。

来自 CellPond 的启示

CellPond 是一个视觉编程语言,它展现了惊人的视觉效果,但其精髓并不在于此。它的真正突破在于其背后有一个仅包含四种操作的虚拟机,这些操作对应于我们熟悉的内存操作:读取、写入、分配和释放。

  • 形式: 网格中的各种复杂图案。
  • 功能: 底层的虚拟机。

这个例子完美地展示了“形式追随功能”的原则。一旦底层的功能被清晰定义,上层的视觉界面便水到渠成。这表明,视觉编程的突破口可能不在于设计更华丽的界面,而在于找到正确的底层抽象。

理解“形式追随功能”

这个原则常被误解。它不是给旁观者的描述,而是给创造者的行动指南。简单来说就是:

如果一个设计是好的,那么它的外观、感觉和工作方式都是其功能、规则和内在本质的直接体现。要设计形式,你不应该凭空捏造。你必须首先解决它的功能问题。

一个设计的“功能”包含三个方面:

  • 适应环境: 设计必须与其所处的环境和生态位契合。就像动物的形态是为了适应其生存环境一样。
  • 内部一致性: 好的设计会在不同场景下重复使用相同的解决方案,具有一种内在的对称性。例如,游戏中的一个道具可以有多种用途。
  • 代数规则: 设计的各个部分如何组合和互动,遵循一套明确的规则。例如游戏中的物理引擎或化学引擎。

如果一个形式没有坚实的功能作为支撑,它就会显得杂乱、不一致且令人困惑。功能让设计师保持诚实

为何“节点-连线”模式是失败的

“节点-连线”图已经成为视觉编程的一种懒惰的默认选项。大多数设计者都在模仿一种现有的形式,而不是从根本上思考它是否真的有帮助。

这种模式的流行,源于一个根本性的错误假设:视觉编程的底层逻辑与传统文本编程是一样的。基于这个假设,人们自然会认为只需为现有的文本语言结构找到视觉对应物即可。

然而,这种做法存在严重缺陷:

  • 难以区分定义与调用: 在节点图里,函数的定义和调用常常混为一谈。
  • 无法良好表达高阶函数: 纯函数式编程的威力在于高阶函数,但节点图很难清晰地表示它们。
  • 对命令式编程没有优势: 用节点图表示一个循环,并不比用文本写出来更清晰,也无法帮助开发者理解复杂的状态变化。

“节点-连线”只在少数特定领域取得了成功,例如游戏引擎中的着色器或声音合成,因为在这些领域,观察中间数据状态有巨大价值。但在通用编程领域,它并未取得突破。

新方向:为视觉皮层建模

与其继续将文本编程概念可视化,一个更好的问题是:我们应该如何建模问题,才能充分利用我们视觉皮层的计算能力?

人类的视觉皮层是一个强大的模式识别机器,能瞬间比较长度、区分前景背景、识别空间模式。我们在数据可视化中利用了它,但在理解计算系统方面却做得远远不够。

一个真正有效的视觉编程语言,应该能让我们在任何抽象层级上,一眼就能理解程序的整体结构和状态

建模实体与关系

任何系统都包含两个方面:实体和它们之间的关系。视觉编程的突破口可能在于如何有效地将这两者视觉化。

  • 实体(Nouns): 比如数据结构、对象。如何将它们可视化并没有标准答案,最佳的视觉表现形式取决于用户的任务和意图。例如,一组坐标数据,用散点图就比用两个独立的直方图更能揭示其空间关系。
  • 关系(Verbs): 实体之间的互动,如函数调用、消息传递等。我们习惯用线条或箭头表示关系,但这在复杂系统中很快会变成一团乱麻。除了线条,我们还可以利用颜色、空间聚集和动态来表示关系,这些都是视觉皮层非常敏感的元素。

建模状态的演变

一个静态的模型是不够的,程序的核心在于计算——即状态如何随时间或外部输入而演变。我们需要一种视觉化的方式来表达状态转换的规则。

细胞自动机通过规则集来表达计算,即从当前状态到下一个状态的映射。但随着行为变得复杂,规则的数量会爆炸式增长。我们需要的是一种能够简洁地表达“一组状态如何映射到下一个状态”的方法,而不仅仅是单个状态的映射。

结论:寻找新的计算语法

视觉编程之所以没有成功,是因为它一直试图为那些本身就不适合视觉化的传统编程范式“套上”一层视觉外壳。

前进的道路是停止模仿,转而专注于发现一种全新的底层功能。我们必须找到一种方法,在视觉画布上对问题进行建模——不仅是实体和关系,还包括它们的状态转换。

我们拥有强大的硬件——我们的大脑视觉皮层。我们缺少的,是一套能与之匹配的计算语法。一旦我们找到了这种只在视觉上才有意义的新功能,正确的“形式”自然会随之而来。