数据结构应该集成到语言中(如Python)还是在标准库中提供(如Java)?


21

在Python以及最有可能的许多其他编程语言中,可以将常见的数据结构作为具有专用语法的核心语言的集成部分。如果我们不考虑LISP的集成列表语法,我想不出任何其他知道的语言,它们在数组上方提供某种数据结构作为其语法的集成部分,尽管所有这些语言(但我猜都是C)似乎在标准库中提供了它们。

从语言设计的角度来看,您对在核心语言中为数据结构使用特定语法有何看法?这是一个好主意吗?语言(等等)的目的是否会改变它的选择余地?

编辑:很抱歉(显然)引起了我所指的是哪种数据结构的困惑。我谈论的是基本的和常用的,但仍然不是最基本的。这不包括树(过于复杂,不常见),堆栈(很少使用),数组(过于简单),但包括例如集合,列表和哈希图。


1
我们要排除对象和哈希图吗?
2011年

3
@Anto:嗯许多语言都具有关联数组,Perl和PHP,JS(这里技术上的对象)等形式包含HashMap
Orbling

1
也许除了阵列,列表,哈希图/关联阵列之外,您还可以更具体地了解正在考虑的数据结构?
FrustratedWithFormsDesigner

1
包括哈希图,列表以及“复杂数据结构”等更高级的内容,并把数组过于简单就扔掉。
Anto

1
我认为一个更合理的标题应该是:“该语言应包含哪些数据结构,而库中应包含哪些数据结构?” 但是,有意义的答案在很大程度上取决于语言:库与语言的集成程度越高,将结构移入库越合理。
杰里·科芬

Answers:


13

这取决于语言的用途。

一些例子(从其他答案中偷来的):

  • Perl对哈希表,数组,字符串具有特殊的语法。Perl通常用于脚本编制,这些对脚本编制很有用。
  • Matlab对于列表,矩阵,结构具有特殊的语法。Matlab用于工程的矩阵和矢量数学。
  • Java / .NET支持字符串和数组。这些是通用语言,其中经常使用数组和字符串(使用新的集合类越来越少)
  • C / C ++支持数组。这些语言不会对您隐藏硬件。部分支持字符串(不连接,使用strcpy等)

我认为这取决于您的语言的目的/精神/听众。您想要它多么抽象以及离硬件有多远。 通常,将列表支持为原语的语言允许您创建无限长的列表。虽然像C / C ++这样的低级语言将永远不会拥有这些语言,因为这不是这些语言的目标,而是精神。

对我来说,垃圾回收遵循相同的逻辑:语言的听众是否关心确切地知道何时以及是否分配或释放内存?如果是,则malloc / free; 如果否,则进行垃圾回收。


6
这是使用术语“ C / C ++”的不好地方,因为C ++中高级模板类型的存在是两种语言之间的主要区别。
dan04 2011年

垃圾可以以确定性的方式进行收集,您只需要线性类型(或其穷人的替代品:RAII)。
pyon

@EduardoLeón,尽管您可以在确定性点调用垃圾回收,但我认为它运行的时间不会是确定性的(出于同一原因,malloc并且new在C / C ++中是不确定性的)。
earlNameless 2013年

@earlNameless:它相对于资源的使用是确定性的:线性类型(或相似的唯一性类型)使它成为类型错误(并因此导致编译错误),以不释放资源(对可能性进行模运算,未由类型捕获)系统,任何异常程序终止),或在处理完之后再使用它们。
pyon

5

Perl具有哈希图,PL / SQL支持记录,而我对matlab的记忆非常模糊,其语法支持所有不同维度的向量和矩阵(尽管我对此可能是错误的,并且可能会争辩说,这些是数据类型而不是数据类型)结构)...我想说,对非常常见的结构具有一些本机支持是很高兴的。通常看来,数组和哈希图/关联数组是最常见的本机支持结构,它们也可能是最常用的结构。

不要忘记,如果您为其他结构(例如二叉树)添加了本机语法支持,那么这些结构也已经由语言的支持工具(编译器/运行时/等)实现了。您要支持多少个结构?

您将不得不为不太常用的本机结构发明新的表示法...保持简单!


不需要为例如树发明文字语法-它们很少见,甚至在许多语言的stdlib中也是如此!出于同样的理由,有人可能反对将运算符包括在内,因为“您必须为不常用的运算发明新的符号”。

@delnan:我的理解是从设计一种新语言的角度出发,并且想知道是否应该(可能)通过新语法本地支持数组以外的数据结构,或者是否应该通过包含库来支持它们。
FrustratedWithFormsDesigner

好吧,第一句话明确地谈到了“通用数据结构”,因此我认为OP 不够疯狂,无法尝试为每一个发明的晦涩数据结构添加特殊语法。

@delnan:...然后,OP继续排除LISP列表和数组(通常)“ ...抛开LISP的集成列表语法,我想不出任何其他我所知道的语言,它们提供了某种数组上方的数据结构作为其语法的集成部分” ...所以我认为他们正在思考比数组/列表更具有异国情调的数据结构...
FrustratedWithFormsDesigner

是的(我将“数组上方”解释为“其他常见数据结构”),但问题中没有任何提示“让我们为我们拥有的每个单个数据结构制造字面量”。很好地说,这应该限于合理范围内,但我认为我们不能仅凭此假设就说“坏主意” 。

5

我最喜欢的例子是Lua。Lua只有一个内置的数据类型“ ”,但是它的灵活性和速度意味着您实际上可以使用它们代替常规数组,链接列表,队列,映射,它们甚至是Lua面向对象功能的基础(即课程)。

Lua是一种非常简单的语言,但是表数据结构的灵活性也使其非常强大。


2
JavaScript对象的使用方法实际上是相同的-例如,数组实际上就是具有数字属性和长度的对象。
2011年

1
Lua表与JavaScript对象不同:在JavaScript {}not中[],在Lua中{},两者都有。Lua表与Lisp中的列表相比更好。
雅各布

我猜在JavaScript中,“一切都是对象”-包括数组-但并非一切都是数组。在Lua中,一切都是一张桌子。
Dean Harding

3

您不必为每种高级数据类型使用专用的语法。例如,可以容忍set([1, 2, 3])(就像Python 2.x一样)而不是{1, 2, 3}

重要的是要有一些方便的方法来构造高级数据结构。您要避免的是类似以下的代码:

s = set()
s.add(1)
s.add(2)
s.add(3)

当我在C ++中使用,和时std::vector,这使我非常烦恼。幸运的是,新标准将具有。std::setstd::mapstd::initializer_list


3

在我看来,这是一个非常简单的加法,经常会出奇的方便,至少在谨慎操作的情况下也是如此-即最多用于元组,列表,映射和集合,因为它们具有公认的文字。

  • 添加一种语言很便宜。您不必花费那么多宝贵的复杂性预算:
    • 语法基本上是someBracket {expr ','} someBracketsomeBracket {expr ':' expr ','} someBracket,如果您想要诸如可选的尾随逗号之类的内容,则可以使用一些简单的附加功能。该浮动文字可以很容易地在语法更长。
    • 在许多语言中,没有一种流行的文字与现有语法发生冲突(我想到的一个例外是,这种语言具有像花括号一样的块作为表达式,一个逗号运算符并且没有分号,例如{1, 2})。
    • 语义可以在不到五句话来定义的,非正式的版本是“实例化一个新的$集合,然后调用.add/ .append/ .setItem一旦每个给定的表达式与(那些)的表达(S)作为参数”。
  • 由于前面的第三点,它也很容易实现。
  • 当您需要一个元素时,它非常方便,并且不会(不需要)影响其他元素的语法,即,当您不使用它时,您无需“付钱”。

3

Clojure是轻率的,但支持

Lists: (x1 x2)
Vectors: [x1 x2]
Maps: {k1 v1 k2 v2}
Sets: #{x1 x2}

2

语言本身具有的数据结构越多,语言学习就越困难。这可能是个人喜好,但我倾向于使用简单的语言,然后库可以提供任何其他功能。

为特定领域设计的语言有时可以受益于该语言内置的某些数据结构,例如Matlab。但是太多的东西会让你不知所措。


2

为了使一种语言真正有用,它必须立即执行一定程度的任务。因为实际的日常编程需要一些可以在某种通用水平上解决其问题的工具。极简主义看起来紧凑而酷,但是当您要开始使用它来解决大而又反复出现的问题时,则需要一个可以在其之上构建的抽象层。

因此,我认为编程语言应在针对该语言设计的任务的语法中提供对最常用数据结构的支持。


2

总的来说,使用列表,集合等文字是很方便的。但是有时我不知道关于Python列表或Javascript数组的实际实现情况一无所知。我唯一可以确定的是,它们公开了给定的接口。

我以语言表达能力为基准,以其如何将自己的数据结构编写为库以及使用它们的方便程度。

例如,Scala提供了具有不同实现和性能保证的各种集合。所有这些都是在Scala本身中实现的,并且使用它们的语法仅比其内置并具有运行时支持的语法稍微复杂一些。

实际上,至少在托管语言中,真正需要运行时本身支持的唯一基本结构是数组:如果不管理内存,则很难获得一堆相邻的字节。其他所有结构都可以由数组和指针(或引用)构建而成。


1

APL(以及相关的现代变体A +,J和K)具有标量,向量和矩阵作为一流的数据结构。

是的,它们仅可作为数组的变体而弃用。但是它们也摆脱了复杂的声明,并且没有来自单独的库,它们感觉像是复杂的数据结构,是该语言的一流组成部分。


APL还具有嵌套数组,并且数组不必具有同质的数据类型,所有这些都构成了非常强大的数据结构。
RFlack

1

从语言设计的角度来看,您对在核心语言中为数据结构使用特定语法有何看法?这是一个好主意吗?语言(等等)的目的是否会改变它的选择余地?

列表和映射文字以及方便的闭包语法是高级语言的基本功能。

此Java代码之间的区别:

Thing t = new Thing();
t.setFoo(3);
t.setBar(6.3);
t.setBaz(true);

这个Groovy代码:

t = new Thing(foo: 3, bar: 6.3, baz: true)

是巨大的。这是40,000行程序和10,000行程序之间的差异。语法很重要。


在C#中可以执行以下操作:var t = new Thing(foo: 3, bar: 6.3, baz: true);-仅再增加4个字符。
工作

实际上是相同的数字;Groovy代码应显示为“ def t = ...”
kevin cline

1

当然,这取决于编程语言的应用程序,但是对于高级语言,使用任何通用数据结构应该尽可能地方便。请查看Wikipedia 中的抽象数据类型列表作为示例。我发现以下最普遍的基本原则(但我也想听听其他意见):

  • 有序序列(一维):数组,队列,堆栈,列表...
  • 有序多维结构:表,向量,矩阵
  • 地图:哈希图,字典,集合,多图...(一维)
  • 多维地图:功能,地图...
  • 图形类型:树,有向图...

您可以使用任何其他结构来模拟任何结构-这仅取决于编程语言所允许的难易程度。例如:

  • 队列和堆栈很容易用数组或列表来模拟,后者提供推,弹出,移位等操作。
  • 可以使用具有数字键的映射来模拟有序序列
  • 集可以通过将值映射到布尔值的映射来模拟
  • 大多数图形类型都可以通过嵌套序列或映射来模拟
  • 如果您可以轻松修改其定义,则可以使用这些函数来模拟地图

大多数语言提供至少一种用于有序序列的类型,一种用于一维映射,一种用于多维映射,但仅限于功能。就我个人而言,我经常会错过Perl,PHP,JavaScript,Lua等语言中的集和有序多维结构,因为对其进行仿真还不够方便。


1

我认为拥有太多获得特殊语法的特权数据类型是一个坏主意。这不必要地使语言语法复杂化,使代码更难阅读,使初学者更难学习,并且使开发该语言的工具更加困难。

少数非常常见的数据结构类型可以例外。我可能最多允许:

  • 定长数组
  • 套装
  • 哈希图
  • 序列/清单
  • 记录/结构/类

使用自定义数据类型的语言常规语法,应该将比这更复杂的事情留给库处理。

特别是,诸如红/黑树,优先级队列等之类的东西有很多可能的实现选项,因此将特定的实现烘焙到核心语言中是不明智的。最好让人们根据自己的情况选择最合适的实现。我可能不希望语言设计师将选择限制在以下实现选择的示例:

  • 可变还是不变?
  • 是否允许空值?
  • 是否同步?
  • 是否有持久存储支持?
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.