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

Should Graphics.* modules be moved to a separate package? #324

Closed
avh4 opened this Issue Aug 2, 2015 · 2 comments

Comments

Projects
None yet
3 participants
@avh4
Member

avh4 commented Aug 2, 2015

(Creating this at Evan's request to collect ideas on this topic.)

Splitting out graphics

It has been a recurring topic on the elm-discuss to ask about when to use Graphics.Element vs evancz/elm-html (see links below). The advice that usually is given is that Graphics.Element is a simple API for playing around with Elm, but that it is an old API that needs to be updated/improved, and that most normal applications probably want to use elm-html instead (at least at the present time).

Pros (reasons to move Graphics.* to a separate package):

  • There are several useful rendering packages (evancz/elm-html, johnpmayer/elm-webgl, and Graphics.*), and there will hopefully be more in the future (vilterp/elm-diagrams, mgold/elm-turtle-graphics, etc). We are still not sure if there is a single best approach to graphics, and we still want to encourage the use of different rendering packages
  • The community currently is recommending evancz/elm-html as the preferred rendering library for most applications (via elm-discuss: Graphics.Element vs elm-html, Graphics vs Html, Migrated my website from Graphics.Element to elm-html, elm-html: the future or a stopgap?)
  • Graphics.* is an old API and needs to be updated. It would be less-intimidating and easier for people to experiment with updating the Graphics API if it were separate from core
  • There is an approaching goal to support running Elm code in node.js for server-side code, meaning that it would not make sense to have graphics-related functionality in core, since it will be used in headless environments
    • counterargument: the opinion that is no use for graphics on the server-side does not mean that those modules should be removed as long as they don't hurt anything

Cons (reasons to keep Graphics.* in core:

  • Graphics.Element and Graphics.Collage are considered easy to understand for beginners, and make it easy to have good-looking and easy-to-understand demos on elm-lang.org
  • Having no rendering engine in core means that newcomers have to learn about packages sooner

Splitting out related modules

In addition, the following must be considered: Color, Text, and Transform2D are modules in core that relate to graphics. If Graphics is split out as a separate package, should these modules move to the new package, stay in core, or be put in another separate package?

Pros (reasons to move Color, Text, Transform2D out of core):

  • Their use is commonly related to the use of Graphics.*

Cons (reasons to keep Color, Text, Transform2D in core):

  • They are common data types that many rendering and other packages might want to use. Moving them to an elm-graphics packages might lead to other package developers writing their own modules for Color, Text, etc, which could lead to inconsistency and confusion and incomplete or incorrect modeling of the data types.
@TheSeamau5

This comment has been minimized.

Show comment
Hide comment
@TheSeamau5

TheSeamau5 Aug 2, 2015

Contributor

Idea inspired from Dart.

Dart ships with its standard library included. This standard library includes dart:html and dart:io. The way they handle this (I don't know if this is still the case today) is that you can't import both libraries in the same file. The rationale is that one runs only in the browser and the other only in the server.

The Dart idea is too harsh because we want to use elm-html in the server for server-side rendering and there are a few bits and pieces from IO that work on the server.

So, how would we solve this? namespacing, of course.

Any library that requires the browser should be prefixed with web(or Web in the import line). Any library that requires the server should be prefixed with io (or IO in the import line). Any library that can work in both is dispensed from such a prefix.

For example:

In the server:

import IO.File
import IO.Http
import IO.Buffer
import Html
import Check
import ElmTest

In the browser:

import Web.Canvas 
import Web.GL
import Web.Audio
import Html
import Check
import ElmTest

Furthermore, any library that has a dependency on a Web library is automatically a Web library, any library that has a dependency on an IO library is automatically an IO library, and if a library doesn't have such dependencies it is neither. This can be guaranteed by the compiler (modulo native modules).

This would mean that the elm core library would be divided in three parts (the parts that work only on the web, the parts that work only on the server, and the parts that work on both).

For example, we could imagine the package listing looking like this

Web-Only (prefixed with Web):

  • Canvas
  • GL
  • Audio
  • UserMedia
  • File
  • Mouse
  • Touch
  • Keyboard
  • Window
    etc...

IO-Only (prefixed with IO):

  • File
  • Path
  • Buffer
  • Crypto
  • OS
  • Http
  • Https
  • UDP
    etc...

Both :

  • Array
  • List
  • Dict
  • Set
  • Basics
  • String
  • Char
  • Task
  • Signal
  • Html
    etc...

And, then when you import the core library, you get everything. You only use what you've imported and the compiler checks that you don't mix both web and io libraries. We might need to find a solution for libraries which wish to abstract common code between them.

Maybe the pattern would be to import both your library and your shell library and have a way to say that you import either this library or that library, whatever is available? Or a better solution should be found? What do you think?

Contributor

TheSeamau5 commented Aug 2, 2015

Idea inspired from Dart.

Dart ships with its standard library included. This standard library includes dart:html and dart:io. The way they handle this (I don't know if this is still the case today) is that you can't import both libraries in the same file. The rationale is that one runs only in the browser and the other only in the server.

The Dart idea is too harsh because we want to use elm-html in the server for server-side rendering and there are a few bits and pieces from IO that work on the server.

So, how would we solve this? namespacing, of course.

Any library that requires the browser should be prefixed with web(or Web in the import line). Any library that requires the server should be prefixed with io (or IO in the import line). Any library that can work in both is dispensed from such a prefix.

For example:

In the server:

import IO.File
import IO.Http
import IO.Buffer
import Html
import Check
import ElmTest

In the browser:

import Web.Canvas 
import Web.GL
import Web.Audio
import Html
import Check
import ElmTest

Furthermore, any library that has a dependency on a Web library is automatically a Web library, any library that has a dependency on an IO library is automatically an IO library, and if a library doesn't have such dependencies it is neither. This can be guaranteed by the compiler (modulo native modules).

This would mean that the elm core library would be divided in three parts (the parts that work only on the web, the parts that work only on the server, and the parts that work on both).

For example, we could imagine the package listing looking like this

Web-Only (prefixed with Web):

  • Canvas
  • GL
  • Audio
  • UserMedia
  • File
  • Mouse
  • Touch
  • Keyboard
  • Window
    etc...

IO-Only (prefixed with IO):

  • File
  • Path
  • Buffer
  • Crypto
  • OS
  • Http
  • Https
  • UDP
    etc...

Both :

  • Array
  • List
  • Dict
  • Set
  • Basics
  • String
  • Char
  • Task
  • Signal
  • Html
    etc...

And, then when you import the core library, you get everything. You only use what you've imported and the compiler checks that you don't mix both web and io libraries. We might need to find a solution for libraries which wish to abstract common code between them.

Maybe the pattern would be to import both your library and your shell library and have a way to say that you import either this library or that library, whatever is available? Or a better solution should be found? What do you think?

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 3, 2015

Member

Adding to #322 for consideration in a revamp of the core libraries. Thanks for outlining this! Further discussion should happen here even though it's closed now.

Member

evancz commented Aug 3, 2015

Adding to #322 for consideration in a revamp of the core libraries. Thanks for outlining this! Further discussion should happen here even though it's closed now.

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