Skip to content

Commit

Permalink
add default kw constructor for immutables
Browse files Browse the repository at this point in the history
For example, the type

    immutable X
        a::Int
        b::Int
    end

now comes with the extra constructor:

    X(x::X; a=x.a, b=x.b) = new(a,b)

Closes #5333.
  • Loading branch information
nolta committed Dec 9, 2014
1 parent bed2b43 commit 10384cb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
39 changes: 22 additions & 17 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -726,22 +726,27 @@
(map (lambda (x) (gensy)) field-names)
field-names))

(define (default-inner-ctors name field-names field-types gen-specific?)
(let* ((field-names (safe-field-names field-names field-types))
(any-ctor
;; definition with Any for all arguments
`(function (call ,name ,@field-names)
(block
(call new ,@field-names)))))
(if (and gen-specific? (any (lambda (t) (not (eq? t 'Any))) field-types))
(list
;; definition with field types for all arguments
`(function (call ,name
,@(map make-decl field-names field-types))
(block
(call new ,@field-names)))
any-ctor)
(list any-ctor))))
(define (default-inner-ctors name field-names field-types gen-specific? mutabl)
(let* ((arg-names (safe-field-names field-names field-types))
(any-ctor `(function (call ,name ,@arg-names)
(block (call new ,@arg-names))))
(ctors (if (and gen-specific? (any (lambda (t) (not (eq? t 'Any))) field-types))
(list
;; definition with field types for all arguments
`(function (call ,name ,@(map make-decl arg-names field-types))
(block (call new ,@arg-names)))
any-ctor)
(list any-ctor))))
(if (and (not mutabl)
(length> field-names 1)
(eq? arg-names field-names))
(let ((g (gensy)))
(cons `(function (call ,name
(parameters ,@(map (lambda (k) `(kw ,k (|.| ,g ',k))) field-names))
(|::| ,g ,name))
(block (call new ,@field-names)))
ctors))
ctors)))

(define (default-outer-ctor name field-names field-types params bounds)
(let ((field-names (safe-field-names field-names field-types)))
Expand Down Expand Up @@ -889,7 +894,7 @@
(field-names (map decl-var fields))
(field-types (map decl-type fields))
(defs2 (if (null? defs)
(default-inner-ctors name field-names field-types (null? params))
(default-inner-ctors name field-names field-types (null? params) mut)
defs))
(min-initialized (min (ctors-min-initialized defs) (length fields))))
(for-each (lambda (v)
Expand Down
16 changes: 16 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1974,3 +1974,19 @@ function f9134()
end
end
@test_throws UndefVarError f9134()

# issue #5333
immutable I5333
a::Int
b::Int
end
type T5333
a::Int
b::Int
end
let i = I5333(1,2), t = T5333(1,2)
@test I5333(i;b=3) === I5333(1,3)
@test I5333(i;a=3) === I5333(3,2)
@test_throws MethodError T5333(t;a=3)
@test_throws MethodError T5333(t;b=3)
end

0 comments on commit 10384cb

Please sign in to comment.