Developer UX, Tools & Errors for Humans

A Talk About Type Theory

Just Kidding

This is not a Type Theory Talk

Gradual Learning

When do you become productive?

Evan Czaplicki claims that you can pick up Elm cold and lean on the tools to become productive early on the learning curve. I decided to put that to the test, and see if developer UX improves learning. At least for n(1)

The Elm Compiler

  • If it compiles it (generally) works

  • Errors focus on Expected vs Actual types things ;)
  • Beginner Hints
  • Tries to catch logic errors

A simple counter

main =
  beginnerProgram { model = 0, view = view, update = update }


view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (toString model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]


type Msg = Increment | Decrement


update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1

Try to add a new button

Sad compiler

type Msg = Increment | Decrement


update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1
    
    Reset ->
      model - 1
Detected errors in 1 module.


-- NAMING ERROR -------------------------

Cannot find pattern `Reset`

30|     Reset ->
        ^^^^^

1 more time

 Still sad compiler

type Msg = Increment | Decrement | Reset


update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1
    
    Reset ->
      model = 0
Detected errors in 1 module.


-- SYNTAX PROBLEM --------------------------------------------------------------

I ran into something unexpected when parsing your code!

31|       model = 0
                ^
I am looking for one of the following things:

    end of input
    whitespace

Finally

main =
  beginnerProgram { model = 0, view = view, update = update }


view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (toString model) ]
    , button [ onClick Increment ] [ text "+" ]
    , button [ onClick Reset ] [ text "reset" ]
    ]


type Msg = Increment | Decrement | Reset


update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1
    
    Reset ->
     0

A thing that works!

Now For The Demos!

Awesome!

So Elm is the new hotness and I should use it right? 

Do you like functional programing

or want to learn more about it?

Great, maybe try Elm

I also kind of like Bucklescript

Do you hate functional programming

or perhaps just prefer OO?

Then don't use Elm, it is very much a functional language

But...

Elm has really nice tools and you should at least check it out so that when you write tools or libraries, you can pass some of these great ideas to your users!

Focus on a good user experience

  • Provide clear error messages
  • Don't assume your users are experts
  • Make the documentation correct
  • Make the documentation good
  • Focus on the principle of least surprise
  • Enable exploration/discovery

I love Elixir,

it has really great tools, most of the time

But not always

iex(5)>     url = "https://auth.drxwebservices.com/v1/auth/token?format=json"
"https://auth.drxwebservices.com/v1/auth/token?format=json"
iex(6)> body = "grant_type=client_credentials"
"grant_type=client_credentials"
iex(7)>     headers = ["Content-Type": "application/x-www-form-urlencoded"]
["Content-Type": "application/x-www-form-urlencoded"]
iex(8)> options = [hackney: [
...(8)>                 basic_auth: {"my key", "my secret"}]]
[hackney: [basic_auth: {"my key",
   "my secret"}]]
iex(9)> HTTPoison.post(url, body, headers, options)
{:error, %HTTPoison.Error{id: nil, reason: :closed}}

WTF does that even mean?

So we updated the docs

Ruby's Pry makes it easy to explore, and tries not to surprise you

[27] pry(main)> cd String
[28] pry(String):1> ls
constants: BLANK_RE
Object.methods: JSON  yaml_tag
JSON::Ext::Generator::GeneratorMethods::String::Extend#methods: json_create
String.methods: try_convert
String#methods:
  %                  capitalize!    each_codepoint  indent           purple            squish                                  to_r
  *                  casecmp        each_line       indent!          purpleish         squish!                                 to_s
  +                  center         empty?          index            red               start_with?                             to_str
  +@                 chars          encode          inquiry          redish            starts_with?                            to_sym
  -@                 chomp          encode!         insert           remove            strip                                   to_time

# omitted because there are like 1,000,000 more
[1] pry(main)> cd String
[2] pry(String):1> show-method capitalize!

From: string.c (C Method):
Owner: String
Visibility: public
Number of lines: 33

static VALUE
rb_str_capitalize_bang(VALUE str)
{
    rb_encoding *enc;
    char *s, *send;
    int modify = 0;
    unsigned int c;
    int n;

...

So Why Does This Matter?

Bad error messages make debugging more difficult

  • Now it takes longer to squash user bugs
  • We have finite time, and slow debugging means we get to do fewer things we may otherwise want to do
  • Developers will abandon your tool/lib/language if its harder to use than it is valuable

Your Users Aren't "Experts"

  • They may be, but that doesn't mean they are experts in your library, and they shouldn't have to be
  • Do you want people to use your code?

Incorrect documentation is worse than no documentation!

Once the Docs are right, they need to be good

  • This helps users find new functionality
  • Good docs make your code easier to contribute to
  • It reduces "how does x work" issues

Surprising Behavior is Awful

  • Surprising behavior might mean your code doesn't have cohesive internal logic
  • If a function behaves in an unexpected way, it will cause bugs
  • Do you want people to use your code?

Enable exploration/discovery

  • If users can discover functionality they'll naturally learn about your project
  • A help function is great
  • Writing readable code is even better

Thanks for Listening!

Chase Gilliam

@chasegilliam

Avhana Health

Dev UX

By Chase Gilliam

Dev UX

  • 105