问题标签 [static-typing]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 厌倦了非语义测试来弥补动态类型 - 建议?
在开始学习计算机工程之前,我曾经在 Rails(之前的 PHP)中进行过很多 Web 编程。
从那时起,我在 C 语言中完成了很多学校作业,并在 Objective-C 中完成了一些个人工作(Mac 的东西)。我学会了喜欢静态类型。
但现在我不得不做一些专业的 Web 开发(自由职业),并且再次选择了 Rails。我发现编写非语义类型检查测试真的很烦人。我是从 C 和 Objective-C 编译器中免费获得的。我喜欢点击 Build 并让系统检查我的所有代码,看看 A 可以调用 B,B 可以调用一些晦涩的库 C,等等。我所要做的就是测试语义。但是对于 Rails,我是编译器。:(
有没有人踩过同样的路?使用 C# 和 Java + x 框架进行 Web 开发 ASP.NET MVC 是我唯一的选择吗?寻求一些建议,甚至是一些同情......:P
顺便说一句,我特别提到了 Rails 而不是 Ruby,因为我不介意 Ruby 对脚本等简单事物的动态特性。但是由于 Rails 依赖于这么多的 gem,而且通常会添加许多其他的 gem,动态类型就成了一个问题。
谢谢!
编辑:
我跟进了 pst 的建议并研究了 Scala。在阅读由该语言的创建者 Martin Odersky 撰写的《Scala 编程》一书时,我偶然发现了这段文字,它在很多方面表达了我的担忧,甚至更多。非常有趣的阅读。
摘自 Martin Odersky 的 Programming in Scala 第 52 页:
Scala 是静态类型的
静态类型系统根据变量和表达式持有和计算的值的种类对它们进行分类。Scala 是一种具有非常先进的静态类型系统的语言。从类似于 Java 的嵌套类类型系统开始,它允许您使用泛型参数化类型,使用交集组合类型,以及使用抽象类型隐藏类型的细节。这些为构建和组合您自己的类型奠定了坚实的基础,因此您可以设计同时安全且灵活使用的界面。
如果您喜欢 Perl、Python、Ruby 或 Groovy 等动态语言,您可能会觉得 Scala 的静态类型系统被列为其强项之一有点奇怪。毕竟,没有静态类型系统被一些人认为是动态语言的主要优势。反对静态类型的最常见论点是它们使程序过于冗长,阻止程序员按照自己的意愿表达自己,并使软件系统的某些动态修改模式成为不可能。
然而,这些论点通常并不反对一般的静态类型的想法,而是反对特定的类型系统,这些系统被认为过于冗长或过于僵化。例如,Smalltalk 语言的发明者 Alan Kay 曾经说过:“我不反对类型,但我不知道任何类型系统不是完全痛苦的,所以我仍然喜欢动态类型。”< /p>
我们希望在本书中让你相信 Scala 的类型系统远非“完全痛苦”。事实上,它很好地解决了关于静态类型的两个常见问题:通过类型推断避免冗长,通过模式匹配和几种编写和组合类型的新方法获得灵活性。排除这些障碍后,可以更好地理解静态类型系统的经典优势。这些好处中最重要的是程序抽象的可验证属性、安全重构和更好的文档。
可验证的属性
静态类型系统可以证明不存在某些运行时错误。例如,他们可以证明以下属性:布尔值永远不会添加到整数;私有变量不能从其类外部访问;函数应用于正确数量的参数;只有字符串被添加到一组字符串中。
今天的静态类型系统无法检测到其他类型的错误。例如,它们通常不会检测到非终止函数、数组边界违规或除以零。他们也不会检测到您的程序不符合其规范(假设有规范,那就是!)。因此,静态类型系统被一些人认为不是很有用。争论的观点是,既然这样的类型系统只能检测简单的错误,而单元测试提供了更广泛的覆盖范围,那么为什么还要使用静态类型呢?
我们认为这些论点没有抓住重点。尽管静态类型系统当然不能替代单元测试,但它可以通过处理一些原本需要测试的属性来减少所需的单元测试数量。同样,单元测试也不能代替静态类型。毕竟,正如 Edsger Dijkstra 所说,测试只能证明错误的存在,而不能证明错误的存在。因此,静态类型提供的保证可能很简单,但它们是任何测试都无法提供的形式的真正保证。
安全重构
静态类型系统提供了一个安全网,让您可以高度自信地更改代码库。例如,考虑向方法添加附加参数的重构。在静态类型语言中,您可以进行更改,重新编译系统并简单地修复导致类型错误的所有行。完成此操作后,您一定会找到所有需要更改的地方。这同样适用于许多其他简单的重构,例如更改方法名称,或将方法从一个类移动到另一个类。在所有情况下,静态类型检查都可以确保新系统与旧系统一样工作。
文档
静态类型是由编译器检查正确性的程序文档。与普通注释不同,类型注释永远不会过时(至少在包含它的源文件最近通过编译器时不会过时)。此外,编译器和集成开发环境可以利用类型注释来提供更好的上下文帮助。例如,集成开发环境可以通过确定进行选择的表达式的静态类型并查找该类型的所有成员来显示可供选择的所有成员。
open-source - 静态类型的开源跨平台现代编程语言
可能这是一个愚蠢的问题。是否有 Java 和 .NET 平台的替代品?
哪一个:
- 本身就是一种编程语言。除非它们成为主导语言端口,否则 IMO 并不真正成功。
- 可能有它自己的执行平台,比如 JVM,这是一个很大的优势。但是翻译也可以。
- 是静态类型的。
- 是开源的,由开放社区开发。
- 像Java一样跨平台:编译一次,到处运行。
- 是现代的:多范式(OOP 和泛型,函数式是加号),并发(至少允许并发写入),垃圾收集是加号,反射是加号。
我很高兴知道也满足此标准的不受欢迎或实验性语言。死语言是不行的。
满足上述所有(主观)条件的语言可能属于以下两个类别之一
- 静态类型的解释语言项目。它将提供跨平台解释器和库。
- 类似 Java 的语言,但有两个区别:不是 Java 端口,由社区开发。
scala - 如何确保在 map() 期间保留自定义 Scala 集合的动态类型?
我阅读了关于 Scala 2.8 集合体系结构的非常有趣的文章,并且一直在尝试使用它。首先,我只是简单地复制了这个好RNA
例子的最终代码。这里供参考:
现在,这是我的问题。如果我运行它,一切都很好:
但是这段代码将 RNA 转换为向量!
这是一个问题,因为不知道该类的客户端代码RNA
可能会将其转换回 aVector
而不是仅映射 from Base
to Base
。为什么会这样,有什么方法可以解决它?
P.-S.:我找到了一个暂定的答案(见下文),如果我错了,请纠正我。
scala - 映射到相同类型时,Scala 的 map() 是否应该表现不同?
在 Scala Collections 框架中,我认为在使用map()
.
我们可以区分(不可变)集合上的两种转换。那些实现调用newBuilder
重新创建结果集合的人,以及那些通过隐式CanBuildFrom
获取构建器的人。
第一类包含所有转换,其中包含元素的类型不会改变。例如,它们是 , filter
, partition
, drop
,take
等span
。这些转换可以自由调用newBuilder
和重新创建与调用它们的集合类型相同的集合类型,无论多么具体:过滤 aList[Int]
总是可以返回 a List[Int]
; 过滤一个BitSet
(或本文中描述的关于集合框架架构RNA
的示例结构)总是可以返回另一个(或)。我们称它们为过滤转换。BitSet
RNA
第二类转换需要CanBuildFrom
s 更加灵活,因为包含的元素的类型可能会发生变化,因此,集合本身的类型可能无法重用:aBitSet
不能包含String
s;anRNA
只包含Base
s。此类转换的示例是map
, flatMap
, collect
, scanLeft
,++
等。我们称它们为映射转换。
现在这里是要讨论的主要问题。无论集合的静态类型是什么,所有过滤转换都会返回相同的集合类型,而映射操作返回的集合类型会因静态类型而异。
现在,我明白为什么会这样了。它在那里和那里解释。简而言之:隐式CanBuildFrom
是基于静态类型插入的,并且根据其def apply(from: Coll)
方法的实现,可能会也可能不会重新创建相同的集合类型。
现在我唯一的一点是,当我们知道我们正在使用映射操作产生具有相同元素类型(编译器可以静态确定)的集合时,我们可以模仿过滤转换的工作方式并使用集合的本机构建器。我们可以BitSet
在映射到Int
s 时重用,创建一个TreeSet
具有相同顺序的新对象,等等。
然后我们将避免以下情况
不TreeSet
以相同的顺序打印增加的元素
所以:
- 您认为按照所述更改映射转换的行为是一个好主意吗?
- 我严重忽视了哪些不可避免的警告?
- 如何实施?
我在考虑类似implicit sameTypeEvidence: A =:= B
参数的东西,可能有一个默认值null
(或者更确切地说是一个implicit canReuseCalleeBuilderEvidence: B <:< A = null
),它可以在运行时用于为 提供更多信息CanBuildFrom
,而这些信息又可以用来确定要返回的构建器的类型。
groovy - Groovy 中带有类型参数的闭包
我想更明确地说明我关于它们的参数类型的闭包。所以我会写类似
我知道 Groovy 不会使用该类型信息,但 Groovy++ 可能会在编译时使用它。这可以实现吗(除了将其放入评论中)?
更新:标题听起来可能会产生误导,但我认为上面的例子会更清楚。我有兴趣指定闭包的类型,它是某个函数的参数。假设,我想重新定义内置的collect
. 所以我对写作感兴趣myCollect
,而不是写作clos
。我想要实现的是获得编译时错误
java - 为什么必须在 Java 中声明接口?
有时我们有几个类,它们的某些方法具有相同的签名,但不对应于已声明的 Java 接口。例如,JTextField
和JButton
(以及 中的其他几个 javax.swing.*
)都有一个方法
现在,假设我希望对具有该方法的对象做一些事情;然后,我想要一个接口(或者自己定义它),例如
这样我就可以写:
但是,可悲的是,我不能:
这种演员阵容是非法的。编译器知道这JButton
不是a CanAddActionListener
,因为该类尚未声明实现该接口......但是它“实际上”实现了它。
这有时会带来不便——Java 本身已经修改了几个核心类来实现由旧方法(String implements CharSequence
例如 )组成的新接口。
我的问题是:为什么会这样?我理解声明一个类实现一个接口的实用性。但是无论如何,看看我的例子,为什么编译器不能推断出类JButton
“满足”接口声明(查看它的内部)并接受强制转换?是编译器效率的问题还是有更根本的问题?
我对答案的总结:在这种情况下,Java 可以允许一些“结构类型”(有点像鸭子类型 - 但在编译时检查)。它没有。除了一些(对我来说不清楚)性能和实现方面的困难之外,这里还有一个更基本的概念:在 Java 中,接口(通常是所有东西)的声明不仅仅是结构性的(具有这些签名)但语义:这些方法应该实现一些特定的行为/意图。因此,在结构上满足某些接口的类(即,它具有具有所需签名的方法)不一定在语义上满足它(一个极端的例子:回想一下“标记接口”,它甚至没有方法!)。因此,Java 可以断言一个类实现了一个接口,因为(并且仅仅是因为)它已被显式声明。其他语言(Go、Scala)有其他的哲学。
c# - 浮动比双倍慢吗?64位程序运行速度比32位程序快吗?
使用float
类型比使用类型慢double
吗?
我听说现代 Intel 和 AMD CPU 可以比浮点数更快地进行双精度计算。
标准数学函数(sqrt
、pow
、log
、sin
、cos
等)呢?以单精度计算它们应该会快得多,因为它应该需要更少的浮点运算。例如,单精度sqrt
可以使用比双精度更简单的数学公式sqrt
。另外,我听说标准数学函数在 64 位模式下更快(在 64 位操作系统上编译和运行时)。这个问题的最终答案是什么?
python - Python 中的静态类型检查工具
我正在使用现有的大型 Python 代码库,并希望开始添加类型注释,以便进行某种程度的静态检查。我在想像Erlang、Strongtalk或Typed Scheme/Racket之类的东西。
我见过快速而肮脏的装饰器,它们根据函数参数和返回类型注释插入动态检查,但我正在寻找更健壮并在编译时执行检查的东西。
现在有哪些工具可用于此类事情?我熟悉编译器和类型检查,如果它有良好的基础,我肯定愿意改进一个不完整的工具。
(注意:我对讨论静态类型的优缺点不感兴趣。)
编辑:一个例子:
我希望能够将该put
函数注释为具有 type put<K,V>(dict<K,V>, K, V) -> None
。
更新:新的PEP 484(2014 年 9 月)定义了 Python 3.5+ 中静态类型和类型注释的标准。有一个名为mypy的类型检查工具与 PEP 484 兼容。
haskell - 在 Haskell 中测试某些数据是否属于某种类型?
既然 Haskell 有这样的表达类型系统,有没有直接支持我们可以查询某些数据是否属于某种类型的东西呢?就像在球拍中,(String? "Hi")
(将返回true
)或喜欢MyType? somedata -> Bool