Skip to content

Commit

Permalink
deprecate (;) (JuliaLang#30115) (JuliaLang#34039)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Dec 12, 2019
1 parent 3382125 commit ce29ec5
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 14 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Language changes

* Calling `show` or `repr` on a 0-dimensional `AbstractArray` now shows valid code for creating an equivalent 0-dimensional array, instead of only showing the contained value. ([#33206])

* The syntax `(;)`, which used to parse as an empty block expression, is deprecated.
In the future it will indicate an empty named tuple ([#30115]).

Multi-threading changes
-----------------------

Expand Down
2 changes: 1 addition & 1 deletion doc/src/base/punctuation.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Extended documentation for mathematical symbols & functions is [here](@ref math-
| `()` | parentheses with no arguments constructs an empty [`Tuple`](@ref) |
| `(a,...)` | parentheses with comma-separated arguments constructs a tuple containing its arguments |
| `(a=1,...)` | parentheses with comma-separated assignments constructs a [`NamedTuple`](@ref) |
| `(;)` | parentheses can also be used to group one or more semicolon separated expressions |
| `(x;y)` | parentheses can also be used to group one or more semicolon separated expressions |
| `a[]` | [array indexing](@ref man-array-indexing) (calling [`getindex`](@ref) or [`setindex!`](@ref)) |
| `[,]` | [vector literal constructor](@ref man-array-literals) (calling [`vect`](@ref Base.vect)) |
| `[;]` | [vertical concatenation](@ref man-array-concatenation) (calling [`vcat`](@ref) or [`hvcat`](@ref)) |
Expand Down
8 changes: 4 additions & 4 deletions doc/src/manual/control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Julia provides a variety of control flow constructs:

* [Compound Expressions](@ref man-compound-expressions): `begin` and `(;)`.
* [Compound Expressions](@ref man-compound-expressions): `begin` and `;`.
* [Conditional Evaluation](@ref man-conditional-evaluation): `if`-`elseif`-`else` and `?:` (ternary operator).
* [Short-Circuit Evaluation](@ref): `&&`, `||` and chained comparisons.
* [Repeated Evaluation: Loops](@ref man-loops): `while` and `for`.
Expand All @@ -19,7 +19,7 @@ direct usage of tasks, but certain problems can be solved much more easily by us

Sometimes it is convenient to have a single expression which evaluates several subexpressions
in order, returning the value of the last subexpression as its value. There are two Julia constructs
that accomplish this: `begin` blocks and `(;)` chains. The value of both compound expression constructs
that accomplish this: `begin` blocks and `;` chains. The value of both compound expression constructs
is that of the last subexpression. Here's an example of a `begin` block:

```jldoctest
Expand All @@ -32,7 +32,7 @@ julia> z = begin
```

Since these are fairly small, simple expressions, they could easily be placed onto a single line,
which is where the `(;)` chain syntax comes in handy:
which is where the `;` chain syntax comes in handy:

```jldoctest
julia> z = (x = 1; y = 2; x + y)
Expand All @@ -41,7 +41,7 @@ julia> z = (x = 1; y = 2; x + y)

This syntax is particularly useful with the terse single-line function definition form introduced
in [Functions](@ref). Although it is typical, there is no requirement that `begin` blocks be multiline
or that `(;)` chains be single-line:
or that `;` chains be single-line:

```jldoctest
julia> begin x = 1; y = 2; x + y end
Expand Down
16 changes: 11 additions & 5 deletions src/julia-parser.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1910,17 +1910,22 @@
;; convert an arglist to a tuple or block expr
;; leading-semi? means we saw (; ...)
;; comma? means there was a comma after the first expression
(define (arglist-to-tuple leading-semi? comma? args . first)
(define (arglist-to-tuple s leading-semi? comma? args . first)
(if (and (pair? first) (null? args) (not leading-semi?) (not comma?))
`(block ,@first) ;; this case is (x;)
(or (and (not comma?) (length= args 1) (pair? (car args)) (eq? (caar args) 'parameters)
(let ((blk (parameters-to-block (car args))))
(and blk (or (and (not leading-semi?)
`(block ,@first ,@blk))
(and (null? first) (null? blk)
`(block)))))) ;; all semicolons inside ()
;; all semicolons inside ()
(if (length= (car args) 1)
(begin (parser-depwarn s "(;)" "begin end")
;; should eventually be (tuple (parameters))
`(block))
`(block)))))))
(and (null? first) (null? args) (not comma?)
`(block)) ;; this case is (;)
(error "unreachable"))
(rm-linenums
(if (and (pair? args) (pair? (car args)) (eq? (caar args) 'parameters))
`(tuple ,(car args) ,@first ,@(map kw-to-= (cdr args)))
Expand Down Expand Up @@ -1974,7 +1979,7 @@
(take-token s) ;; take #\)
'(|::| . #f))
((eqv? nxt #\;)
(let ((ex (arglist-to-tuple #t #f (parse-arglist s #\) ))))
(let ((ex (arglist-to-tuple s #t #f (parse-arglist s #\) ))))
(cons ex (eq? (car ex) 'tuple))))
(else
;; here we parse the first subexpression separately, so
Expand All @@ -1991,10 +1996,11 @@
((eqv? t #\,)
;; tuple (x,) (x,y) etc.
(take-token s)
(cons (arglist-to-tuple #f #t (parse-arglist s #\) ) ex)
(cons (arglist-to-tuple s #f #t (parse-arglist s #\) ) ex)
#t))
((eqv? t #\;)
(cons (arglist-to-tuple
s
#f
;; consider `(x...; ` the start of an arglist, since it's not useful as a block
(vararg? ex)
Expand Down
4 changes: 3 additions & 1 deletion src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,9 @@
(current-vals '())
(expr #f))
(if (null? L)
(merge expr (to-nt current-names current-vals))
(or (merge expr (to-nt current-names current-vals))
;; if that result is #f the named tuple is empty
'(call (core NamedTuple)))
(let ((el (car L)))
(cond ((or (assignment? el) (kwarg? el))
(if (not (symbol? (cadr el)))
Expand Down
2 changes: 1 addition & 1 deletion test/namedtuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ end
@test Meta.lower(Main, Meta.parse("(; f(x))")) == Expr(:error, "invalid named tuple element \"f(x)\"")
@test Meta.lower(Main, Meta.parse("(;1=0)")) == Expr(:error, "invalid named tuple field name \"1\"")

@test Meta.parse("(;)") == quote end
@test eval(Expr(:tuple, Expr(:parameters))) === NamedTuple()
@test Meta.lower(Main, Meta.parse("(1,;2)")) == Expr(:error, "unexpected semicolon in tuple")

# splatting
Expand Down
4 changes: 2 additions & 2 deletions test/syntax.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ macro test999_str(args...); args; end

# blocks vs. tuples
@test Meta.parse("()") == Expr(:tuple)
@test Meta.parse("(;)") == Expr(:block)
@test_skip Meta.parse("(;)") == Expr(:tuple, Expr(:parameters))
@test Meta.parse("(;;;;)") == Expr(:block)
@test_throws ParseError Meta.parse("(,)")
@test_throws ParseError Meta.parse("(;,)")
Expand Down Expand Up @@ -1322,7 +1322,7 @@ end
@test Meta.parse("-(x)^2") == Expr(:call, :-, Expr(:call, :^, :x, 2))
@test Meta.parse("-(a=1)^2") == Expr(:call, :-, Expr(:call, :^, Expr(:(=), :a, 1), 2))
@test Meta.parse("-(x;y)^2") == Expr(:call, :-, Expr(:call, :^, Expr(:block, :x, LineNumberNode(1,:none), :y), 2))
@test Meta.parse("-(;)^2") == Expr(:call, :-, Expr(:call, :^, Expr(:block), 2))
@test_skip Meta.parse("-(;)^2") == Expr(:call, :-, Expr(:call, :^, Expr(:tuple, Expr(:parameters)), 2))
@test Meta.parse("-(;;;;)^2") == Expr(:call, :-, Expr(:call, :^, Expr(:block), 2))
@test Meta.parse("-(x;;;)^2") == Expr(:call, :-, Expr(:call, :^, Expr(:block, :x), 2))
@test Meta.parse("+((1,2))") == Expr(:call, :+, Expr(:tuple, 1, 2))
Expand Down

0 comments on commit ce29ec5

Please sign in to comment.