From 1d2970b3ed90e53e024a39c97f94f947e5d2d407 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 9 Feb 2019 00:54:39 -0800 Subject: [PATCH 1/2] Allow @: as a macro --- src/julia-parser.scm | 7 ++++--- test/syntax.jl | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 2a4db29d343d5..b2e8697c72f4c 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -2330,9 +2330,10 @@ (disallowed-space '@ nxt))) (with-space-sensitive (let ((startloc (line-number-node s)) - (head (if (eq? (peek-token s) '|.|) - (begin (take-token s) '__dot__) - (parse-atom s #f)))) + (head (case (peek-token s) + ((|.|) (begin (take-token s) '__dot__)) + ((:) (take-token s)) + (else (parse-atom s #f))))) (peek-token s) (if (ts:space? s) (maybe-docstring diff --git a/test/syntax.jl b/test/syntax.jl index bb8f5a4837636..178fb7c0fa94e 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1832,3 +1832,8 @@ end allocs = @allocated identity(p) @test allocs == 0 end + +@test Meta.parse("@: a b c") == Expr(:macrocall, + Symbol("@:"), + LineNumberNode(1, :none), + :a, :b, :c) From 00f257d603810b564d0e730c3394e8db29546aa6 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Fri, 15 Feb 2019 17:47:12 -0800 Subject: [PATCH 2/2] Use @: to construct a non-materialized broadcasted object --- base/broadcast.jl | 27 ++++++++++++++++++++++++++- base/exports.jl | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index 24d0424a89727..8a074511ef9e7 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -11,7 +11,7 @@ using .Base.Cartesian using .Base: Indices, OneTo, tail, to_shape, isoperator, promote_typejoin, _msk_end, unsafe_bitgetindex, bitcache_chunks, bitcache_size, dumpbitcache, unalias import .Base: copy, copyto!, axes -export broadcast, broadcast!, BroadcastStyle, broadcast_axes, broadcastable, dotview, @__dot__ +export broadcast, broadcast!, BroadcastStyle, broadcast_axes, broadcastable, dotview, @__dot__, @: ## Computing the result's axes: deprecated name const broadcast_axes = axes @@ -1211,4 +1211,29 @@ end end @inline broadcasted(::S, f, args...) where S<:BroadcastStyle = Broadcasted{S}(f, args) +function _lazy end # only used in `@:` macro; does not have to be callable +# wrap the Broadcasted object in a tuple to avoid materializing +@inline broadcasted(::typeof(_lazy), x) = (x,) + +""" + @: broadcasting_expression + +Construct a non-materialized broadcasted object from a `broadcasting_expression` +and [`instantiate`](@ref) it. + +# Examples +```jldoctest +julia> bc = @: (1:3).^2; + +julia> bc isa Broadcast.Broadcasted # it's not an `Array` +true + +julia> sum(bc) # summation without allocating an array +14 +``` +""" +macro (:)(ex) + return esc(:($instantiate(($_lazy.($ex))[1]))) +end + end # module diff --git a/base/exports.jl b/base/exports.jl index 8a26eb8fdc73f..ee4da1e8ec10c 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -973,6 +973,7 @@ export @assert, @__dot__, + @:, @enum, @label, @goto,