261 (1) [Avatar] Offline
#1
So far this book has been written in the tone of "phew, we got that to work!"

Honestly, that's how Elm feels to me, even after a month - except I haven't gotten to the "phew, it works" part. I'm still in the phase of "gd how do I make this work without just brute forcing everything".

Speaking directly to the author: I'm glad you were able to come up with a program that paints a bunch of concepts. It helps, somewhat.

But very soon, I need to learn how to start thinking in Elm. No tutorials or screencasts have helped me with that - and so far, this book really hasn't either.

Some questions and topics that come to mind:

* How do I design messages?
* How did you decide to separate view functions?
* Related, every time I try to build a non-trivial view, I end up with totally heterogeneous lists that don't compile - that's a pretty common noob thing, right? What's the usual plan of attack?
* How should I think ahead as I design, so views and messages and commands aren't a total mess?
* Should I be using union types however I need, just mashing anything together, or is there a right way to think about these?
* Case-ing off very different things in the update function seems... weird. Is update really supposed to just be a catch-all bucket that everyone cases?
* Is there an alternative like elixir function pattern matching? So that separate, simpler, smaller update functions can be routed to.
* How do even bigger programs deal with heterogeneity of messages, models, etc? Modularizing?
* How do I make sure I'm building good modules? How early should I be thinking this way? (Would that help solve some of the pains listed above?)

Hope this input helps. This is just part of the mess that's still swirling around in my head.

Chris
rtfeldman (60) [Avatar] Offline
#2
Hi Chris,

Thank you for the level of detail!

But very soon, I need to learn how to start thinking in Elm. No tutorials or screencasts have helped me with that - and so far, this book really hasn't either.

To be totally honest, the plan is for this to be more the focus of the last three chapters - 8, 9, and 10. The thing is, I can't assume that all readers have been supplementing with tutorials and screencasts - it's important that I thoroughly cover the basics of "how to code in Elm" before getting into "how to think in Elm."

That said, I can point you to Elm Slack and try to help with some brief answers to some of these now.

* Related, every time I try to build a non-trivial view, I end up with totally heterogeneous lists that don't compile - that's a pretty common noob thing, right? What's the usual plan of attack?

Writing Elm code that doesn't compile isn't just a noob thing, it's a programmer thing! The reason Elm code tends not to get runtime exceptions isn't that it turns us into perfect programmers, but rather that it shifts so many runtime errors to compile time. This is great for our users and for our ability to refactor, but it does mean that we're going to encounter compile errors - not just as a noob, but for as long as we're capable of making mistakes.

So I'd say the "plan of attack," as it were, is not to sweat compiler errors. Seeing compile errors - for heterogeneous lists or anything else - isn't something I'd consider a problem to be fixed. It's just the compiler doing its job!

* Case-ing off very different things in the update function seems... weird. Is update really supposed to just be a catch-all bucket that everyone cases?
* Is there an alternative like elixir function pattern matching? So that separate, simpler, smaller update functions can be routed to.

No, but if you have several related Msg constructors, it's totally reasonable to pull them out into their own union type. Then you can also split out a mini-update function that only deals with that other union type.

* How should I think ahead as I design, so views and messages and commands aren't a total mess?
* How do I make sure I'm building good modules? How early should I be thinking this way? (Would that help solve some of the pains listed above?)


Broadly speaking, the biggest mistake I see people make when transitioning from Elm beginner to working on their first serious project is this:

Too much design up front.

In general I would strongly recommend the following approach to scaling Elm apps:

1. Design less up front
2. Refactor at the drop of a hat

I think this can be counterintuitive because it's basically the opposite of what I'd recommend in JavaScript. That's because refactoring in JS is a lot more risky and error-prone.

To be a bit more specific about the refactoring part, I recommend adding to your current program in exactly the same way we've been doing in the book - that is, focusing on the new business logic itself without thinking too hard about where to put it. Then:

1. If a view function feels too big, split out part of it without splitting up update or Model.
2. If update feels too big, split out part of it without splitting up view or Model.
3. If the Model feels too big, split out part of it without splitting up view or update.

This is how we've scaled our Elm codebase at work from zero to 75,000 lines of production Elm code.

I've seen many beginners assume that this wouldn't work (which is a reasonable assumption - it certainly wouldn't in JS!) and end up inventing design patterns that lead to clunky code bases that are a lot harder to work with than they need to be.

So the best advice I can give is to refactor eagerly and design less up front. smilie

Hope this was helpful, and thank you again for the input - I'll definitely refer back to this when I get to chapters 8, 9, and 10, and I'll do my best to cover the specific things you're looking for!
9821 (4) [Avatar] Offline
#3
Regarding this:

Related, every time I try to build a non-trivial view, I end up with totally heterogeneous lists that don't compile - that's a pretty common noob thing, right? What's the usual plan of attack?


I believe that Elm 0.18 is a big step up because in 0.17, every time you have a view that doesn't compile it talks to you about the virtual dom. The new error messages in 0.18 are way, way more noob friendly.