Skip to content

Commit

Permalink
fixing issue #90
Browse files Browse the repository at this point in the history
isequal() is the primitive comparison function.
  . it defaults to is()
  . is generally only true for arguments of the same type

types with "value type" semantics should define isequal and hash appropriately

subtypes of Number may define == instead of isequal for aesthetics

== defaults to isequal(). only define it for number-like things where
  some special behavior is needed (e.g. type promotion, IEEE-754, etc.)
  • Loading branch information
JeffBezanson committed Jul 1, 2011
1 parent cb41e38 commit 1f1a0c9
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion j/bool.j
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ sizeof(::Type{Bool}) = 1
## boolean operations ##

!(x::Bool) = eq_int(unbox8(x),trunc8(unbox32(0)))
==(x::Bool, y::Bool) = eq_int(unbox8(x),unbox8(y))
isequal(x::Bool, y::Bool) = eq_int(unbox8(x),unbox8(y))

(~)(x::Bool) = !x
(&)(x::Bool, y::Bool) = (x&&y)
Expand Down
7 changes: 7 additions & 0 deletions j/complex.j
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ pi{T}(::Type{Complex{T}}) = pi(T)
## functions of complex numbers ##

==(z::ComplexNum, w::ComplexNum) = (real(z) == real(w) && imag(z) == imag(w))
==(z::ComplexNum, x::Real) = (real(z)==x && imag(z)==0)
==(x::Real, z::ComplexNum) = (real(z)==x && imag(z)==0)

isequal(z::ComplexNum, w::ComplexNum) =
isequal(real(z),real(w)) && isequal(imag(z),imag(w))

hash(z::ComplexNum) = bitmix(hash(real(z)),hash(imag(z)))

conj(z::ComplexNum) = complex(real(z),-imag(z))
norm(z::ComplexNum) = square(real(z)) + square(imag(z))
Expand Down
2 changes: 0 additions & 2 deletions j/expr.j
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ symbol(a::Array{Uint8,1}) =

gensym() = ccall(:jl_gensym, Any, ())::Symbol

(==)(x::Symbol, y::Symbol) = is(x, y)

## expressions ##

expr(hd::Symbol, args::ANY...) = Expr(hd, {args...}, Any)
Expand Down
11 changes: 7 additions & 4 deletions j/operators.j
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@

## comparison ##

==(x, y) = false
isequal(x, y) = is(x, y)

==(x, y) = isequal(x, y)
!=(x, y) = !(x == y)
==(x::Number, y::Number) = (==)(promote(x,y)...)

# this definition allows Number types to implement == instead of isequal,
# which is more idiomatic.
isequal{T<:Number}(x::T, y::T) = (x == y)

< (x::Real, y::Real) = (<)(promote(x,y)...)
> (x::Real, y::Real) = (y < x)
<=(x::Real, y::Real) = (x < y) || (x == y)
>=(x::Real, y::Real) = (x > y) || (x == y)

isequal{T}(x::T, y::T) = (x==y)
isequal(x, y) = isequal(promote(x,y)...)

## definitions providing basic traits of arithmetic operators ##

+() = 0
Expand Down
2 changes: 1 addition & 1 deletion j/pointer.j
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ulong(x) = convert(Ulong, x)

## limited pointer arithmetic & comparison ##

==(x::Ptr, y::Ptr) = uint(x) == uint(y)
isequal(x::Ptr, y::Ptr) = uint(x) == uint(y)
-(x::Ptr, y::Ptr) = uint(x) - uint(y)

+{T}(x::Ptr{T}, y::Int) = pointer(T, uint(x) + uint(y))
Expand Down
12 changes: 5 additions & 7 deletions j/process.j
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ global STDIN = FileDes(ccall(:jl_stdin, Int32, ()))
global STDOUT = FileDes(ccall(:jl_stdout, Int32, ()))
global STDERR = FileDes(ccall(:jl_stderr, Int32, ()))

==(fd1::FileDes, fd2::FileDes) = (fd1.fd == fd2.fd)
isequal(fd1::FileDes, fd2::FileDes) = (fd1.fd == fd2.fd)

hash(fd::FileDes) = hash(fd.fd)

Expand All @@ -55,15 +55,15 @@ type Pipe
end
end

==(p1::Pipe, p2::Pipe) = (p1.in == p2.in && p1.out == p2.out)
isequal(p1::Pipe, p2::Pipe) = (p1.in == p2.in && p1.out == p2.out)

abstract PipeEnd
type PipeIn <: PipeEnd; pipe::Pipe; end
type PipeOut <: PipeEnd; pipe::Pipe; end

==(p1::PipeEnd, p2::PipeEnd) = false
==(p1::PipeIn , p2::PipeIn ) = (p1.pipe == p2.pipe)
==(p1::PipeOut, p2::PipeOut) = (p1.pipe == p2.pipe)
isequal(p1::PipeEnd, p2::PipeEnd) = false
isequal(p1::PipeIn , p2::PipeIn ) = (p1.pipe == p2.pipe)
isequal(p1::PipeOut, p2::PipeOut) = (p1.pipe == p2.pipe)

in (p::Pipe) = PipeIn(p)
out(p::Pipe) = PipeOut(p)
Expand Down Expand Up @@ -170,8 +170,6 @@ end

exec(cmd::Cmd) = exec(cmd.exec)

==(c1::Cmd, c2::Cmd) = is(c1,c2)

## Port: a file descriptor on a particular command ##

type Port
Expand Down
6 changes: 4 additions & 2 deletions j/rational.j
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ isinf(x::Rational) = x.den == 0 && x.num != 0
isfinite(x::Rational) = x.den != 0
isequal(x::Rational, y::Rational) = x.num == y.num && x.den == y.den
isequal(x::Rational, y::Int) = x.den == 1 && x.num == y
isequal(x::Number, y::Rational) = isequal(y, x)
hash(x::Rational) = bitmix(hash(x.num),hash(x.den))
==(x::Rational, y::Rational) = !isnan(x) && x.num == y.num && x.den == y.den
==(x::Rational, y::Int) = x.den == 1 && x.num == y
==(y::Int, x::Rational) = x.den == 1 && x.num == y
!=(x::Rational, y::Rational) = isnan(x) || x.num != y.num || x.den != y.den
<=(x::Rational, y::Rational) = float(x) <= float(y)
< (x::Rational, y::Rational) = float(x) < float(y)
Expand Down
10 changes: 5 additions & 5 deletions j/string.j
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ function chars(s::String)
cx
end

(<) (a::String, b::String) = cmp(a,b) < 0
(>) (a::String, b::String) = cmp(a,b) > 0
(==)(a::String, b::String) = cmp(a,b) == 0
(<=)(a::String, b::String) = cmp(a,b) <= 0
(>=)(a::String, b::String) = cmp(a,b) >= 0
(<) (a::String, b::String) = cmp(a,b) < 0
(>) (a::String, b::String) = cmp(a,b) > 0
isequal(a::String, b::String) = cmp(a,b) == 0
(<=)(a::String, b::String) = cmp(a,b) <= 0
(>=)(a::String, b::String) = cmp(a,b) >= 0

function cmp(a::String, b::String)
i = start(a)
Expand Down
3 changes: 1 addition & 2 deletions j/tensor.j
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,7 @@ function isequal(x::Tensor, y::Tensor)
end

for i=1:numel(x)
xi=x[i]; yi=y[i]
if xi!=yi && !isequal(xi, yi)
if !isequal(x[i], y[i])
return false
end
end
Expand Down
2 changes: 1 addition & 1 deletion j/tuple.j
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ map(f, ts::Tuple...) = ntuple(length(ts[1]), n->f(map(t->t[n],ts)...))

## comparison ##

function ==(t1::Tuple, t2::Tuple)
function isequal(t1::Tuple, t2::Tuple)
if length(t1) != length(t2)
return false
end
Expand Down
2 changes: 1 addition & 1 deletion test/tests.j
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ b = rand()
for a = -5:5, b = -5:5
@assert isequal(a/b, a/b)
@assert isequal(a//b, a/b)
@assert (a//b == a/b) || (isnan(a//b) && isnan(a/b))
@assert isequal(a//b, a//b)
for c = -5:5, d = -5:5
@assert isequal(a//b, c//d) == isequal(a/b, c/d)
Expand Down

0 comments on commit 1f1a0c9

Please sign in to comment.