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
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* [Kernel] Implement `defmodule/2`, `@/1`, `def/2` and friends in Elixir itself. `case/2`, `try/2` and `receive/1` have been made special forms. `var!/1`, `var!/2` and `alias!/1` have also been implemented in Elixir and demoted from special forms
* [Record] Support dynamic fields in `defrecordp`
* [Stream] Add `Stream.resource/3`
* [Stream] Add `Stream.zip/2`, `Stream.filter_map/3`, `Stream.each/2`, `Stream.take_every/2`, `Stream.chunks/2`, `Stream.chunks/3`, `Stream.chunks/4`, `Stream.chunks_by/2`, `Stream.scan/2`, `Stream.scan/3` and `Stream.uniq/2`
* [Stream] Support `Stream.take/2` and `Stream.drop/2` with negative counts
* [Typespec] Support `is_var/1` in typespecs

* Bug fixes
Expand All @@ -16,13 +18,17 @@
* [Mix] Also symlink `include` directories in _build dependencies

* Deprecations
* [Enum] `Enumerable.count/1` and `Enumerable.member?/2` should now return tagged tuples. Please see `Enumerable` docs for more info
* [File] `File.binstream!/3` is deprecated. Simply use `File.stream!/3` which is able to figure out if `stream` or `binstream` operations should be used
* [Macro] `Macro.extract_args/1` is deprecated in favor of `Macro.decompose_call/1`
* [Typespec] `when` clauses in typespecs were moved to the outer part of the spec

* Backwards incompatible changes
* [Kernel] Behaviour of `Enum.drop/2` and `Enum.take/2` has been switched when given negative counts
* [Enum] Behaviour of `Enum.drop/2` and `Enum.take/2` has been switched when given negative counts
* [Enum] Behaviour of `Enum.zip/2` has been changed to stop as soon as the first enumerable finishes
* [Enum] `Enumerable.reduce/3` protocol has changed to support suspension. Please see `Enumerable` docs for more info
* [Mix] Require `:escript_main_module` to be set before generating escripts
* [Range] `Range.Iterator` protocol has changed in order to work with the new `Enumerable.reduce/3`. Please see `Range.Iterator` docs for more info
* [Stream] The `Stream.Lazy` structure has changed to accumulate functions and accumulators as we go (its inspected representation has also changed)

# v0.11.2 (2013-11-14)
Expand Down
1 change: 0 additions & 1 deletion lib/elixir/lib/dict.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ defmodule Dict do
defcallback update(t, key, value, (value -> value)) :: t
defcallback update!(t, key, (value -> value)) :: t | no_return
defcallback values(t) :: list(value)
defcallback reduce(t, any, ({key, value}, any -> any)) :: any

defmacrop target(dict) do
quote do
Expand Down
52 changes: 28 additions & 24 deletions lib/elixir/lib/dict/behaviour.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,37 +48,31 @@ defmodule Dict.Behaviour do
:error -> default
end
end
defoverridable get: 2, get: 3

def fetch!(dict, key) do
case fetch(dict, key) do
{ :ok, value } -> value
:error -> raise(KeyError, key: key)
:error -> raise KeyError, key: key
end
end
defoverridable fetch!: 2

def has_key?(dict, key) do
match? { :ok, _ }, fetch(dict, key)
end
defoverridable has_key?: 2

def put_new(dict, key, value) do
update(dict, key, value, fn(v) -> v end)
end
defoverridable put_new: 3

def drop(dict, []), do: dict

def drop(dict, [key|keys]) do
drop(delete(dict, key), keys)
end
defoverridable drop: 2

def take(dict, keys) do
take(dict, keys, new)
end
defoverridable take: 2

defp take(_dict, [], acc), do: acc
defp take(dict, [key|keys], acc) do
Expand All @@ -88,38 +82,48 @@ defmodule Dict.Behaviour do
end
end

def to_list(dict), do: reduce(dict, [], &[&1|&2]) |> Enum.reverse
defoverridable to_list: 1
def to_list(dict) do
reduce(dict, { :cont, [] }, fn
kv, acc -> { :cont, [kv|acc] }
end) |> elem(1) |> :lists.reverse
end

def keys(dict), do: reduce(dict, [], fn({k, _}, acc) -> [k | acc] end) |> Enum.reverse
defoverridable keys: 1
def keys(dict) do
reduce(dict, { :cont, [] }, fn
{k, _}, acc -> { :cont, [k|acc] }
end) |> elem(1) |> :lists.reverse
end

def values(dict), do: reduce(dict, [], fn({_, v}, acc) -> [v | acc] end) |> Enum.reverse
defoverridable values: 1
def values(dict) do
reduce(dict, { :cont, [] }, fn
{_, v}, acc -> { :cont, [v|acc] }
end) |> elem(1) |> :lists.reverse
end

def equal?(dict1, dict2) do
import Kernel, except: [size: 1]
case size(dict1) == size(dict2) do
false -> false
true ->
try do
reduce(dict1, nil, fn({ k, v }, _acc) ->
unless fetch(dict2, k) == { :ok, v }, do: throw(:error)
end)
true
catch
:error -> false
end
true ->
reduce(dict1, { :cont, true }, fn({ k, v }, _acc) ->
unless fetch(dict2, k) == { :ok, v } do
{ :halt, false }
else
{ :cont, true }
end
end) |> elem(1)
end
end
defoverridable equal?: 2

def merge(dict, enumerable, callback // fn(_k, _v1, v2) -> v2 end) do
Enum.reduce(enumerable, dict, fn({key, value}, acc) ->
update(acc, key, value, fn(v1) -> callback.(key, v1, value) end)
end)
end
defoverridable merge: 2, merge: 3

defoverridable merge: 2, merge: 3, equal?: 2, to_list: 1, keys: 1,
values: 1, take: 2, drop: 2, get: 2, get: 3, fetch!: 2,
has_key?: 2, put_new: 3
end
end
end
Loading