Open bbarker opened 5 years ago
I attempted to make a DOM typeclass library, unrelated to Concur, but wanted to share my experience. The hardest part was trying to be polymorphic over the data types returned from the DOM methods, because they have sub-typing relationships and some other reason... So, that part of it might be unavoidable to use concrete types.
I don't fully understand this. The view part of a widget is swappable, and nothing inside Concur.Core
namespace depends on the actual view type. The only real dependencies on the view are the 2-3 el...
functions inside Concur.React
, but those are only used in the actual DOM element creation which is highly React specific. I don't think we get a lot of mileage out of generalising these.
Basically to port Concur to a new backend, all you would need is rewrite the el...
functions, write some smart constructors for the new view type which use those el...
functions, and write a rendering/run function to actually render the view type on the backend. It's pretty minimal code.
It's on my TODO list to separate out the generic Concur stuff into a purescript-concur-core package, and have purescript-concur-react depend on it.
I've also been meaning to write a canvas integration as an example of using a different backend. Perhaps I should go ahead and do that once core is separated.
@ajnsit Good to know about implementing the el
functions.
Say I want to write the following function:
tabPageDiv' :: El'
tabPageDiv' els =
div [className "pure-g"] [
div [menuTypeClasses] [
div [tabColClasses] els
]
]
where
menuTypeClasses = classList $
map Just ["pure-menu", "pure-menu-horizontal"]
tabColClasses = classList $
map Just ["pure-u-1", "pure-u-md-1-3"]
Since this uses div
from the Concur.React module, and say someone else has a Concur.Vue module - it would be good if this code could work with either since the idea is that this function tabPageDiv'
would be part of a library, not a user-application. After all, div
is standard - maybe how React deals with this is highly specific, but I would think the HTML
interface (as supported by Concur) for e.g. div
would be fairly standard.
It's on my TODO list to separate out the generic Concur stuff into a purescript-concur-core package, and have purescript-concur-react depend on it.
+1
The original plan was to support interop between multiple backends only at a user level, i.e. the Vue backend would define functions like div
with the same signature, and then the user just has to change the import from Concur.React
to Concur.Vue
.
But I see the value in having library code also be reusable in the same way. So a library of widgets would not import any particular backend and could be shared between different backends.
I'll keep this issue open until we have this implemented.
I just recalled backpacks, which might be useful for this. But I don't think Purescript has them yet: https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst#motivation
Started making some progress on this with https://github.com/ajnsit/purescript-concur/commit/0135377fb11dc54d8a8f5cc6e6321a05f6ff7ed3, https://github.com/ajnsit/purescript-concur/commit/11025285ad1ccdf462e43e59951917b61cab0ffa, and https://github.com/ajnsit/purescript-concur/commit/6e16e62e60e86701fcde4b62965b33e6eeec664f
Just to discuss your original plan:
The original plan was to support interop between multiple backends only at a user level, i.e. the Vue backend would define functions like div with the same signature, and then the user just has to change the import from Concur.React to Concur.Vue.
I've come across other areas in PureScript where I could really benefit from some template-based programming, using something like a pre-processor (though a non-existent PureScript-specific templating system might be preferable, I doubt it will happen anytime soon). Perhaps using something like e.g. heterocephalus or haji, but this would at least be a simple application of it.
I was thinking of creating a small CSS wrapper library for Prism.CSS and Concur. This may or may not be a good idea - too early to tell. But, it made me realize that
HTML
might be better off as a typeclass with all the element functions as typeclass members, because libraries that depend onHTML
might want to do it an implementation-independent fashion (rather than relying specifically on, say, React).To be clear it isn't something I'm in need of anytime soon.