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

0.4: map function doesn't support union types #76

Open
twavv opened this issue Oct 7, 2021 · 5 comments
Open

0.4: map function doesn't support union types #76

twavv opened this issue Oct 7, 2021 · 5 comments

Comments

@twavv
Copy link
Member

twavv commented Oct 7, 2021

map!(f, Observable(f(arg1[], map(to_value, args)...)), arg1, args...; update=false)

For context, I have code that returns different things based on the state of observable:

app = Canvas()
hbox(app, map(app) do img_matrix
        if img_matrix === nothing
            return html"<b>Draw something!</b>"
        end
        heatmap_digit(img_matrix; size=(300, 300))
    end
)

This causes issues™:

MethodError: Cannot `convert` an object of type Plots.Plot{Plots.GRBackend} to an object of type HTML{String}
Closest candidates are:
  convert(::Type{T}, ::T) where T at essentials.jl:171
  HTML{String}(::Any) where T at docs/utils.jl:23

I think it's the line referenced above that creates an Observable{T} where T is the type of the return value of the mapper function the first time it's executed.

CC @rajraomichigan

@timholy
Copy link
Member

timholy commented Oct 9, 2021

You can create an observable like this: Observable{Union{TypeA, TypeB}}(args...). Does that fix it?

@twavv
Copy link
Member Author

twavv commented Oct 11, 2021

I think it does, but definitely a far less convenient syntax and definitely a gotcha that you can't just "use map".

Is there any way to infer the return type of a function and use that? (Instead of just the type of the functions return value from the initial evaluation)

@timholy
Copy link
Member

timholy commented Oct 11, 2021

definitely a far less convenient syntax

You can also use Observable{Any} instead of Observable. 5 more characters.

Is there any way to infer the return type of a function and use that?

Yes, that's possible too. Of course, it gives you something too wide if your code breaks inferrability, but Observable{Any} is not the worst thing that can happen to someone. Historically we tried to use inference only to handle the empty-container problem, so this would be a violation, but there are several in Base already. Want to put together a PR?

@twavv
Copy link
Member Author

twavv commented Oct 11, 2021

I can do a PR. I don't know how I'd go about it. Is there a de facto way of determining the return type of a function nowadays?

And by convenient syntax, I mean the map syntax. Correct me if I'm wrong but what you're suggesting would require creating a new observable and map!-ing into it.

@timholy
Copy link
Member

timholy commented Oct 11, 2021

Check out MappedArrays which seems to have wholeheartedly embraced your proposed strategy. (Just the simple stuff, don't worry about the fancy anonymous-function printing.)

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

No branches or pull requests

2 participants