Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

map does not infere type #34

Closed
jonalm opened this issue May 16, 2019 · 0 comments · Fixed by #62
Closed

map does not infere type #34

jonalm opened this issue May 16, 2019 · 0 comments · Fixed by #62

Comments

@jonalm
Copy link

jonalm commented May 16, 2019

In the implementation of map

function Base.map(f, o::AbstractObservable, os...; init=f(o[], map(_val, os)...))
    map!(f, Observable{Any}(init), o, os...)
end

https://github.com/JuliaGizmos/Observables.jl/blob/master/src/Observables.jl#L172

Why is there an Any as a construction parameter? Shouldn't this type be inferred by the output of f here https://github.com/JuliaGizmos/Observables.jl/blob/master/src/Observables.jl#L25?

timholy added a commit that referenced this issue Jan 8, 2021
There are several things that are a bit complicated/confusing about
`map` and `map!`:
- the `init` keyword affects whether `f` runs
- in contrast with `Base.map!`, `map!(f, dest::Observable, args..)`
  does *not* update `dest`---that doesn't happen until one of `args...`
  updates
- `map` always yields an `Observable{Any}`, somewhat in contradiction
  to the behavior of `Base.map` (see #34)

This redesigns `map` and `map!` to address these issues (fixes #34).
It is a breaking change, although I've put in a depwarn for the case
where `init` was supplied. (The non-deprecated changes are so fundamental
that this may not be useful, however.)

Now:
- `map` always runs `f` on initial creation
- `map!` typically runs `f` on the initial call, but it can be
  suppressed with an `update=false` keyword
- control over output `eltype` is up to the user.

To replicate the old `init` behavior, use
    map!(f, Observable(init), args...; update=false)
To control the output type, use
    map(f, Observable{T}, args...)

For instance, the old `map` behavior is
    map(f, Observable{Any}, args...)
or with an `init` it's
    map!(f, Observable{Any}(init), args...; update=false)
timholy added a commit that referenced this issue Jan 9, 2021
There are several things that are a bit complicated/confusing about
`map` and `map!`:
- the `init` keyword affects whether `f` runs
- in contrast with `Base.map!`, `map!(f, dest::Observable, args..)`
  does *not* update `dest`---that doesn't happen until one of `args`
  updates
- `map` always yields an `Observable{Any}`, somewhat in contradiction
  to the behavior of `Base.map` (see #34)

This redesigns `map` and `map!` to address these issues (fixes #34).
It is a breaking change, although I've put in a depwarn for the case
where `init` was supplied. (The non-deprecated changes are so fundamental
that this may not be useful, however.)

Now:
- `map` always runs `f` on initial creation
- `map!` typically runs `f` on the initial call, but it can be
  suppressed with an `update=false` keyword
- `map` creates an `Observable{T}` with specific `T`, but users can
  control output `eltype` by using `map!(f, Observable{S}(), args...)`
  instead.

To replicate the old `init` behavior, use
    map!(f, Observable(init), args...; update=false)
To control the output eltype, use
    map!(f, Observable{T}(), args...)

For instance, the old `map` behavior is
    map!(f, Observable{Any}(), args...)
or with an `init` it's
    map!(f, Observable{Any}(init), args...; update=false)
timholy added a commit that referenced this issue Jan 16, 2021
There are several things that are a bit complicated/confusing about
`map` and `map!`:
- the `init` keyword also affects whether `f` runs (controlling the initial
  value is not orthogonal to execution, which spells trouble for
  functions with side effects)
- in contrast with `Base.map!`, `map!(f, dest::Observable, args..)`
  does not eagerly update `dest`---that doesn't happen until one of
  `args` updates
- `map` always yields an `Observable{Any}`, somewhat in contradiction
  to the behavior of `Base.map` (see #34)

This redesigns `map` and `map!` to address these issues (fixes #34).
It is a breaking change, although I've put in a depwarn for the case
where `init` was supplied. (The non-deprecated changes are so fundamental
that this may not be useful, however.)

Now:
- `map` always runs `f` on initial creation
- `map!` typically runs `f` on the initial call, but it can be
  suppressed with an `update=false` keyword
- `map` creates an `Observable{T}` with specific `T`, but users can
  control output `eltype` by using `map!(f, Observable{S}(), args...)`
  instead.

Using the new API, the old `map` behavior can be obtained with
    map!(f, Observable{Any}(), args...)
or with an `init` it's
    map!(f, Observable{Any}(init), args...; update=false)
timholy added a commit that referenced this issue Jan 20, 2021
There are several things that are a bit complicated/confusing about
`map` and `map!`:
- the `init` keyword also affects whether `f` runs (controlling the initial
  value is not orthogonal to execution, which spells trouble for
  functions with side effects)
- in contrast with `Base.map!`, `map!(f, dest::Observable, args..)`
  does not eagerly update `dest`---that doesn't happen until one of
  `args` updates
- `map` always yields an `Observable{Any}`, somewhat in contradiction
  to the behavior of `Base.map` (see #34)

This redesigns `map` and `map!` to address these issues (fixes #34).
It is a breaking change, although I've put in a depwarn for the case
where `init` was supplied. (The non-deprecated changes are so fundamental
that this may not be useful, however.)

Now:
- `map` always runs `f` on initial creation
- `map!` typically runs `f` on the initial call, but it can be
  suppressed with an `update=false` keyword
- `map` creates an `Observable{T}` with specific `T`, but users can
  control output `eltype` by using `map!(f, Observable{S}(), args...)`
  instead.

Using the new API, the old `map` behavior can be obtained with
    map!(f, Observable{Any}(), args...)
or with an `init` it's
    map!(f, Observable{Any}(init), args...; update=false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant