Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ An `AbstractDict{K, V}` should be an iterator of `Pair{K, V}`.
"""
abstract type AbstractDict{K,V} end

"""
Iterators.Pairs(values, keys) <: AbstractDict{eltype(keys), eltype(values)}

Transforms an indexable container into an Dictionary-view of the same data.
Modifying the key-space of the underlying data may invalidate this object.
"""
struct Pairs{K, V, I, A} <: AbstractDict{K, V}
data::A
itr::I
end
Pairs{K, V}(data::A, itr::I) where {K, V, I, A} = Pairs{K, V, I, A}(data, itr)
Pairs{K}(data::A, itr::I) where {K, I, A} = Pairs{K, eltype(A), I, A}(data, itr)
Pairs(data::A, itr::I) where {I, A} = Pairs{eltype(I), eltype(A), I, A}(data, itr)
pairs(::Type{NamedTuple}) = Pairs{Symbol, V, NTuple{N, Symbol}, NamedTuple{names, T}} where {V, N, names, T<:NTuple{N, Any}}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit strange to have as a method; maybe just make it a constant instead?


## optional pretty printer:
#const NamedTuplePair{N, V, names, T<:NTuple{N, Any}} = Pairs{Symbol, V, NTuple{N, Symbol}, NamedTuple{names, T}}
#export NamedTuplePair


# The real @inline macro is not available until after array.jl, so this
# internal macro splices the meta Expr directly into the function body.
macro _inline_meta()
Expand Down
22 changes: 5 additions & 17 deletions base/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module Iterators
import ..@__MODULE__, ..parentmodule
const Base = parentmodule(@__MODULE__)
using .Base:
@inline, Pair, AbstractDict, IndexLinear, IndexCartesian, IndexStyle, AbstractVector, Vector,
@inline, Pair, Pairs, AbstractDict, IndexLinear, IndexCartesian, IndexStyle, AbstractVector, Vector,
tail, SizeUnknown, HasLength, HasShape, IsInfinite, EltypeUnknown, HasEltype, OneTo,
@propagate_inbounds, @isdefined, @boundscheck, @inbounds, Generator, AbstractRange,
LinearIndices, (:), |, +, -, !==, !, <=, <, missing, any, _counttuple
Expand Down Expand Up @@ -177,18 +177,6 @@ end
(i, n[1]), (i-1, ri, n[2])
end

"""
Iterators.Pairs(values, keys) <: AbstractDict{eltype(keys), eltype(values)}

Transforms an indexable container into an Dictionary-view of the same data.
Modifying the key-space of the underlying data may invalidate this object.
"""
struct Pairs{K, V, I, A} <: AbstractDict{K, V}
data::A
itr::I
Pairs(data::A, itr::I) where {A, I} = new{eltype(I), eltype(A), I, A}(data, itr)
end

"""
pairs(IndexLinear(), A)
pairs(IndexCartesian(), A)
Expand Down Expand Up @@ -240,11 +228,11 @@ pairs(::IndexCartesian, A::AbstractArray) = Pairs(A, CartesianIndices(axes(A)))

# preserve indexing capabilities for known indexable types
# faster than zip(keys(a), values(a)) for arrays
pairs(tuple::Tuple) = Pairs{Int}(tuple, keys(tuple))
pairs(nt::NamedTuple) = Pairs{Symbol}(nt, keys(nt))
pairs(v::Core.SimpleVector) = Pairs(v, LinearIndices(v))
pairs(A::AbstractArray) = pairs(IndexCartesian(), A)
pairs(A::AbstractVector) = pairs(IndexLinear(), A)
pairs(tuple::Tuple) = Pairs(tuple, keys(tuple))
pairs(nt::NamedTuple) = Pairs(nt, keys(nt))
pairs(v::Core.SimpleVector) = Pairs(v, LinearIndices(v))
# pairs(v::Pairs) = v # listed for reference, but already defined from being an AbstractDict

length(v::Pairs) = length(v.itr)
Expand All @@ -266,7 +254,7 @@ reverse(v::Pairs) = Pairs(v.data, reverse(v.itr))

haskey(v::Pairs, key) = (key in v.itr)
keys(v::Pairs) = v.itr
values(v::Pairs) = v.data
values(v::Pairs) = v.data # TODO: this should be a view of data subset by itr
getindex(v::Pairs, key) = v.data[key]
setindex!(v::Pairs, value, key) = (v.data[key] = value; v)
get(v::Pairs, key, default) = get(v.data, key, default)
Expand Down
21 changes: 11 additions & 10 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -470,15 +470,16 @@
(filter (lambda (s)
(not (any (lambda (p) (eq? (car p) (car s)))
positional-sparams)))
sparams)))
(let ((kw (gensy))
(rkw (if (null? restkw) (make-ssavalue) (symbol (string (car restkw) "..."))))
(mangled (let ((und (and name (undot-name name))))
(symbol (string (if (and name (= (string.char (string name) 0) #\#))
""
"#")
(or und '_) "#"
(string (current-julia-module-counter)))))))
sparams))
(kw (gensy))
(rkw (if (null? restkw) (make-ssavalue) (symbol (string (car restkw) "..."))))
(restkw (map (lambda (v) `(|::| ,v (call (top pairs) (core NamedTuple)))) restkw))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be merged with the first definition of restkw.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computing rkw needs the initial form (to stringify the variable name) before this wrapper is applied

(mangled (let ((und (and name (undot-name name))))
(symbol (string (if (and name (= (string.char (string name) 0) #\#))
""
"#")
(or und '_) "#"
(string (current-julia-module-counter)))))))
;; this is a hack: nest these statements inside a call so they get closure
;; converted together, allowing all needed types to be defined before any methods.
`(call (core ifelse) (false) (false) (block
Expand Down Expand Up @@ -579,7 +580,7 @@
(list `(... ,(arg-name (car vararg)))))))))))
;; return primary function
,(if (not (symbol? name))
'(null) name))))))
'(null) name)))))

;; prologue includes line number node and eventual meta nodes
(define (extract-method-prologue body)
Expand Down
2 changes: 1 addition & 1 deletion test/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ end
@test isempty(d) || haskey(d, first(keys(d)))
@test collect(v for (k, v) in d) == collect(A)
if A isa NamedTuple
K = isempty(d) ? Union{} : Symbol
K = Symbol
V = isempty(d) ? Union{} : Float64
@test isempty(d) || haskey(d, :a)
@test !haskey(d, :abc)
Expand Down