类型系统学习 篇1

https://www.cis.upenn.edu/~bcpierce/tapl/taplcover.jpg

写在前头:重点看《篇三》,值得反复看,也贴有原文链接,看完还是要去看原文,写的太好了。

有没有那一刻,突然感觉懂了,为什么之前学不会,现在能学会,为什么编程要这样学?
那就是此刻。《篇三》给我的启发真的太大了。


types and programming language 是由 pierce教授写的,很经典的一本书。现在找到的这本中译本是2005年翻译的,原书是2002年出版的。

https://www.cis.upenn.edu/~bcpierce/tapl/ tapl就是这本书的简称。


最近在学习编程的时候,就遇到一个问题,书中老是提到类型系统,在群里讨论的时候也是,会有小伙伴提到类型系统,我就比较好奇这个。
找了很多文档,慢慢阅读起来。
在网上看教程,要保持怀疑,在学别的东西的时候,也要保持怀疑。


对全文的总结和回顾:通过阅读这些文章,你会看到好的文章是什么样子的,作者的一些观点,你边看边思考,你会有你的取舍。

还有就是,越来越觉得,就是在学的过程中,有哪些问题,然后,针对性的去学,这样效果是最好的, 也就是“小孩子学母语”的思维。

这周我越来越认同这种思维方式,不需要搞太多东西,准备太多东西,然后再开始,这样真的太累了。当这些准备工作全部做完后,你的激情、精力也随着殆尽。 这种学习方法,我在暑假和上个月就在犯,不能这样。

遇到什么感兴趣,有关系,就查查,就学学这就够了,这种学东西的状态才是最好的。

还有就是用词、概念上的一些追求:

  • 集合
  • 约束
  • etc...

如何准确用词去表达你想要表达的意思,这是很重要的,我如今就欠缺这种表达能力。
还有一些看不懂的:

  • 动态内存分配技术

篇一

https://github.com/FrankHB/pl-docs/blob/master/zh-CN/typing-vs-typechecking.md
说实话,这篇我没看懂,但是我感觉这篇写的还是很严谨的,有很多的引用。
摘一点能读懂的,

  • 有关类型是什么? 这个问题值得思考

    基于足够的理由,我旗帜鲜明地站在前者一边——谁告诉你看不出显式的类型可读性就差了?谁规定显式类型就是所谓“可读性”了?又有谁规定理解程序源代码片段的含义应该先从了解具体的项的某一个类型开始?

  • 显式类型和隐式类型的讨论,如上,提出了几个问题
  • 类型安全问题
  • 强类型与弱类型

篇二

两段知乎答案转载

https://www.cnblogs.com/feng9exe/p/10740346.html

程序是类型的证明。
计算机程序是建立在计算机硬件和一系列规则、协议、规范、算法基础之上的;

程序是建立在逻辑和严格证明基础之上的;
逻辑学的基本要素是:概念、判断、推理;
类型系统相当于逻辑和科学中的概念,在此基础上才能进行运算和推理;
编程语言不过是建立了类型系统和在类型系统基础上的一些列运算法则而已。
类型+运算法则+运算推演=程序;

作者:匿名用户
链接:https://www.zhihu.com/question/23434097/answer/42374622
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个回答,我看完后的感觉是,很直观的解释了 “为什么需要类型?”。 其实,也说明了什么是类型,只是定义的不“准确”:类型是“规则”。 按照此回答,可以这样推:

  • 类型是前提,因为这是逻辑推理的“概念”
  • 判断的话,是不是需要运算符什么的?这点是我的臆想。

先匿了,我不确定我说的好不好。
发现和《Types and Programming》说的一模一样,不匿了
安全,有了类型系统以后就可以实现类型安全,这时候程序就变成了一个严格的数学证明过程,编译器可以机械地验证程序某种程度的正确性,从而杜绝很多错误的发生。
正面例子:Haskell、Rust
反面例子:C,动态语言
抽象能力,在安全的前提下,一个强大的类型系统的标准是抽象能力,能将程序中的很多东西纳入安全的类型系统中进行抽象,这在安全性的前提下又不损耗灵活性,甚至性能也能很优化。动态语言的抽象能力可以很强,但安全性和性能就不行了。
泛型、高阶函数(闭包)、类型类、Monad、Lifetime(Rust) 属于这一块。
工程能力,一个强类型的编程语言比动态类型的语言更适合大规模软件的构建,哪怕不存在性能问题,但是同样取决于前两点。
对于编译器来说能清楚程序的意图,对于人来说也是如此 。一个函数或者类似的东西,说白了就是一个映射关系,Python 中这些映射关系都是没有很明显的约束,要靠约定和默契才能维持,对大型软件来说这是不行的。一个优秀的强类型的程序,很多函数都不需要文档,光看函数申明就可以了。而在安全的前提下的抽象,也是不容易引发灾难的。
不过,同时类型检查和标注增加了学习成本和编码时间成本(类型推倒不是万能的),编译不过也会挫伤初学者信心,不像动态语言上马就能干,边干边学。不过个人觉得值。

https://www.zhihu.com/question/23434097

读来读去,看不懂了。 就是说,强类型是利好编译器的?(大致这个意思?)编译器是死脑经,它就对着规则跟你一点点核准,它要是通过了,就说明“通常情况下”,不会有啥问题,有问题就是两个:规则设计的有问题、编译器设计的有问题。 跟人没什么关系,至少跟编码的人,关系不至于那么大。 应该可以这样去理解,目前我就这样去理解吧。

篇三 (1)

http://laomst.site/article/38

先插入一段作者的别的文章:

上面的程序中我们使用了伪指令dw来告诉汇编程序我们的数据占用多大的内存空间,而我们从内存中读取数据的时候,要读取多大的内存空间呢?这一部分信息隐藏在了指令的目标寄存器中,比如上面的add ax cs:[bx]这行代码的目标寄存器是ax,是16位的寄存器,我们要从地址cs:[bx]开始读取16位也就是两个字节,如果我们把目标寄存器换成ah,那么就成了读取8位也就是一个字节了。
可以看出,我们在使用汇编语言进行内存访问的时候,数据应该以怎样的步长读取,读取到的数据可以进行什么样的操作,语言本身能提供给我们的元数据信息非常有限,而且几乎没有对我们进行任何的限制。我们所能依靠的只有代码注释和自己的大脑,这样的编程方式就像走钢丝一样,稍不留神就会坠入万丈深渊。

http://laomst.site/article/37

一个很重要的观点:
可以说,类型系统是一门语言的世界观的基本规则,只有理解了一门语言的类型系统,才能真正掌握这门语言的核心。

在进行这部门内容的讨论之前,我们需要先明确以下几个事实:

  • 左值(变量)代表了一个数据存储区域,我们可以认为它是一个用来存储值的容器,之所以称其为变量是因为这个容器中的值是可以改变的。
  • 一个值一定是一个常量,一个值是确定且唯一的。
  • 数据类型是值的固有属性,一个值一定具有明确且唯一的类型。高级语言抽象出数据类型的概念根本目的就是为存储值、读取值以及使用值提供元数据信息以及约束。

而静态类型/动态类型所描述的其实是左值是不是具有数据类型约束。换句话说,其描述的是变量(左值)是不是只能存储某种类型的值。

http://laomst.site/article/38

静态类型的核心是变量只能存储某种类型的值,因此,一个变量在静态期必须具有一个明确且唯一的类型,而到了语言的运行时,变量中的值肯定是和我们声明变量时指定的数据类型是兼容的。

lvalue (left vaule)左值概念

数据类型是高级语言抽象出来,为数据的存储和数据可以进行的操作提供元数据信息的。它代表了一门高级语言最基本的抽象能力。一门语言的数据类型的灵活性将直接影响整门语言的灵活性。

笔记:静态有静态的好,动态有动态的好。 静态语言,例如C++在解决代码复用的问题的时候,提供模板的功能。“这种技术的核心思想就是类型参数化,把数据类型当做参数使用,让编译器根据类型参数生成对应类型的代码或者是进行静态类型校验。”

我们上面说明了各种语言中提高类型使用灵活性的方法,大致的套路如下:

  • 静态类型中一般通过类型参数化来提高类型的灵活性
  • 动态类型中一般通过鸭子类型来提高类型的灵活性

很多人都把类型的静/动和强/弱混为一谈,诚然,静态类型的编程语言对类型好像天生比较敏感,其看上去好像就是强类型的,其实这是因为静态类型本身固有的静态期类型检查的功能所造成的错觉,实际上强/弱跟静/动描述的是不同的维度。

  • 静/动描述的是语言是不是限制左值的数据类型
  • 强/弱则主要描述语言对类型的敏感程度,侧重于描述语言的类型安全性

比如C语言,它是静态类型的,静态类型检查是其固有的属性,但是其设计思想是——相信程序员,不妨碍程序员做任何事情。这就意味着其类型是比较弱的——它连数组访问是否越界都不会进行检查。

http://laomst.site/article/38

有一些bug是 莫名其妙的bug。这就要查手册,靠积累了,我感觉是这样。 此刻的想法,先记录下来。


在此,还要再插入一篇,
劳码识途
讲解数据结构非常不错的一篇文章,有理有据。
这篇文章值得反复看。

和现实中的分子类似,基本数据结构为我们提供了把标量数据或者其他的数据结构组合在一起的基本手段,数据之间的组合形式其实一共就只有两种

  • 一种是将多个异构的数据组合成一个有意义的整体,成为一个新的数据类型,本质上其实就是用户自定义数据类型;这类似于水分子这种由不同的原子组成的分子。
  • 另一种组合方式是多个同构的数据组合成一个整体,这有点类似于足球富勒这种单质分子。我们会在这个群体中进行一系列的操作,比如遍历每一个成员、从中寻找某一个或者某一些满足某个条件的成员、修改某一个成员的信息、添加一个新成员等等。

对于这两种数据的组合方式,基本数据结构都可以进行支持。常见的基本数据结构只有四种,分别是数组、结构体、元组和联合体。其中数组和结构体是所有的高级语言都会提供或者提供类似特性的基本数据结构,而元组和联合体并不是所有的语言都提供的基本数据结构。

http://laomst.site/article/17

笔记? 基本数据结构:

  • 用户自定义类型 (引用:结构体本质上其实就是用户自定义数据类型,它提供了对‘异构数据组合成一个具有意义的整体’这种数据组合方式的支持。
  • 其他类型

列举四种基本数据类型:数组(看作,顺序结构存储,这在物理世界/现实世界中真实存在的)

、结构体、

元组(它其中的成员没有名称,我们可以认为索引就是他们的名称。)。 数组和结构体的大杂烩

联合体(比较少见,我也不太懂其实)。 这些可以看作是语言自身提供的特性,当然不是所有语言都有这四种特性的。

总之,从上面可以看出来。 数组和结构体,是高级程序语言必备的啊,叫语言基础设施。 这是语言自身的性质,比依赖于“三方”,我是这样理解这个“自身特性”的。

高级数据结构最典型的特征就是随着程序的运行,它的值和结构可能会发生变化。因此,实现高级数据结构需要更加复杂的技术,最基本的就是动态内存分配技术。

比如我们通常使用指针把结构中的所有元素链接到一起的手段来实现一个链表,常见的高级数据结构有链表、哈希表、树、图等等。到了高级数据结构这个层面,我们已经开始涉及到数据结构中的逻辑结构了。

http://laomst.site/article/17

我们可以认为高级数据结构是数据结构层级中的物质,它们由分子构成(只通过标量数据的组合是无法形成高级数据结构的),它具有无限的可能性和灵活性。同时我们的数据结构所重点描述的就是高级数据结构。

一言以蔽之,数据结构落实到编程语言中所研究的问题其实就是是同一种数据类型的大量实例如何组织和管理以实现快速的查找、插入、删除、排序等操作的问题

数据结构的逻辑结构和物理结构

先说逻辑结构四个:
(内容全部来自:http://laomst.site/article/17

  • 集合结构:结构中的元素之间除了“属于同一个集合”之外没有其他关系;
  • 线性结构:结构中的元素存在一对一的相互关系,即简单的前后关系;
  • 树形结构:结构中的元素存在一对多的关系;
  • 图形结构:结构中的元素存在多对多的关系。

为什么要学习《离散数学》为什么说《离散数学》很重要? 就在于此。

存储结构来看就;

  • 顺序存储
  • 链式存储

数据结构与算法二者关系的论述

总的来说,我认为数据结构和算法的关系是这样的:

  • 数据结构是为算法服务的,因为不同的数据结构具有不同的特性,有的数据结构支持的算法,换成另一种结构可能就不行了,比如我们可以对一个有序的数组进行二分查找,但是对于一个有序的链表,我们就无法使用二分查找算法了,因为链表并不支持随机访问。在特定的场景中选择合适的数据结构能够使得我们的程序更加简单高效。
  • 算法需要作用在特定的数据结构之上,我们所要对数据进行的操作(我们所要采用的算法)反过来驱动我们进行数据结构的选择。我们的每一个场景都会要求对数据做什么样的操作,而想要对数据做特定的操作必须有能够支持这样操作的数据结构的支持,所以算法在一定程度上能决定我们对数据结构的选择。

总的来说数据结构和算法之间的关系并不是简单的谁决定谁的关系,二者其实是一种互为决定的关系,从物理上来说,数据结构决定了算法,而在逻辑意义上,算法决定了我们对数据结构的选择。
数据结构是静态的,它只是组织数据的一种方式。如果不在它的基础上操作、构建算法,孤立存在的数据结构就是没用的。

笔记: 可以说是我迄今为止,读过的讲的最好的了。 (这句话明显和主观)。 真的解释清楚了二者的关系,“相互”。 尤其是这个 有序数组和有序链表的例子,你就能看到,就能理解“数据结构与算法的相互关系”了,

抽象数据类型 与 面向对象有关系。 但是,对于面向对象,我是真的不懂。


篇三 (2)

http://laomst.site/article/38
有关强类型、弱类型,这个争论不休,我感觉没必要去争论这个东西。从该文来看,强弱之分,本来就不好去划分,我们应该把握本质。本质是什么? 就是对类型的敏感程度(文章http://laomst.site/article/38 作者观点,我比较赞同这个提法)。

每一种数据类型都有其所能表示的值的范围,一个数据类型所能表示的所有的值我们就称之为这个数据类型的值集。
在讨论数据类型的值集的时候其实我们只需要关注标量数据类型的值集,原因有以下几点:

  • 标量数据类型都是语言内建的数据类型
  • 标量数据类型的值集往往与硬件相关,比如java中的int类型的值集是 -2147483648~2147483647 的闭区间。
  • 标量数据类型是数据类型中的原子,是构成所有具有结构的数据类型的基础。

不同语言对于标量类型都具有不同的规则,相似标量类型的值集可能也有所不同,在我们介绍具体语言的时候会对语言的标量类型的值集有所介绍。

这段论述太棒了。 我个人感觉,只要学习过一点集合论,理解上述就不是问题。

相关推荐

intel 8086 asm 基础1

1.进入debug模式 r 查看 2. mov指令测试 指令以CS:IP 格式进行读取,后跟8086 asm实 ...

暂无评论

发表评论

您的电子邮件地址不会被公开,必填项已用*标注。