Jumping from `text "html.Hello!"` to `Browser`

Why I can’t just use html - why Browser is necessary?


I discovered https://elm-lang.org/examples/hello as a better starting point for my understanding of Elm. After elm init spent quite a while to run it, because online hello doesn’t include module Main exposing (..). I’ve got this working example in my browser.

module Main exposing (..)
import Html exposing (text)

main =
  text "Hello!"

Now when I read https://guide.elm-lang.org/architecture/buttons.html it explains what Main is, but uses Browser.sandbox and doesn’t explain why it is needed if html module already allows to create content?

main =
  Browser.sandbox { init = init, update = update, view = view }

For the tutorial I would appreciate explanation of how to make nested html markup after being introduced to hello, and before jumping to Model, View. Update part.

Html can be either static or interactive. If you don’t need to interact with the created html, you can use just plain html in the main. If you need interaction (like it is the case with the buttons example) you need to let Elm know that the output is not a simple html but a Program (something that has state and responds to user interaction).

the buttons example that you link has an example on how to make this in the view:

  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]

You can use this example without the event handling and the model stuff:

module Main exposing (..)
import Html exposing (..)

main =
  div []
    [ button [ ] [ text "-" ]
    , div [] [ text "5" ]
    , button [  ] [ text "+" ]
    ]
1 Like

Browser object adds dynamic behavior. That’s seems logical.

However, for the simple static site with one <div>, one <button> and a few SVG tags below, why the resulting index.html size is so big?

94222 Jan 29 17:05 index.html
module Main exposing (..)

import Html exposing (div, button, text)
import Html.Attributes exposing (style)
import Svg exposing (..)
import Svg.Attributes exposing (..)

main =
  div [] [
  button [ Html.Attributes.style "height" "20px",
           Html.Attributes.style "padding" "0",
           -- trying to keep text label inside button
           Html.Attributes.style "line-height" "0",
           -- place button at the top of the parent div
           Html.Attributes.style "vertical-align" "top"
         ]
         [ Html.text ">>" ],
  svg
    [ width "400", height "100" ]
    [ rect [ width "10", height "10" ] []
    , rect [ x "10", y "10", width "10", height "10" ] []
    , rect [ x "20", y "10", width "10", height "10" ] []
    , rect [ x "30", y "10", width "10", height "10" ] []
    , rect [ x "40", y "10", width "10", height "10" ] []
    , rect [ x "50", y "10", width "10", height "10" ] []
    , rect [ x "60", y "10", width "10", height "10", fill "red" ] []
    , rect [ x "70", y "10", width "10", height "10", fill "green" ] []
    ]]

The resulting index.html is not a static text. It still has the entire implementation of the core libraries used.

While the dead code elimination is very good when considering regular Elm libraries, it is not as good when considering libraries implemented with Kernel code.

There is code being worked on that will provide server-side rendering. This will output static text that will be as small as possible.

1 Like

One further thing to consider to answer your question.

Using main = html ... is really there to make either simple prototyping easier or to allow beginners to get started smoothly. It is not how Elm is typically used. Therefore there is not much point in optimising that - it’s not something that is likely to matter much.

1 Like

When trying to jump to Browser I noticed that main becomes a function that not just returns Html object, but also the msg.

> import Html
> main = Html.div [] []
<internals> : Html.Html msg

At first I thought that the output of main is the rendered HTML text that is just being printed to stdout. Now that you’ve mentioned that main = html is a syntax sugar, I am interested who is processing the Html.Html object and msg argument? If it is not Browser object, then what?

Who is responsible for managing the feedback loop described in https://guide.elm-lang.org/architecture/ - the Browser or the Elm itself?

Does the loop work for the simple case of main = html?

First a little bit of clarification Html msg means "an Html type producing msg" It is the full name of a single type. There is no object receiving an argument. msg in Html msg is a type variable just like a in List a. List a means “a List of as” . List String is “a List of Strings”.

The value of main is handled by the runtime. The value can be of type Html msg OR Program flags msg model. Browser.sandbox or Browser.application are functions that produce this Program type.
The loop described in the elm architecture is not involved in the simple case.

What you see in the repl is an implementation detail. <internals> : Html.Html msg is just elm repl attempting to represent as a string an Html msg value. Because Html msg is an opaque custom type, it’s string representation is <internals>.

It could have been <div></div> : Html msg if there would have been a function like Html.toString that would have been used internally for the representation of the Html msg values. This is not the case for various reasons that have to do with implementation details.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.