gleam_decode icon indicating copy to clipboard operation
gleam_decode copied to clipboard

Create example applications

Open rjdellecese opened this issue 5 years ago • 7 comments

If the Elm community's experience is anything to go by, decoders can be quite difficult for people to understand!

Elixir and Erlang examples in the form of complete applications would help people understand how decoding fits into the broader story of Gleam interop. Given that there aren't too many examples of Gleam interop right now, it would probably help flesh out an understanding of that broader story, too.

Ideally these applications would have many examples of how to decode many different kinds of things, in at least some different contexts (the examples for the dillonkearns/elm-graphql tool are the kind of thing I'm thinking of).

rjdellecese avatar Dec 26 '19 02:12 rjdellecese

Some examples that should be included:

  • What to do when you run out of map functions (use intermediate types to map in chunks and then put it all together, or use then)
  • What to do when you're trying to decode a list of different types of values

Please suggest others if you can think of any!

rjdellecese avatar Dec 26 '19 03:12 rjdellecese

I'd like to see examples of how to handle gracefully when the data doesn't align with the specification described. What happens and how to recover without using exceptions for control flow?

mgwidmann avatar Dec 28 '19 18:12 mgwidmann

Thanks @mgwidmann, that's a great suggestion! I think that will be a common question that people will have. I'll make sure that these example applications cover that case, too.

If you are playing around with the library and have a specific example of the above that you need help with, please feel free to open an issue and I'll be happy to offer some ideas.

rjdellecese avatar Dec 28 '19 19:12 rjdellecese

  • What to do when you run out of map functions (use intermediate types to map in chunks and then put it all together, or use then)

Instead of documenting this approach have you considering adding some functions similar to the Elm json-decode-pipeline?

chazsconi avatar May 10 '20 09:05 chazsconi

@chazsconi unfortunately that kind of approach isn't currently possible in Gleam, as Gleam doesn't have auto-currying! I'm not actually sure if "auto-currying" is the formal term, but let me try to convey the idea.

In Elm, I can do this:

add :: Int -> Int -> Int
add n m =
    n + m

-- This partial application returns a function with the value 1 substituted for n.
add 1 -- (Int -> Int)

-- You could also do this, but you don't need to.
addOne :: Int -> Int
addOne n =
    add n 1

In Gleam we can't do that:

pub fn add(x: Int, y: Int) -> Int {
  x + y
}

// Instead of returning a function that takes an Int and adds one to it,
// this will just raise a compilation error wherever it's used.
add(1)

// So we need to do this instead.
pub fn add_one(x: Int) -> Int {
  add(x, 1)
}

Elm's json-decode-pipeline library relies on this "auto-currying" to work its magic so, for the moment at least, explicitly using named map functions are our only option.

rjdellecese avatar May 10 '20 23:05 rjdellecese

@mgwidmann That makes sense. I hadn't looked at how the elm code was implemented. Thanks for the clear explanation 👍

chazsconi avatar May 12 '20 06:05 chazsconi

@rjdellecese for those desperately needing more fields in mapN, they could always use a continuation passing style. It won't be pretty but it should work.

This is a library that uses this approach in Elm: https://github.com/webbhuset/elm-json-decode/blob/1.1.0/src/Json/Decode/Field.elm#L51

AFAIK we do not have <| in Gleam so this approach will probably end in "callback hell", but it should be a usable solution for people that need something now.

mradke avatar Mar 16 '21 06:03 mradke