Skip to content

Commit

Permalink
deprecate concatenating [a,b,...] and T[a,b,...]
Browse files Browse the repository at this point in the history
closes #2488, closes #3737
  • Loading branch information
nolta committed Jan 8, 2014
1 parent 8a8a382 commit c784d89
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 60 deletions.
63 changes: 55 additions & 8 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,45 @@ typealias AbstractVecOrMat{T} Union(AbstractVector{T}, AbstractMatrix{T})

## Basic functions ##

vect() = Array(None, 0)
vect{T}(X::T...) = T[ X[i] for i=1:length(X) ]

const _oldstyle_array_vcat_ = true

if _oldstyle_array_vcat_
function oldstyle_vcat_warning(n::Int)
if n == 1
before = "a"
after = "a;"
elseif n == 2
before = "a,b"
after = "a;b"
else
before = "a,b,..."
after = "a;b;..."
end
warn_once("[$before] concatenation is deprecated; use [$after] instead")
end
function vect(A::AbstractArray...)
oldstyle_vcat_warning(length(A))
vcat(A...)
end
function vect(X...)
for a in X
if typeof(a) <: AbstractArray
oldstyle_vcat_warning(length(X))
break
end
end
vcat(X...)
end
else
function vect(X...)
T = promote_type(map(typeof, X)...)
T[ X[i] for i=1:length(X) ]
end
end

size{T,n}(t::AbstractArray{T,n}, d) = (d>n ? 1 : size(t)[d])
eltype(x) = Any
eltype{T,n}(::AbstractArray{T,n}) = T
Expand Down Expand Up @@ -791,6 +830,11 @@ end
## cat: general case

function cat(catdim::Integer, X...)
T = promote_type(map(x->isa(x,AbstractArray) ? eltype(x) : typeof(x), X)...)
cat_t(catdim, T, X...)
end

function cat_t(catdim::Integer, typeC::Type, X...)
nargs = length(X)
dimsX = map((a->isa(a,AbstractArray) ? size(a) : (1,)), X)
ndimsX = map((a->isa(a,AbstractArray) ? ndims(a) : 1), X)
Expand Down Expand Up @@ -834,7 +878,6 @@ function cat(catdim::Integer, X...)

ndimsC = max(catdim, d_max)
dimsC = ntuple(ndimsC, compute_dims)::(Int...)
typeC = promote_type(map(x->isa(x,AbstractArray) ? eltype(x) : typeof(x), X)...)
C = similar(isa(X[1],AbstractArray) ? full(X[1]) : [X[1]], typeC, dimsC)

range = 1
Expand All @@ -850,12 +893,15 @@ end
vcat(X...) = cat(1, X...)
hcat(X...) = cat(2, X...)

typed_vcat(T::Type, X...) = cat_t(1, T, X...)
typed_hcat(T::Type, X...) = cat_t(2, T, X...)

cat{T}(catdim::Integer, A::AbstractArray{T}...) = cat_t(catdim, T, A...)

cat(catdim::Integer, A::AbstractArray...) =
cat_t(catdim, promote_type(map(eltype, A)...), A...)

function cat_t(catdim::Integer, typeC, A::AbstractArray...)
function cat_t(catdim::Integer, typeC::Type, A::AbstractArray...)
# ndims of all input arrays should be in [d-1, d]

nargs = length(A)
Expand Down Expand Up @@ -916,6 +962,9 @@ end
vcat(A::AbstractArray...) = cat(1, A...)
hcat(A::AbstractArray...) = cat(2, A...)

typed_vcat(T::Type, A::AbstractArray...) = cat_t(1, T, A...)
typed_hcat(T::Type, A::AbstractArray...) = cat_t(2, T, A...)

# 2d horizontal and vertical concatenation

function hvcat(nbc::Integer, as...)
Expand Down Expand Up @@ -1003,22 +1052,20 @@ function hvcat_fill(a, xs)
a
end

function hvcat(rows::(Int...), xs::Number...)
function typed_hvcat(T::Type, rows::(Int...), xs...)
nr = length(rows)
nc = rows[1]
#error check
for i = 2:nr
if nc != rows[i]
error("row ", i, " has mismatched number of columns")
end
end
T = typeof(xs[1])
for i=2:length(xs)
T = promote_type(T,typeof(xs[i]))
end
hvcat_fill(Array(T, nr, nc), xs)
end

hvcat(rows::(Int...), xs::Number...) =
typed_hvcat(promote_type(map(typeof, xs)...), rows, xs...)

## Reductions and scans ##

function isequal(A::AbstractArray, B::AbstractArray)
Expand Down
4 changes: 4 additions & 0 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,15 @@ end

getindex(T::(Type...)) = Array(T,0)

if _oldstyle_array_vcat_
# T[a:b] and T[a:s:b] also contruct typed ranges
function getindex{T<:Number}(::Type{T}, r::Ranges)
warn_once("T[a:b] concatenation is deprecated; use T[a:b;] instead")
copy!(Array(T,length(r)), r)
end

function getindex{T<:Number}(::Type{T}, r1::Ranges, rs::Ranges...)
warn_once("T[a:b,...] concatenation is deprecated; use T[a:b;...] instead")
a = Array(T,length(r1)+sum(length,rs))
o = 1
copy!(a, o, r1)
Expand All @@ -173,6 +176,7 @@ function getindex{T<:Number}(::Type{T}, r1::Ranges, rs::Ranges...)
end
return a
end
end

function fill!{T<:Union(Int8,Uint8)}(a::Array{T}, x::Integer)
ccall(:memset, Ptr{Void}, (Ptr{Void}, Int32, Csize_t), a, x, length(a))
Expand Down
26 changes: 11 additions & 15 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -845,14 +845,10 @@
(loop (list 'typed_dict ex))
(loop (list 'ref ex)))
(case (car al)
((vect) (loop (list* 'ref ex (cdr al))))
((dict) (loop (list* 'typed_dict ex (cdr al))))
((hcat) (loop (list* 'typed_hcat ex (cdr al))))
((vcat)
(if (any (lambda (x)
(and (pair? x) (eq? (car x) 'row)))
(cdr al))
(loop (list* 'typed_vcat ex (cdr al)))
(loop (list* 'ref ex (cdr al)))))
((vcat) (loop (list* 'typed_vcat ex (cdr al))))
((comprehension)
(loop (list* 'typed_comprehension ex (cdr al))))
((dict_comprehension)
Expand Down Expand Up @@ -1289,21 +1285,20 @@
(error (string "missing comma or " closer
" in argument list"))))))))))

; parse [] concatenation expressions and {} cell expressions
(define (parse-vcat s first closer)
(define (parse-vect s first closer)
(let loop ((lst '())
(nxt first))
(let ((t (require-token s)))
(if (eqv? t closer)
(begin (take-token s)
(cons 'vcat (reverse (cons nxt lst))))
(cons 'vect (reverse (cons nxt lst))))
(case t
((#\,)
(take-token s)
(if (eqv? (require-token s) closer)
;; allow ending with ,
(begin (take-token s)
(cons 'vcat (reverse (cons nxt lst))))
(cons 'vect (reverse (cons nxt lst))))
(loop (cons nxt lst) (parse-eq* s))))
((#\;)
(error "unexpected semicolon in array expression"))
Expand All @@ -1313,7 +1308,7 @@
(error "missing separator in array expression")))))))

(define (parse-dict s first closer)
(let ((v (parse-vcat s first closer)))
(let ((v (parse-vect s first closer)))
(if (any dict-literal? (cdr v))
(if (every dict-literal? (cdr v))
`(dict ,@(cdr v))
Expand Down Expand Up @@ -1349,7 +1344,7 @@
(if (pair? outer)
(fix 'vcat (update-outer vec outer))
(if (or (null? vec) (null? (cdr vec)))
(fix 'vcat vec) ; [x] => (vcat x)
(fix 'vect vec) ; [x] => (vect x)
(fix 'hcat vec)))) ; [x y] => (hcat x y)
(case t
((#\; #\newline)
Expand Down Expand Up @@ -1390,8 +1385,8 @@
(else
(parse-dict s first closer)))
(case (peek-token s)
((#\,)
(parse-vcat s first closer))
((#\, closer)
(parse-vect s first closer))
((for)
(take-token s)
(parse-comprehension s first closer))
Expand Down Expand Up @@ -1663,6 +1658,7 @@
(if (null? vex)
'(cell1d)
(case (car vex)
((vect) `(cell1d ,@(cdr vex)))
((comprehension)
`(typed_comprehension (top Any) ,@(cdr vex)))
((dict_comprehension)
Expand Down Expand Up @@ -1698,7 +1694,7 @@
((eqv? t #\[ )
(take-token s)
(let ((vex (parse-cat s #\])))
(if (null? vex) '(vcat) vex)))
(if (null? vex) '(vect) vex)))

;; string literal
((eqv? t #\")
Expand Down
56 changes: 19 additions & 37 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1796,6 +1796,9 @@
(error "invalid \":\" outside indexing"))
`(call colon ,.(map expand-forms (cdr e))))

'vect
(lambda (e) (expand-forms `(call (top vect) ,@(cdr e))))

'hcat
(lambda (e) `(call hcat ,.(map expand-forms (cdr e))))

Expand All @@ -1818,47 +1821,26 @@
`(call vcat ,@a)))))

'typed_hcat
(lambda (e)
(let ((t (cadr e))
(a (cddr e)))
(let ((result (gensy))
(ncols (length a)))
`(block
#;(if (call (top !) (call (top isa) ,t Type))
(call (top error) "invalid array index"))
(= ,result (call (top Array) ,(expand-forms t) 1 ,ncols))
,.(map (lambda (x i) `(call (top setindex!) ,result
,(expand-forms x) ,i))
a (cdr (iota (+ ncols 1))))
,result))))
(lambda (e) `(call (top typed_hcat) ,(expand-forms (cadr e)) ,.(map expand-forms (cddr e))))

'typed_vcat
(lambda (e)
(let ((t (cadr e))
(rows (cddr e)))
(if (any (lambda (x) (not (and (pair? x) (eq? 'row (car x))))) rows)
(error "invalid array literal")
(let ((result (gensy))
(nrows (length rows))
(ncols (length (cdar rows))))
(if (any (lambda (x) (not (= (length (cdr x)) ncols))) rows)
(error "invalid array literal")
`(block
#;(if (call (top !) (call (top isa) ,t Type))
(call (top error) "invalid array index"))
(= ,result (call (top Array) ,(expand-forms t) ,nrows ,ncols))
,.(apply nconc
(map
(lambda (row i)
(map
(lambda (x j)
`(call (top setindex!) ,result
,(expand-forms x) ,i ,j))
(cdr row)
(cdr (iota (+ ncols 1)))))
rows
(cdr (iota (+ nrows 1)))))
,result))))))
(a (cddr e)))
(expand-forms
(if (any (lambda (x)
(and (pair? x) (eq? (car x) 'row)))
a)
;; convert nested hcat inside vcat to hvcat
(let ((rows (map (lambda (x)
(if (and (pair? x) (eq? (car x) 'row))
(cdr x)
(list x)))
a)))
`(call (top typed_hvcat) ,t
(tuple ,.(map length rows))
,.(apply nconc rows)))
`(call (top typed_vcat) ,t ,@a)))))

'|'| (lambda (e) `(call ctranspose ,(expand-forms (cadr e))))
'|.'| (lambda (e) `(call transpose ,(expand-forms (cadr e))))
Expand Down
12 changes: 12 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,18 @@ Y = [1. 2. 3.; 4. 5. 6.]
@test size(X) == size(Y)
for i = 1:length(X) @test X[i] === Y[i] end

_array_equiv(a,b) = eltype(a) == eltype(b) && a == b
@test _array_equiv(Uint8[1:3;4], [0x1,0x2,0x3,0x4])
if !Base._oldstyle_array_vcat_
@test_throws Uint8[1:3]
@test_throws Uint8[1:3,]
@test_throws Uint8[1:3,4:6]
a = Array(Range1{Int},1); a[1] = 1:3
@test _array_equiv([1:3,], a)
a = Array(Range1{Int},2); a[1] = 1:3; a[2] = 4:6
@test _array_equiv([1:3,4:6], a)
end

# "end"
X = [ i+2j for i=1:5, j=1:5 ]
@test X[end,end] == 15
Expand Down

0 comments on commit c784d89

Please sign in to comment.