Bill Gosper说数据结构只是一种愚蠢的编程语言意味着什么?[关闭]


16

小拉尔夫·威廉·高斯珀Ralph William Gosper)的话说:

数据结构只是一种愚蠢的编程语言。

他是什么意思?las,我在Google上能找到的就是对报价本身的无休止的复制/粘贴,没有任何上下文。



1
这种问题现在正在我们的元讨论站点上进行讨论

有图灵完全类型系统的语言。其中有些很愚蠢。
SK-logic

@ SK-logic:图灵系统是完整的还是其他类型,与这个引用有什么关系?
missingfaktor 2011年

1
@RehnoLindeque,您见过Agda或Coq吗?类型可以是图灵完备的。
SK-logic

Answers:


10

好吧,似乎声明的核心是:

数据结构只是一种...编程语言

如果您考虑一下,那是真的。毕竟,编译器一直都依赖于这种可传递性。他们采用一种编程语言,将其转换为数据结构,对该数据进行一些转换,然后将结果转换为另一种编程语言。

实际上,如果您愿意,甚至可以使诸如C数据结构之类的东西变得疯狂,它可以让您通过调用其各种方法来编写C代码-例如(在某种C#中,因为这就是我现在正在使用的):

var C = new HorribleCObject();
C.Function <int>(“ main”,typeof(char [] []),typeof(int))
  .Variable(“ i”,typeof(int),0)
  .while(“ i”,Func(i)=> i <10))
     .Call(“ printf”,“%d”,“ i”)
     .PostIncrement(“ i”)
  .EndWhile();
  。返回(0)
 .EndFunction();

现在,关于全部引文:与用C本身编写(比如说)相比,为什么这样的事情愚蠢?很明显,这是冗长的,并且不如C中的等效语言清晰((实际上,可能不支持C可以做的全部工作-typedef很棘手));因此,这种数据结构只是嵌入在“真实”编程语言中的“愚蠢”编程语言。可以将相同的逻辑推广到您可以想到的任何数据结构。链表只是Lisp的“愚蠢”版本,哈希映射只是某些理论上的哈希编程语言(Hasp?)的“愚蠢”版本。

事实是,我们并不总是想要编写Hasp以便与我们的哈希图进行交互。这是所有领域特定语言都存在的问题-一方面,一个实现良好的DSL足够强大,可以表达基础模型可以做的一切;另一方面,您必须首先实现DSL,然后其他人必须学习它。这需要他们可能不想花费的时间和精力。毕竟,我只想将事物放入哈希映射中,然后检查其中是否包含其他事物,我不想学习面向哈希的编程的所有复杂性。

因此,几乎不用考虑,我们就采用了这些理论上高度特定和非常聪明的编程语言,并将它们提炼为数据结构中体现的少数愚蠢的操作。链表中有一些简单方法。哈希图还有其他一些。我们忽略了可能会在数据结构上执行的其他更强大的操作(例如,大多数LinkedList实现没有.Map或.ForEach函数,而且我什至无法想象在Hasp中会做什么),支持以父编程语言显式实现它们-这是大多数程序员都将熟悉的语言。

从本质上讲,数据结构是其父语言在概念上表示的问题空间的愚蠢扩展。一个足够聪明的扩展程序将需要一种新的特定编程语言,并且大多数人都不想学习它。


2

数据结构是一种编程语言的表示。但不是特别“犀利”的。

可以从“节点图”中看到,就像下面的Wiki文章中的那样:

http://en.wikipedia.org/wiki/Root_node#Terminology

尽管如此,数据结构作为一种编程语言还是不完整的,因为它缺乏语法和完整的思想,程序员无法理解。可以将数据结构的“语言”与一个说“我,冷,穿上外套”之类的孩子进行比较。

“语言”很容易理解,但可以理解。孩子在说“他/她很冷,想要盖多件衣服”。孩子的话语是英语的“愚蠢”版本,同样是与编程语言有关的数据结构。


1

我相信Bill Gosper的意图是所有数据结构只是适用性有限的编程结构。这也与“语言设计是图书馆设计而图书馆设计是语言设计” [1]的思想有关。

思考该问题的一种方法是仅基于算法考虑数据结构。暂时不要考虑存储需求或类型注释,因为它们只是辅助的。

例如,您可以map通过两种方式来编纂关联数组(在某些语言中称为a ):使用存储在内存中的某种索引或使用简单的case表达式。

在Haskell中,您可以将关联数组编码为数据结构...

let assocArray = [("a", 1),("b", 2),("c", 3)]
let key = "b"
lookup key assocArray

...或通过使用case表达式...

let key = "b"
case key of 
  "a" -> 1
  "b" -> 2
  "c" -> 3

甚至更直接地

let key = "b"
if key == "a" 
  then 1 
  else if key == "b"
    then 2
    else if key == "c"
      then 3
      else undefined

通过查看lambda演算,很容易看到在数据结构和代码之间的这种镜像是可能的。λ演算中的函数可以表示任何值,并且演算本身是通用的(图灵完成)。

[1]引用感谢Bjarne Stroustrup。


0

考虑一下Javascript,其中所有数据都是代码。考虑一下LISP,其中所有数据都是代码,而所有代码都是数据。

在开始,结束以及之间的任何地方,数据都只是位。我们试图用文本和符号对位进行本体化,以使它们易于人类理解和转换,这是抽象的一层,需要a)学习定义语言,b)学习抽象的漏洞。

例如,在C#中,了解结构和类之间的区别要求您了解值类型和引用类型之间相等性比较的区别。每个数据本体都需要您必须学习并遵守的一组规则。并且,与任何语言一样,它使您可以快速了解一般概念,但是您越想接近问题的真实情况,您就应该越多地看一下二进制文件。

最后,当考虑使用B树或类似的数据结构时,在树的结构上导航并对其执行其他类型的操作需要一种特殊的语法,这种语法不一定可以在树,结构或语言之间传递。


3
我不确定这是否真正成为问题的核心。例如,通用编程专门针对与数据结构无关的算法(通常使用迭代器或范围)。
乔恩·珀迪

4
您确定这就是Ralph William Gosper,Jr.的实际意思吗?
罗伯特·哈维

在Common Lisp中,并非所有数据都可以编译为代码,但是所有代码都可以视为数据。语法规则并不多,但是至少在宏处理之后,所有代码都必须是S表达式,并且并非所有数据都是S表达式。
David Thornley
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.