elm / error-message-catalog

A catalog of broken Elm programs / data to improve error messages
BSD 3-Clause "New" or "Revised" License
173 stars 17 forks source link

Port in file without module header #286

Closed 01mf02 closed 5 years ago

01mf02 commented 5 years ago

When a port is defined and used in an Elm file without a module header, the Elm compiler says no variable with the name of the port can be found. I would have expected the compiler to point out that a header line port module ... has to be added in order to use ports in the file.

import Browser
import Html exposing (Html, div)

-- MAIN

main =
  Browser.element
    { init = init
    , update = update
    , view = view
    , subscriptions = subscriptions
    }

-- PORTS

port myPort : Cmd msg

-- MODEL

type alias Model = ()

init : () -> (Model, Cmd Msg)
init _ =
  ( ()
  , myPort
  )

-- UPDATE

type alias Msg = ()

update : Msg -> Model -> (Model, Cmd Msg)
update msg model = (model, Cmd.none)

-- VIEW

view : Model -> Html Msg
view model =
  div [] [ ]

subscriptions model =
  Sub.none

The error message:

Detected errors in 1 module.                                         
-- NAMING ERROR --------------------------------------------------- src/test.elm

I cannot find a `myPort` variable:

31|   , myPort
        ^^^^^^
These names seem close though:

    floor
    not
    sqrt
    xor

Hint: Read <https://elm-lang.org/0.19.0/imports> to see how `import`
declarations work in Elm.

P.S.: Thanks for the otherwise awesome error messages in Elm! :)

evancz commented 5 years ago

The behavior is improved a bit in the development build of the compiler.

In the next version, it will only be possible to leave off the module line if you are creating a file outside of your src/ directories. I expect that case to be most commonly used by beginners trying out Elm for the first time or by experts trying out something real quick. In either case, it actually doesn't complain if you have ports. It just works under the theory that requiring the port module line isn't making anything better.

If the file is in your src/ directories, and you do have an incorrect module declaration, it is saying:

-- UNEXPECTED PORTS -------------------------------------------- src/Example.elm

You are declaring ports in a normal module.

1| module Example exposing (..)
   ^^^^^^
Switch this to say port module instead, marking that this module contains port
declarations.

Note: Ports are not a traditional FFI for calling JS functions directly. They
need a different mindset! Read <https://elm-lang.org/0.19.1/ports> to learn the
syntax and how to use it effectively.

So I think the situation will be improved once Elm 0.19.1 is released. Thank you for the report!