论坛首页 编程语言技术论坛

变量一定要有类型吗(一)

浏览 6699 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-03-01  
先讨论一下Ruby是不是强类型。


1).在《Beyond Java》September 2005 一书  6.1.2节Typing  中,Bruce Tate举例
     irb(main):015:0> "fish"+4
    TypeError: cannot convert Fixnum into String
            from (irb):15:in‘+’
              from (irb):15
从而得出结论:
引用
That means Ruby is strongly typed.


我们知道,Ruby是动态语言,在运行中边解释、边检测、边执行,检测类型匹配吗?不是检测类型匹配,而是检测语法。
String类的‘+’是一个方法,但是,Ruby从来不拒绝你重写方法。
class String
  alias : old_plus :+
  def +(other)
    self.old_plus(other.to_s)    
  end  
end

puts "fish"+4       # => fish4
puts '1 ' + 2.3      # => 1 2.3



2).Bruce Tate 在“跨越边界: Java 模型以外的类型策略”2006 年 6 月 一文中写到:
引用
...这两种语言都 倾向于 强类型...


这两种语言是指Java和 Ruby,他给出了一行Ruby代码来说明;

1 + "hello"
会收到以下错误消息:
TypeError: String can't be coerced into Fixnum
        from (irb):3:in '+'
        from (irb):3


字面值1是Fixnum类的实例对象,让我们重写Fixnum类的‘+’方法,使得‘+’的语法不再出错;

class Fixnum
  alias : old_plus :+
  def +(other)
    (other.class.eql?String) ? (self.to_s << other) : (old_plus(other))    
  end  
end

puts  1 + "hello"  # => 1hello
puts  1 + " 2.3"   # => 1 2.3




3). Ruby是简单的,我们可以只管按照别人说的去使用;Ruby也是灵活而复杂的,我们可以按照自己的需求去使用;
require "another_plus3"

puts  'he'+1        # => he1
puts '1.5'+2        # => 3.5
puts 1+" he"        # => 1 he

puts 1 + " 2.3"    # => 3.3
puts 1 + 2.3      # => 3.3

puts 1.6 * "2.7"   # => 4.32
puts 1 -"2.3"    # => -1.3

类型错误根本不存在,如果语法错误算是强类型,我无言。Bruce Tate是大牛,他断言Ruby是强类型,国内的牛们也跟着如是说。
在1).中, Bruce Tate断言Ruby是强类型;
在2).中, Bruce Tate认为Ruby 倾向于 强类型。

后文“变量一定要有类型吗(二)”将更进一步说明。


#another_plus3.rb

class String

  alias : old_plus :+
  def +(other)    
    (Float(self)) + (Float(other))  rescue  (self.to_s).old_plus(other.to_s)     
  end  
  
  def coerce(other)
    case other
      when Integer : return other, Integer(self)  rescue  return Float(other), Float(self)
      when Float : return other, Float(self)
      else super
    end
  end
  
end

class Fixnum
  alias : old_plus :+
  def +(other)
    (other.class.eql?String)?(old_plus(Float(other)) rescue self.to_s<<other):(old_plus(other))      
  end  
end

class Float
  alias : old_plus :+
  def +(other)
    (other.class.eql?String)?(old_plus(Float(other)) rescue self.to_s<<other):(old_plus(other))    
  end  
end


========
题外话

假设若干年后,有一篇搜索引擎报告指出:
A)21世纪初期,网络信息以中文和英文居多;
B)其中中文信息多数是英文信息的跟风之作,
从发布时间得出,英文信息居前;
从信息不确切度得出,中文信息没有经过中文世界的思维、理解与吸收,英文信息如何错误,中文信息也有相似度极高的错误...
...

我衷心地希望与你,一起唱和出中文技术论坛自身的弦音。
   发表时间:2007-03-01  
变量一定要有类型吗(二)



变量一定要有类型吗?不一定。

在《The Ruby Way 2nd》一书中,1.2.3节 Constants, Variables, and Types
“In Ruby, variables do not have types, but the objects they refer to still have types. ” 在Ruby中,变量没有类型,但变量引用的对象有类型。
1.5.2节 Perspectives in Programming
“In Ruby, variables don't have classes; only values have classes.” Ruby里, 变量没有类别;只有值才有类别。

《The Ruby Way 2nd》所描述是真的吗?口说无凭,程序为证。
a=5
puts  "a = #{a},  #{a.class}"   # => a = 5,  Fixnum

a="hh"    # a: 5 --> "hh"
puts  "a = #{a},  #{a.class}"   # => a = hh,  String

变量a只是一个符号,当a指向一个表达式的时候,那个表达式的值也许是Fixnum,也许是String。变量a并没有什么事先预定的类型;而且变量a在事后也不会固定在什么具体的类型上。
a = x==nil ? 2 : x**2 < x<<2  ? 2.0 : ""
puts a.class

你能告诉我,变量a是什么类型吗?你如果问我,我只能说:
假设x = 2,程序输出为Float;
假设x = 4,程序输出为String;
假如x 是一个无返回值的方法,程序输出为Fixnum。

Gödel在证明不完备性定理时,用一个正整数指代某个数值;用另一个正整数指代某个运算符;而且,公式也用正整数指代;定理也用正整数指代…正整数只是符号,数值、运算符、公式、定理有区别,正整数没有类型差别。

变量只是符号,变量没有类型你如果不能接受,那么,我们自小熟悉的正整数只是代表不同类事物的符号,也许会让你发疯。

完备性、一致性、可证性似乎与主题不相关,其实,计算机编程语言是形式数学的直接产物。最初的LISP语言哪里有变量类型的概念,从C一路走来,到C++,到Java,变量的概念中塞入了太多的东西。一个子类拥有许许多多的内容,它父类的父类,最初的根类,只是一个符号。

你也许认为,变量有类型拓展了我们表达事物的能力,可事实是,如今Java程序、C++程序所作的并没有超越Turing当初的构想。假如某个语言因为变量有类型而实现了智能化,请你一定,一定要mail me。

人们在编程语言的道路上行走了几十年,跌跌绊绊,缝缝补补,没能见到希望中的曙光。这一切的努力是有意义的,但也许应该回到起初的地方,认真审视,重新选择方向。Ruby是一个值得去做的尝试。

A). Rails框架充分发挥了Ruby的动态性,继承ActiveRecord时,数据库中的表将被映射为一个Ruby类,你不用操心字段值的类型。在Java及其上的框架中则作不到。

B).假设有一个Java EE 项目,几个人分别在PowerDesigner里定义了几百甚至上千张表,连接上数据库,PowerDesigner 帮你自动在库中生成了这些表;在Hibernate 里SessionFactory创建JDBC连接, MyEclipse 为你自动生成了每张表相应的JavaBean。你现在要将表中的内容显示在前端网页表格中,不是很难,可问题是,每个表有几个字段,十几个字段,甚至更多,你显示的时候不仅要考虑到getXXX(),还要顾及到返回类型,有些字段又没有定义缺省值,上万个字段实在是无休止的折磨。假设出现在生活中,你只能无奈地写一个Java类,定义成静态方法,是为了直接调用。都是类型惹得祸。
//package com.lilytech.hr.rsgl;
/*
 * Created on 2006-4-21
 *
 */

/**
 * @author Kaichuan Zhang
 *
 */
public class Wrap {
	public static String tostring(Object obj){
		try{
			return (obj!=null)?obj.toString():"";
		}catch(Exception err){
			return "";
		}	
	}
	
	public static String tostring(long obj){		
		try{
			return (new Long(obj)).toString();
		}catch(Exception err){
			return "";
		}	
	}
	
	public static String tostring(double obj){		
		try{
			return (new Double(obj)).toString();
		}catch(Exception err){
			return "";
		}	
	}
	
	public static String tostring(boolean obj){			
		try{
			return (new Boolean(obj)).toString();
		}catch(Exception err){
			return "";
		}	
	}
}

一门语言的变量有无类型,对于其上的框架之影响,如你在A). 与B).比较中所见。

结语:像Java,C++这样的静态语言需要变量有类型。而对于Ruby这样的动态语言,变量未必需要有类型。

0 请登录后投票
   发表时间:2007-03-01  
你混淆了强类型/弱类型和静态类型/动态类型。

http://en.wikipedia.org/wiki/Strong_typing

0 请登录后投票
   发表时间:2007-03-01  
more:

http://en.wikipedia.org/wiki/Type_system#Strong_and_weak_typing

http://en.wikipedia.org/wiki/Comparison_of_programming_languages

0 请登录后投票
   发表时间:2007-03-01  
假设若干年后,有一篇搜索引擎报告指出:
A)21世纪初期,网络信息以中文和英文居多;
B)其中中文信息多数是英文信息的跟风之作,
从发布时间得出,英文信息居前;
从信息不确切度得出,中文信息没有经过中文世界的思维、理解与吸收,英文信息如何错误,中文信息也有相似度极高的错误.

这真是让我喷饭, 又是"国人自强论", 鬼子们在科学技术方面的统治地位是勿庸置疑的, 不会因为我们叫口号而改变. 只有竭力追赶上咱们才有叫板的资格.
0 请登录后投票
   发表时间:2007-03-01  
这个问题还需要讨论啊!...无语了...
0 请登录后投票
   发表时间:2007-03-02  
从lambda演算的角度说
我们并不关心一个东西到底是什么,而只看作一个符号
并定义符号之上的函数
然后将函数看作符号,并称为算子
在定义作用于算子上的算子,获得高阶函数

类型系统是个数学概念
咱们搞编程的明不明白不重要
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics