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

Discussion: making HTML a typeclass #14

Open
bbarker opened this issue Mar 19, 2019 · 7 comments
Open

Discussion: making HTML a typeclass #14

bbarker opened this issue Mar 19, 2019 · 7 comments
Assignees

Comments

@bbarker
Copy link
Contributor

bbarker commented Mar 19, 2019

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 on HTML 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.

@chexxor
Copy link

chexxor commented Mar 19, 2019

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.

@bbarker bbarker changed the title Dicussion: making HTML a typeclass Discussion: making HTML a typeclass Mar 19, 2019
@ajnsit
Copy link
Member

ajnsit commented Mar 19, 2019

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.

@bbarker
Copy link
Contributor Author

bbarker commented Mar 19, 2019

@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

@ajnsit ajnsit self-assigned this Mar 20, 2019
@ajnsit
Copy link
Member

ajnsit commented Mar 20, 2019

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.

@bbarker
Copy link
Contributor Author

bbarker commented Mar 20, 2019

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

@ajnsit
Copy link
Member

ajnsit commented Jun 9, 2019

Started making some progress on this with 0135377, 1102528, and 6e16e62

@bbarker
Copy link
Contributor Author

bbarker commented Mar 3, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants