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

Retroaliment the core with input from the rendering display #81

Open
NickSeagull opened this issue Jun 9, 2017 · 4 comments
Open

Retroaliment the core with input from the rendering display #81

NickSeagull opened this issue Jun 9, 2017 · 4 comments

Comments

@NickSeagull
Copy link
Member

This is a very interesting feature that is awesome to have. In Jupyter, one can use the interact function to generate widgets as sliders, checkboxes, textboxes and dropdowns. These are quite cool because we can create a "Display input" typeclass, to map each input to a type:

class (Show a, Read a) => DisplayInput a where
    displayInput :: a -> _

instance DisplayInput Int where  -- Same for Float, Double, ...
    displayInput = <code to display a slider>

instance DisplayInput Bool where
    displayInput = <code to display a checkbox>

instance FromString a => DisplayInput a where
    displayInput = <code to display a text input>

instance DisplayInput MySumType where
    displayInput = dropdown [ <all the MySumType constructors (must be of kind `:: *`, which basically means that it is something like an enum)> ]

data MySumType
    = Option1
    | Option2
    | Option3 deriving (Read, Show)

How this would work?

I had an interesting talk with Simon Thompson, and this idea came out:

We setup a websocket/endpoint that is listening in some other port. We will add a script tag inside our display (when it gets generated), and that script tag has some code to send messages through the websocket/endpoint. Then these displayInputs simply are HTML elements with onclick or other attributes that just call the function defined in the script tag we created before.

In the Haskell side, the websocket/endpoint will wait until, and we, somehow, will pass a Map to our Compilation module, where, before compilation, the different variables will be substituted by the values we selected in our widgets, but we will save the previous code. The code gets compiled, rendering is executed and then we substitute the code back, so our markdown editor still has the code we've written.

Thinking about this better, it introduces some stuff that doesn't seem reasonable from a user's perspective, if they want to use the module they've generated in haskell.do in a project:

  • They have to depend in a module that is already outside of the scope, of their project (displaying stuff)
  • The code gets modified in compile time, and it gets back to it's previous state, but still they have the rendered code with some other value.

Another idea that comes to mind is use some annotation like Liquid Haskell uses, inside comments:

liquid haskell magic

Maybe we could have something like:

{-@ displayInput @-}
myValue :: Int
myValue = 10

In this way, we don't force the user to depend on the DisplayInput module, and we just define the value at the moment. In this case, it will start in 10, but as soon as the user moves the slider, it will just change the value of the variable and it will leave the value like that, which is very useful if you are fine-tuning parameters, for example, say, in a neural network.

@NickSeagull
Copy link
Member Author

After proposing this, I think it it more flexible for us to use just normal functions/typeclasses, because, it is more extensible in the end. Maybe there could be something like a "cleanup" button?

@NickSeagull NickSeagull added this to Backlog in HaskellDO Jun 10, 2017
@o1lo01ol1o
Copy link

o1lo01ol1o commented Jun 10, 2017

I think typeclasses are the way to go, allowing users to extend the class with their own instance (potentially using one of the reactive frameworks like react flux) is way preferable to generic inputs.

(This would also make haskell-do an interactive visualization development environment: you could potentially take a haskell-do project and stick it onto an existing endpoint on some server and have a functioning data-driven webapp.)

I don't know enough about the internals of haskell-do: why wouldn't you just pass any defined display instances to GHCJS on compile and embed the bundled html/js/websocket pipe in the frontend wherever eval is called?

@NickSeagull
Copy link
Member Author

NickSeagull commented Jun 10, 2017

Because that would require the user to have GHCJS installed, and definitely, that is not an option in my opinion. @o1lo01ol1o

@o1lo01ol1o
Copy link

Ah right, somehow I thought js was being compiled on the fly.

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

No branches or pull requests

2 participants