This section deals with more theoretical aspects of types.

type system is a set of rules used by a language to structure and organize its collection of types.

We use the term object (or data object) to denote both the storage and the stored value.

The operations defined for a type are the only way to  manipulate its instantiated objects.

type error is any attempt to manipulate objects with illegal operations.

A program is type safe (or type secure) if it is guaranteed to have no type errors.

Static Versus Dynamic Program Checking ( for type errors )

Let's consider errors in general before looking at type errors specifically.

  • What kinds of errors may occur in programs?
  • When may errors be checked for?
  • How does error-checking time affect the quality of the resulting programs?

There are two categories of errors

  • Language errors - syntactic and semantic errors in the use of the PL
  • Application errors - deviations in program behavior relative to the program's specifications
    • has to do with software design issues, which are outside the scope of this book

There are two broad categories of error checking based on when the errors are checked for

  • dynamic error checking - requires the program to be executed on sample input data
  • static error checking - does not require program execution
     
    • Preferable to dynamic checking

      • potential errors are only detected at runtime if the input data we provide causes the error
      • dynamic checking slows down program execution
    • Often called compile-time checking or translation-time checking
      • a misnomer since with separate compilation some checks must be made at link time
    • Does not uncover all errors. Some are only manifest at run time

Strong Typing and Type Checking

The goal of a type system is to prevent the writing of type-unsafe programs as much as possible.

  • A type system is said to be strong, if it guarantees type safety.
  • A type system is said to be weak if it is not strong.
  • strongly typed language is one with a strong type system.
  • weakly typed language is one with a weak type system.

In general, there different ways for a PL to achieve a strong type system.

  • A statically typed language is a strongly typed language
  • Example: A static type system can be achieved by requiring:
    • Only built-in types can be used
    • All variables are declared with an associated type
    • All operations are specified by stating the types of the required operands and the type of the result
  • In some languages the binding between a variable and its type cannot be determined
    at compile-time, yet their type systems guarantee type safety

How should a designer choose a type system when designing a new PL?

  • Two conflicting design specifications

    • The size of the set of legal programs
    • The efficiency of the type checking procedure in the compiler
  • The type system restricts the set of programs that can be written
  • A smaller set of programs � simpler type checking

Type Compatibility

Consider a PL with an operation, OP, which expects an operand of type T

A strict type system might require that OP may only be legally invoked with a parameter of type T

On the other hand, the PL might define conditions under which an operand of type Q is also acceptable
without violating type safety.

In this case we say that "in the context of operation OP, type Q is compatible with type T".

Type compatibility is sometimes called type conformance or type equivalence.

When this compatibility is precisely defined, the PL can still have a strong type system.

Example: The program fragment in figure 3.8 is written in a hypothetical PL.
What are the effects of different sorts of type compatibility rules?

Name Compatibility - A strict conformance rule in which a type name is compatible only with itself

Under this rule:

  • (2) is type correct
  • (1), (3) and (4) contain type errors

Structural Compatibility - Two types are compatible if they have the same structure

Under this rule:

  • (1),(2) and (3) are type correct
  • (4) contains a type error

A few issues with structural compatibility as defined here.

  • What happens with the field names of Cartesian Products?

    • Ignored? Required to coincide? Required to occur in same order?

Name Compatibility is:

  • easier to implement than structural compatibility
  • much stronger than structural compatibility

Name compatibility is often preferable because it prevents two types from being considered
compatible just because their representations happen to be identical.

Practical Issue:

Some PLs adopt the idea of type compatibility, but either poorly define the rules
or leave it entirely up to the implementer.

This results in programs accepted by one compiler and rejected by another compiler

Type Conversions

  • Automatic conversions , called coercions
  • Explicit conversions, called casts

Example of coercion

x = x + z;  (in C )

Any coercions which may occur depend on context.

If z is float and x is int:

  • x is coerced to float to evaluate the addition, which is a real addition
  • the result is coerced to an int for the asignment

Explicit Type Conversion

An explicit conversion can be used in some PLs to avoid an undesirable coercion.

For example, C has a cast construct which can force a type conversion that otherwise
might not occcur.

Assuming the same variable types as above, a programmer could write:

x = x + (int) z; 

  • z is coerced to type int

    semantically, z is assigned to an unamed variable of
    type int using the normal coercion rules

  • the un-named variable is used to evaluate the addition, which is integer

Ada provides only explicit conversions, subject to rules defining allowed conversions.

  • If X is declared as FLOAT and I as INTEGER

    I := INTEGER(X);

    The conversion function, INTEGER(), provided by Ada, is
    applied to X to give the nearest INTEGER.

Advantages of allowing coercions

  • Desirable conversions are automatically done

Disadvantages of allowing coercions

  • These implicit conversions are 'behind the scenes'

    � PL gets complicated
    � Programs may become obscure

  • Coercions weaken the usefulness of type checking by overriding the declared types of objects

    The interaction between coercions and overloading of operators and routines makes programs
    difficult to understand.

Types and Subtypes

Assume a type T is defined as a set of values with an associated set of operations.

subtype STof T can be defined to be a subset of those values ( and, for simplicitiy, the same operations )

*note - the discussion here is in the context of conventional PLs. We ignore the ability to
specify user-defined operations for subtypes

If ST is a subtype of TT is also called ST's supertype (or parent type)

If a PL supports subtypes, it must define:

  • A way to define subsets of a given type
  • Compatibility rules between a subtype and it's supertype

Example - Pascal

  • introduced concept of subtype as a subrange of any discrete ordinal type

    type natural = 0..maxint;
         digit = 0..9;
         small = -9..9;

  • A Pascal program may only  define a subset of contiguous values
    - e.g.  a subtype of all even integers would not be allowwed
  • Different subtypes of a given type are compatible among themselves and the supertype,
    but type-safe operations may cause run-rime errors.

    - e.g. small is provided to an expression requiring a digit may cause error

Generic Types

Consider a generic abstract data type for a stack of elements of parameter type T,
with operations having the following signatures:

push: stack(T) � T � stack(T)

pop: stack(T) � stack(T) � T

length: stack(T) �int

The operations defined for type stack(T) should work uniformly for any possible type T.

Since the type is not known, how can the routines be type-checked?

PLs like Ada, C++ and Eiffel support this by instantiating generic types and/or routines at compile-time.

The generic type parameters are bound to concrete types, enabling type-checking.
 - C++ only requires explicit instantiation of generic classes, not routines

Monomorphic versus Polymorphic Type Systems

A statically typed language can provide a strong, simple type system in which every program entity
has a specific type (defined by a declaration), and every operation requires operands of exactly
the sort appearing in the operation definition.

monomorphic type system is a type system in which every object belongs to one and only one type,
as described above.

polymorphic type system is a type system in which objects can belong to more than one type.

C, Pascal and Ada all deviate from strict monomorphism to some degree.

  • compatibility
  • coercion
  • subtyping
  • operator overloading

All practical PLs have some degree of polymorphism, so to differentiate between them
we need to differentiate among the various levels and kinds of polymorphism.

The different facets of  polymorphism can be classifies as shown in figure 3.10.

Let's show how the classification scheme applies in the case of polymorphic functions.

Polymorphic functions are those whose arguments and return values (domain and range)
can belong to more than one type.

Level 1 - universal vs, ad hoc polymorphism

  • functions that are universally polymorphic work uniformly for an infinite set of types
    all of which have some common structure

    • execute the same code for all admissible types
  • An ad hoc polymorphic function is just a syntactic abbreviation for small set of
    different monomorphic functions.

Level 2 - universal :: parametric vs inclusion

  • parametric polymorphism is the most genuine form of universal polymorphism.

    • in this case the polymorphic function  works uniformly on a range of types
    • an implicit or explicit type parameter determines the type of arguments for each use
    • generic routines as implemented by ML functions are an example of this
    • generic routines as implemented in Ada and C++ are only an apparent kind of polymorphism
      • they can be viewed as ad hoc polymorphism since the routines are instantiated at compile time
        with full binding of parameters to specific types.
  • an example of inclusion  polymorphism is subtyping
     
    • the function is applicable to a given type and any of its subtypes
    • also applicable in the context of object oriented languages
  • dynamic polymorphism is frequently used to classify the case where the binding between
    language entities and their form varies dynamically.

    PLs which support this cannot have strong type systems

Level 2 - ad hoc :: overloading vs. coercion

  • In overloading, the same function name can be used in different contexts to denote different functions

    • Example in C : arithmetic expression a + b

      + is an ad hoc polymorphic function whose behavior depends on its operand types
          - float operands machine instruction float+
          - int operands machine instruction int+

      The fact that + is overloaded is purely a syntactic phenomenon

  • In coercion, the argument is converted to a type expected by the function
    • the polymorphism is only apparent

      • provided statically by code inserted by the compiler
      • provided dynamically by runtime tests on type descriptors
    • Example in C : arithmetic expression a + b

      + is an ad hoc polymorphic function whose behavior depends on its operand types as above

      If the two operands are different types, the float+ operator is invoked after coercing the int
      operand to a real.


The Type Structure of Representative Languages

The type structure of a PL  is an overall hierarchical classification of the features provided for structuring data.

In order to completely understand the semantics of a PL, this description must be complemented by a precise
understanding of the rules of the type system

http://www.cs.kent.edu/~durand/CS43101Fall2004/DT-TypeSystems.html

Type Systems的更多相关文章

  1. Working with the Dynamic Type in C#

    Working with the Dynamic Type in C# https://www.red-gate.com/simple-talk/dotnet/c-programming/workin ...

  2. Type system

    Type system[edit] Main articles: Data type, Type system, and Type safety A type system defines how a ...

  3. Type system-Type checking

    类型系统的属性: 1.结构属性: 2.规则属性:类型系统定义了一套规则(内部数据的访问规则.函数的访问规则.类型的比较与转化规则),以供编译和运行时进行检查. In programming langu ...

  4. Python Type Hint类型注解

    原文地址:https://realpython.com/python-type-checking/ 在本指南中,你将了解Python类型检查.传统上,Python解释器以灵活但隐式的方式处理类型.Py ...

  5. 类型检查和鸭子类型 Duck typing in computer programming is an application of the duck test 鸭子测试 鸭子类型 指示编译器将类的类型检查安排在运行时而不是编译时 type checking can be specified to occur at run time rather than compile time.

    Go所提供的面向对象功能十分简洁,但却兼具了类型检查和鸭子类型两者的有点,这是何等优秀的设计啊! Duck typing in computer programming is an applicati ...

  6. Java资源大全中文版(Awesome最新版)

    Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...

  7. 6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.)

    作者:余博伦链接:https://zhuanlan.zhihu.com/p/23412169来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 和大家一样,最近我也看了Jo ...

  8. 你应当如何学习C++(以及编程)(转载)

    你应当如何学习C++(以及编程)(rev#1) By 刘未鹏(pongba) C++的罗浮宫(http://blog.csdn.net/pongba) Javascript是世界上最受误解的语言,其实 ...

  9. Scala vs. Groovy vs. Clojure

    http://stackoverflow.com/questions/1314732/scala-vs-groovy-vs-clojure Groovy is a dynamically typed ...

随机推荐

  1. weblogic cluster error-----Could not= open connection with host: 127.0.0.1

    weblogic主机及一台从机启动成功后,在启动从机的时候报错, <BEA-000905> <Could not open connection with host: 127.0.0 ...

  2. mongodb配置文件与启动

    数据库配置文件 mongo.cnf #日志文件位置 logpath=/data/db/journal/mongodb.log (这些都是可以自定义修改的) # 以追加方式写入日志 logappend= ...

  3. jQuery 整体架构

    不同于 jQuery 代码各个模块细节实现的晦涩难懂,jQuery 整体框架的结构十分清晰,按代码行文大致分为如上图所示的模块. 初看 jQuery 源码可能很容易一头雾水,因为 9000 行的代码感 ...

  4. JavaScript - 表单提交前预览图片

    其实这东西网上到处都是,但并不完整. 正好我也遇到了这个问题,不仅仅是预览,还需要得到图片的属性. 于是东凑西凑整理出一个完整的版本,并根据个人的理解加上了一点点说明. 首先做一些准备工作,HTML方 ...

  5. 设置固定ip后无法上公网

    把电脑ip设置成固定ip后,发现其不能上公网,突然想到要设置DNS. 运行cmd程序,输入命令ipconfig /all查看此网络的DNS,设置固定ip 时添加此DNS地址即可.

  6. Hibernate 学习(三)

    一.关系映射 实体类之间的关联映射以及表之间的关系是 ORM 的灵魂之处.对象间的关系的子集可以用下列四种方式解释.关联映射可以是单向的也可以是双向的.  映射类型 描述 Many-to-One 使用 ...

  7. Redis实现主从复制(Master&Slave)

    由于前段时间公司项目比较赶,一直抽不出时间写博客,今天偷空写一篇吧.前面给大家讲解了单机版redis的基本操作,现在继续给大家讲解一下Redis的进阶部分,主从复制和读写分离. 一.Master&am ...

  8. Maven+Spring+MySql 登陆实例

    近来无事,复习复习Spring相关知识,从<Spring企业应用开发实战>这本书开始. 本文为学习<Spring企业应用开发实战>总结,著作权归原作者. 一.用Maven建立w ...

  9. linux 共享目录

    1. 文件上传遇到多物理机多实例时,怎么处理呢? ftp, 文件同步, 目录共享 这里用目录共享来一把. 2. 操作流程 物理机两台 192.168.1.88  192.168.1.166 2.1 服 ...

  10. elentment-ui解析

    序言 现在前端的技术越来越杂,也越来越细了,以至于每次看完文档都会有个错觉,就是自己差不多会了.真正去做项目的时候又是重复之前的步骤. 之前写Java的时候,会习惯性的看看源码,看完之后会对知识掌握的 ...