Status Report - 5 Sept 2016

1 077 megtekintés
Ugrás az első olvasatlan üzenetre

Evan Czaplicki

olvasatlan,
2016. szept. 5. 16:49:062016. 09. 05.
– elm-dev
Last week I got --debug to a really nice place. The next phase is to get "swapping" working in conjunction with elm-reactor, so folks can save code and see the new functionality in their browser automatically without losing their session history.

That next phase is a pretty big project and I found I needed to take a break to get productive on it, so I did the following things.


Blog

Finish and publish the blog post on performance. I felt the post could have done a lot better on Hacker News, so I found this release kind of frustrating. There were a lot of folks saying silly things. That motivated me to take a look at ways of making it so no one says silly things anymore.


Documentation

I channeled that motivation into:
  • Redoing the home page to be more visual and clear. (Would still love a PR to convert images of code into HTML blocks!)
  • Consolidating installation and "get started" docs in one place that also dumps people into the guide, so there is no way to miss the official documentation.
  • Adding a section on reuse to the guide to try to get us over this "components" confusion. So far, it has had quite a nice response!
So it sort of felt like a good time to return to elm-reactor, but the NoRedInk Elm Friday came up, and we decided to work on localStorage.


Local Storage

People have been requesting this for ages. I have worked on it multiple times in the past and never been happy with the results, so it kept getting scheduled for a revisit.

This time, I think I figured out why the results felt unsatisfactory, and I'm really excited about taking it in a different direction, described here.

I'll write a bit more about this in a separate post.

Wouter In t Velt

olvasatlan,
2016. szept. 5. 17:56:582016. 09. 05.
– elm-dev
Thank you for clearing up my "components confusion". This was a hard habit to break, coming from react+flux. Your reuse section in the guide is a real gem!

Oliver Searle-Barnes

olvasatlan,
2016. szept. 6. 3:45:182016. 09. 06.
– elm-dev
At the risk of adding some noise, I also wanted to add a note of thanks for reuse. My first month with Elm has involved a huge amount of thought and discussion on that topic. Had this resource been available it would have made my introduction to Elm far easier (it's still been incredibly fun so far though). The new guide seems very clear and I see it constantly being referenced now on slack, so great job and thanks again! 

Charles-Edouard Cady

olvasatlan,
2016. szept. 7. 4:24:022016. 09. 07.
– elm-dev
Thank you for the "Scaling the Elm architecture" section! It's very nice.
Would it be possible to add an example of a reusable a widget (eg. a calendar) that has an internal state (eg. shown/not shown, day hovered, current month etc.) that the rest of the application does not depend on?
I found myself reusing the view by adding the msg it uses as parameter (wrapping it in a record if there are a lot of them) and having a "local" update function which only updates the part of the model that concerns the calendar.
This has proved quite satisfactory in practice, but I would like to have your opinion on this.

Essentially, view has this signature:

view : ParentModel -> InternalModel -> ParentMsg a msg -> (InternalMsg -> msg) -> (Html.Html msg)

where ParentMsg is, eg.

type alias ParentMsg a msg =
 
{ a
 
| setDate : Date -> msg
 
}

Obviously, you do not always need an InternalMsg (eg. for a slider widget or any of the examples given in the guide), but I do think this pattern comes in handy sometimes... What do you think?

OvermindDL1

olvasatlan,
2016. szept. 7. 11:01:042016. 09. 07.
– elm-dev
Yeah I am curious about such a 'calendar' example as well.  I end up making a lot of widgets that hold internal state, need to handle their own messages, etc... etc... and I keep writing them the elm-mdl way, which although is nicer still does not seem 'perfect'.

Here might be a simple example that I actually have here:
 - Button
 - Ripple
   - Ripples can be applied 'to' nodes, what they do is add a custom click listener (we really need a way to register multiple listeners).
   - Ripples have various parameters that only the view needs, like coloring.
   - When the thing is clicked it gets the location of the click on the element and spawns a new child div
   - The child div has a style of transformation to do the rippling out.
   - When the click is released then it applies another transformation that adds to the previous that fades it to pure transparency (so the ripple still goes out while it is fading out)
   - When it changes it to fading out it also sends a message via Time delay for however-many-ms in the future
   - When that time message is received, then it removes the div
   - Every time a click is done it does another ripple, even if another is still visible

This means that there can be multiple Ripple's on things, they need to register an event on their parent, they have their own messages, conditional rendering, etc... that the main application just absolutely does-not-care-about, but is needed to follow the design.

An example of how it works, click the Wave button on this page repeatedly:  http://materializecss.com/waves.html

The one I made is very elm-mdl'ish in design (although made before elm-mdl so it is slightly different).  The code required to use it is just adding this to my app:
```elm
filters : Msg -> Model -> ( Msg, States Model Msg )
filters msg model =
    case msg of
        Helpers helpersMsg ->
            Helpers.delegate Helpers helpersMsg model
        _ ->
            ( msg, States.enableAll )
```

And then I use it by just adding this to something in my view:
```elm
        button
          ( Helpers.Ripple.events Helpers model "rippleid" DoClick
          ++ [ otherAttributes ]
          )
          [ Helpers.Ripple.view Helpers model "rippleid"
          , text "Button Text"
          ]
```

And that is it, I only see the parts that I am interested in, my application does not care about rippling messages, does not want to see them in update, does not care about event registrations.  The only real wart is that the events needs the 'DoClick' message since there is not a way to combine multiple events into a single click so I have to do it internally (the 'events' call will send the message `DoClick` when mouseup is released after mousedown on the button or on a click message since click is used for when the, say, space-bar is pressed on the button, the ripple will happen from the center of the button).

As stated though, this does not feel 'right'.  Although it does let me ignore ripples as they are entirely a view only necessity, even though they have their own messages, individual state, etc... It just feels so wrong...  However, holding state for hundreds of little ripples around in my model and handling them in my views and polluting my update with them seems much much worse.

Richard Feldman

olvasatlan,
2016. szept. 7. 11:22:572016. 09. 07.
– elm...@googlegroups.com
Yeah I am curious about such a 'calendar' example as well.  I end up making a lot of widgets that hold internal state, need to handle their own messages, etc... etc... and I keep writing them the elm-mdl way, which although is nicer still does not seem 'perfect'.

I would write both of those using techniques like elm-autocomplete and elm-sortable-table. :)

Here might be a simple example that I actually have here:

I think if you have to write eight bullet points about the thing, evidence suggests that maybe it is not actually simple. ;)

Again, I would use the techniques of elm-autocomplete and elm-sortable-table.

(Well, no, actually I would just never use ripple because it's an unimportant visual flourish that demands introducing complexity far disproportionate to what it brings to the table over the gazillion other flourishes out there which can be implemented with CSS alone.)

OvermindDL1

olvasatlan,
2016. szept. 7. 11:30:332016. 09. 07.
– elm-dev
On Wednesday, September 7, 2016 at 9:22:57 AM UTC-6, Richard Feldman wrote:
(Well, no, actually I would just never use ripple because it's an unimportant visual flourish that demands introducing complexity far disproportionate to what it brings to the table over the gazillion other flourishes out there which can be implemented with CSS alone.)

(I agree, but the bosses want a Material themed site, it is not my choice. ;-) ).

And it is actually quite simple, in javascript it is just a couple of lines.  Elm makes it... huge.

OvermindDL1

olvasatlan,
2016. szept. 7. 11:38:082016. 09. 07.
– elm-dev
Blah sent too soon, Discourse would be useful indeed...


On Wednesday, September 7, 2016 at 9:22:57 AM UTC-6, Richard Feldman wrote:
I would write both of those using techniques like elm-autocomplete and elm-sortable-table. :)

Here might be a simple example that I actually have here:

I think if you have to write eight bullet points about the thing, evidence suggests that maybe it is not actually simple. ;)

Again, I would use the techniques of elm-autocomplete and elm-sortable-table.

Eh, but both of those have a distinct message and model for each instance, and I do not even want to know about those, in addition to the amount of them is changing all the time as the program works, the way they are used changes, etc...  I'd have to do something like make the handler message for it be keyed based on which one and dispatch out to a dictionary of them, which is not useful or interesting to handle in the business update function.  I want all code related to those ripples beyond just stating that one should be 'here' in the view to be no where near the business end of things that does actual work.  And this is just 1 of a hundred examples.  Imagine your update function being filled with more view stuff then there is business stuff (again, because of boss requirements) when it should just be ferried away 'elsewhere'.

Richard Feldman

olvasatlan,
2016. szept. 7. 11:39:022016. 09. 07.
– elm...@googlegroups.com
On Wednesday, September 7, 2016 at 9:22:57 AM UTC-6, Richard Feldman wrote:
(Well, no, actually I would just never use ripple because it's an unimportant visual flourish that demands introducing complexity far disproportionate to what it brings to the table over the gazillion other flourishes out there which can be implemented with CSS alone.)

(I agree, but the bosses want a Material themed site, it is not my choice. ;-) ).

Ripple is an opt-in addition to MDL, so you're in the clear for building a material themed site without it. ;)

And it is actually quite simple, in javascript it is just a couple of lines.  Elm makes it... huge.

And if your app is already built around WebGL, a visual flourish where the buttons tilt in 3D is "actually quite simple." ;)

Doesn't mean it's a good idea to haul all that complexity into your HTML app just for a flourish!

My point is that you're writing Elm code, not JavaScript code. Why would it be a good idea to evaluate whether to use something based on how well-suited it is to a technology other than the one you're using? :)

Richard Feldman

olvasatlan,
2016. szept. 7. 11:43:282016. 09. 07.
– elm...@googlegroups.com
Eh, but both of those have a distinct message and model for each instance, and I do not even want to know about those, in addition to the amount of them is changing all the time as the program works, the way they are used changes, etc...  I'd have to do something like make the handler message for it be keyed based on which one and dispatch out to a dictionary of them, which is not useful or interesting to handle in the business update function.  I want all code related to those ripples beyond just stating that one should be 'here' in the view to be no where near the business end of things that does actual work.

Well, yes, this is why I think ripple is a poor choice of flourish haha...it needs so much state management for so little gain!

OvermindDL1

olvasatlan,
2016. szept. 7. 12:04:032016. 09. 07.
– elm-dev
On Wednesday, September 7, 2016 at 9:39:02 AM UTC-6, Richard Feldman wrote:
On Wednesday, September 7, 2016 at 9:22:57 AM UTC-6, Richard Feldman wrote:
(Well, no, actually I would just never use ripple because it's an unimportant visual flourish that demands introducing complexity far disproportionate to what it brings to the table over the gazillion other flourishes out there which can be implemented with CSS alone.)

(I agree, but the bosses want a Material themed site, it is not my choice. ;-) ).

Ripple is an opt-in addition to MDL, so you're in the clear for building a material themed site without it. ;)

Tell them that, they love the little bits of animation as they say the site looks far more modern with it, so it is demanded.  :-)
 

On Wednesday, September 7, 2016 at 9:39:02 AM UTC-6, Richard Feldman wrote:
And it is actually quite simple, in javascript it is just a couple of lines.  Elm makes it... huge.

And if your app is already built around WebGL, a visual flourish where the buttons tilt in 3D is "actually quite simple." ;)

Not here, this is building a single replacement site for a lot of in-business sites that are highly disjoint.  I am testing the site with everything from Chrome, Firefox, Opera, and Edge to a dozen different phone browsers to down to IE9 (thank-goodness no IE8 at least) as everyone uses a variety of things here that each department refuse to change from for various reasons (usually things that only work in one specific browser, old OracleCrap in IE9 to a document site that only works in Chrome to etc... etc...).  Believe me, this is not really fun, so I try to simplify the amount of code I write, not compound it.  ;-)

Thankfully Elm is actually a decent language and the less javascript I have to write, the better.


On Wednesday, September 7, 2016 at 9:39:02 AM UTC-6, Richard Feldman wrote:
Doesn't mean it's a good idea to haul all that complexity into your HTML app just for a flourish!

I'd love another way to be able to do it, but it is part of my requirements.


On Wednesday, September 7, 2016 at 9:39:02 AM UTC-6, Richard Feldman wrote:
My point is that you're writing Elm code, not JavaScript code. Why would it be a good idea to evaluate whether to use something based on how well-suited it is to a technology other than the one you're using? :)

I hate untyped languages with an undying passion, and they don't care what language I use.  This is just one of the few warts in Elm design currently, the rest of it is wonderful.

 
On Wednesday, September 7, 2016 at 9:43:28 AM UTC-6, Richard Feldman wrote:
Eh, but both of those have a distinct message and model for each instance, and I do not even want to know about those, in addition to the amount of them is changing all the time as the program works, the way they are used changes, etc...  I'd have to do something like make the handler message for it be keyed based on which one and dispatch out to a dictionary of them, which is not useful or interesting to handle in the business update function.  I want all code related to those ripples beyond just stating that one should be 'here' in the view to be no where near the business end of things that does actual work.

Well, yes, this is why I think ripple is a poor choice of flourish haha...it needs so much state management for so little gain!

Entirely agree!  But again, not my choice, I have 4 bosses above me that demand otherwise and I'm not paid enough to be important enough to argue.  ;-) 

Sean Clark Hess

olvasatlan,
2016. szept. 7. 12:20:162016. 09. 07.
– elm...@googlegroups.com
On Wed, Sep 7, 2016 at 6:30 PM OvermindDL1 <overm...@gmail.com> wrote:

And it is actually quite simple, in javascript it is just a couple of lines.  Elm makes it... huge.
 
And this is why it is hard (for me, anyway) to let go of the idea of components, and embrace composition, because components let us think that we are getting a lot for very little, when in fact we get something very inflexible. 

As a thought experiment, there is one ideal "component" for every application that would make writing it completely trivial. It's called "MyApp" and contains the entire functionality of the application. But obviously it only works with one application. 

So I am arguing that there is a tradeoff between "just a couple of lines" and being unable to use it in a wide variety of situations. Compare to something like List.filter, which can be used in so many different situations, but of course you have to compose it with other things. 

Imagine a calendar module which exposes many functions which do a single, focused thing related to building a calendar. Perhaps some of them are default styles, others layout, others calculations. Anyone could use parts of this to make a calendar that suits their requirements. 

This is why good "components" are so hard to come by: because even when they are designed very well, they will not be able to handle all the use cases people want. If, instead, authors create functions, these can be used in more situations. 

Less code != better. DRY is far inferior to KISS. 

Richard Feldman

olvasatlan,
2016. szept. 7. 13:14:432016. 09. 07.
– elm-dev
I hate untyped languages with an undying passion, and they don't care what language I use.  This is just one of the few warts in Elm design currently, the rest of it is wonderful.

I agree with Sean on this...architectural simplicity is not a wart! It's a design decision I very much appreciate.

I'm sorry to hear that your bosses are making it difficult to make good engineering choices. I've been there, and it sucks. :(
Az üzenetet töröltük.

Sean Clark Hess

olvasatlan,
2016. szept. 7. 15:16:322016. 09. 07.
– elm-dev
I'm not aware of components being solved well in any language. Can you point me to an example of where you feel it is done well? It just seems like a hard problem to me.

I've only seen it done the way I described before, where complex functionality is put into a nice package, but the author has to explicitly support every use case. So of course it never does exactly what I want

So I feel like the way forward is to provide composable view functions that do require some boilerplate (regular composition) but which don't suffer from trying to pretend that disparate things (styling, update logic, etc) and actually one thing.

Hmm this makes me want to build a calendar module to see how simple I could get it. That seems like a difficult use case.


On Wed, Sep 7, 2016 at 8:50 PM OvermindDL1 <overm...@gmail.com> wrote:
On Wednesday, September 7, 2016 at 11:14:43 AM UTC-6, Richard Feldman wrote:
I hate untyped languages with an undying passion, and they don't care what language I use.  This is just one of the few warts in Elm design currently, the rest of it is wonderful.

I agree with Sean on this...architectural simplicity is not a wart! It's a design decision I very much appreciate.

Simplicity sure, but being a functional language it should be easy to compose functions to reduce such boilerplate, and indeed it is 'mostly' possible (see my version in prior email in this thread, try beating that), but the current espoused style seems against making this compartmentalized, which coming from a lot of languages, most functional, over a period of 3 decades, is still rather jarring to me as I've never seen it stated anyway to take the longer more wordy path when something like my prior style is readable and separates concerns well (don't mix view handling with business logic).
 

On Wednesday, September 7, 2016 at 11:14:43 AM UTC-6, Richard Feldman wrote:
I'm sorry to hear that your bosses are making it difficult to make good engineering choices. I've been there, and it sucks. :(

Oh if you want to see bad you should see how bad Xerox was, almost a decade with them, that was horrible...  >.<
My current job is utter bliss in comparison.  ^.^

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/aa9fdbc5-4bb0-4de2-bb33-50980776871f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Az üzenetet töröltük.

Richard Feldman

olvasatlan,
2016. szept. 7. 16:42:562016. 09. 07.
– elm-dev
I think this question is a magnet for answers that lead to local maxima.

If the focus is "how do we make an isolated widget as easy to drop in as possible," optimizing for that seems to have non-obvious drawbacks at scale.

For example, at work we were able to solve a database load problem because we can trivially serialize our whole UI state and replay it. Implementing the whole persistence layer as append-only serialized UI actions was (and I do not use this word lightly) trivial, and it meant we could have zero database contention—a problem for us, historically—on a hot path. This wasn't hard for us, but it would have been impossible if we had and used the local state features that make an individual calendar widget easier to drop in with, say, React.

Forget local state though. Let's look at other tactics used in pursuit of the "easy to drop in" goal. Evan has said "it's not a good idea to put functions in Msg" and one good reason for that is that functions can't be serialized or introspected for debugging purposes. In 0.18's debugger you can step through all your messages and see what values they hold, to isolate "bug X happened right after messages Y and Z went through the update function"...unless you're using elm-parts, in which case I'm assuming instead of "message Y" and "message Z" you'll see something unhelpful like "<function of unknown contents>" for every single message.

I think this because elm-parts wraps all messages in a function, meaning there's no way to toString them and get any useful debugging information out. It could be there's a potential design miracle I'm missing, but I don't see how it would be possible to get useful debugging info out of an unevaluated function. I glean from the elm-parts docs that this was explicitly done in pursuit of "reducing boilerplate."

Personally I am beyond excited to use the 0.18 dev tools and have no interest in sacrificing that debugging feature (or others) in pursuit of the local maximum of "less boilerplate." I think there's a long track record in the Web development space of developing beautiful trees that look lovely in isolation and then come together to form a nasty forest. Elm is the first Web development environment I've worked in where the entire forest felt nice in aggregate, even at scale, and I am default wary of attempts to import the surface-nice things that make other ecosystems' trees pretty and forests thorny.

My "two" cents. ;)

Mark Hamburg

olvasatlan,
2016. szept. 7. 18:18:052016. 09. 07.
– elm...@googlegroups.com
On Sep 7, 2016, at 9:38 AM, Richard Feldman <richard....@gmail.com> wrote:
>
> My point is that you're writing Elm code, not JavaScript code. Why would it be a good idea to evaluate whether to use something based on how well-suited it is to a technology other than the one you're using? :)

What you are arguing here is that Elm is less useful as a general purpose programming language than JavaScript. When the programmer who chose Elm says "that's hard" and the JavaScript programmer says "no problem", what do you think the management reaction is going to be to Elm and people who choose Elm? Something along the lines of an ineffective technology chosen by dilettantes? Is that really the case you want to be building? You may not like ripples but if the designers like them they are going to come up and the developers are going to be expected to deliver or find new jobs after their JavaScript-based counterparts deliver.

Mark

Mark Hamburg

olvasatlan,
2016. szept. 7. 18:24:582016. 09. 07.
– elm...@googlegroups.com
And please don't read my message as a specific complaint about lack of components but rather a criticism of dismissing concerns with "don't design your UX that way".

Mark

Mark Hamburg

olvasatlan,
2016. szept. 7. 18:28:142016. 09. 07.
– elm...@googlegroups.com
I liked the new guide sections but they raise the question of whether the new guide to reuse is a disavowal of the nested TEA architecture from 0.16. If so, then it might be good to say so and if not then there should probably be a discussion of how they relate.

Mark
--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+u...@googlegroups.com.

OvermindDL1

olvasatlan,
2016. szept. 7. 18:34:392016. 09. 07.
– elm-dev
This is by far the big wart of elm-parts with this style yes.  That is why I'd mentioned before a more 'erlang' style where there are multiple update calls for various modules.  This could be wrapped around by a parent model/update loop and was something I'd been playing with recently in testing.  Essentially you could have multiple top-level modules in an application, each have their own update/subscription paths, and there would be one central view call.  Any module could return their own message types from the view for handling out of Html events and so on and they would be handled in their own areas based on the Message type.  This would be fairly simple to set up with a more powerful type system or could be done now by decorating each message with their primary 'module' message.  But with this there would be no functions in messages, no functions in the model, things only handle what they care about.

It can be done now and I am doing it as so in many areas but it requires significantly more boilerplate, however it does make it a lot easier to reason about things and makes it explicit where what goes where and seems very to the TEA, just a model level higher, and keeps it still easy to follow the message flow, able to time-warp, etc...

Richard Feldman

olvasatlan,
2016. szept. 7. 18:44:522016. 09. 07.
– elm-dev
On Sep 7, 2016, at 9:38 AM, Richard Feldman wrote: 

> My point is that you're writing Elm code, not JavaScript code. Why would it be a good idea to evaluate whether to use something based on how well-suited it is to a technology other than the one you're using? :) 

What you are arguing here is that Elm is less useful as a general purpose programming language than JavaScript. When the programmer who chose Elm says "that's hard" and the JavaScript programmer says "no problem", what do you think the management reaction is going to be to Elm and people who choose Elm?

That's not supported by either what you quoted or the rest of what I wrote.

Here are two true statements:
  • JavaScript's pervasive mutable state makes it so you can write less code to obtain a ripple effect.
  • Elm's centralized state management makes it so you can write less code to implement an undo feature.
Neither of these provides any basis for a claim like either of these languages is "less useful as a general purpose programming language" than the other. They have different designs, which implies tradeoffs. Balancing tradeoffs like these is a huge part of programming.

I think the tradeoffs Elm makes in comparison to JavaScript make Elm a better choice overall for building Web applications. Feel free to disagree. :)

And please don't read my message as a specific complaint about lack of components but rather a criticism of dismissing concerns with "don't design your UX that way". 
 
If you believe that "don't design your UX that way" is not a thing that responsible programmers should ever say to someone proposing a given UX, then please make that claim explicitly and I will respond to it.

I liked the new guide sections but they raise the question of whether the new guide to reuse is a disavowal of the nested TEA architecture from 0.16.

I don't know what 0.16 thing you are referring to here. Can you link to something that explains what it is?

Charles-Edouard Cady

olvasatlan,
2016. szept. 8. 0:11:172016. 09. 08.
– elm-dev
I'm not sure dismissing the problem by saying "I certainly wouldn't do that" is fair. Even if you don't like ripples I find it hard to argue about the necessity of private state for something like a calendar. I starting to think one design pattern will not fit all use cases and some applications might end up using several.
The msg wrapper impact on debugging is a very valid point: I hadn't thought of that. The pattern does allow for serializing the whole app state though...

Charles-Edouard Cady

olvasatlan,
2016. szept. 8. 0:36:562016. 09. 08.
– elm-dev
I really love the pattern in sortable table! It does remove the need for a specific update. It slightly complicates the component's view function but I can live with that.

Mario Sangiorgio

olvasatlan,
2016. szept. 8. 2:44:062016. 09. 08.
– elm...@googlegroups.com
Even if you don't like ripples I find it hard to argue about the necessity of private state for something like a calendar.

Does that state really need to be private? The think I like the most in Elm is that everything is explicit and I can have a clear idea of what's happening just by looking at state and messages.

Can you show me a code example of how you would implement a calendar in Elm and how having some sort of private state would improve it?

Charles-Edouard Cady

olvasatlan,
2016. szept. 8. 3:59:292016. 09. 08.
– elm-dev
Sure, no problem! I can't post all the code here, but this is the gist of it.

The calendar (aka DatePicker) is itself part of another widget (called OperatingPointConf), which is part of another widget (called RouteProfile) which in turn is part of the main application.

The calendar's internal state is:

type alias Model =
 
{ browseDate : Date
 
, firstDayOfWeek : Date.Day
 
, showPicker : Bool
 
, hovered : Bool
 
}

You'll notice that DatePicker's internal state doesn't even hold the selected date because it's not an internal state. The rest of the application needs to know about it otherwise there wouldn't be much point in having a calendar widget in the first place. It is passed as a parameter to the view function, though, as you will later see.

That internal state Model is wrapped in OperatingPointConf's internal model:

type alias Model =
 
{ clock : Clock.Model
 
, datePicker : DatePicker.Model
 
}



OperatingPointConf has an init function for its initial internal model:

init : Date -> Model
init date
=
 
{ clock = Clock.init
 
, datePicker = DatePicker.init date
 
, showSpeedSlider = False
 
}



The calendar has internal msg, namely

type Msg =
   
Unhover
 
| PreviousMonth
 
| NextMonth
 
| ShowPicker
 
| HidePicker
 
| Hover



which are then wrapped the containing widget (OperatingPointConf):

type
Msg =
   
DatePickerMsg DatePicker.Msg
 
| ClockMsg Clock.Msg



OperatingPointConf's internal update is simply:

update
: Msg -> Model -> Model
update msg model
=
 
case msg of
   
DatePickerMsg msg' ->
      { model | datePicker = DatePicker.update msg'
model.datePicker }
   
ClockMsg msg' ->
      { model | clock = Clock.update msg'
model.clock }



Of course, we could apply elm-sortable-table's pattern & get rid of the update altogether but as you're not getting rid of the internal state, there's not much point: basically you'd just be littering view with update's content (even if you do spread it out in helper functions) because the operations that update perform need to be there one way or the other. This pattern keeps the semantics clear:

- update only updates a component's internal state that no one else cares about
- view can trigger msg from parent components that the child component doesn't care about
- if you need to modify both the internal & the shared state, you can start with the internal state & then you launch a Cmd. You need

run : msg -> Cmd msg
run m
=
 
Task.perform (always m) (always m) (Task.succeed ())



and then the update is

update : ParentMsg a msg -> Msg -> Trip.Model -> Model -> (Model, Cmd msg)
update parentMsg msg shared model
=
 
...



where ParentMsg is just a record containing the parent's msg (it avoids having ten parameters in the view function & makes the code more readable & maintainable).

For example, one line in that update (nothing to do with the calendar anymore) reads:

FilterName key ->
 
({ model | filterKey = key }, run <| parentMsg.filterTrips shared.trips key)


Returning to the calendar widget (DatePicker'), its view function starts with:

view : Date -> Model -> (Date -> msg) -> (Msg -> msg) -> Html msg
view currentDate model setDate msgWrapper
=
 
...



msgWrapper is just there to marshall the internal messages through the parent component. setDate is what you want to do when a date is selected.

And the update is:

update
: Msg -> Model -> Model
update action model
=
 
case action of
   
PreviousMonth ->
     
{ model | browseDate = getPreviousMonth model.browseDate}
   
NextMonth ->
     
{ model | browseDate = getNextMonth model.browseDate}
   
ShowPicker ->
     
{ model | showPicker = True, browseDate = (Maybe.withDefault model.browseDate model.selectedDate) }
   
HidePicker ->
     
{ model | showPicker = False, hovered = False }
   
Hover ->
     
{model | hovered = True}
   
Unhover ->
     
{model |hovered = False}



The reason I don't want DatePicker's internals to surface up the component chain like a mafioso's innards on the Hudson river is that I don't want the calendar widget's user to have to provide & initialize that state: it would break encapsulation & render the widget much harder to use. If I decide to add another internal state to that calendar, the caller doesn't even need to know or care.

Richard Feldman

olvasatlan,
2016. szept. 8. 5:23:082016. 09. 08.
– elm-dev
I'm not sure dismissing the problem by saying "I certainly wouldn't do that" is fair. Even if you don't like ripples I find it hard to argue about the necessity of private state for something like a calendar.

I am 100% on board with the last sentence. :)

In the case of a calendar, separating its internal state makes great sense to me! The wiring seems totally worthwhile in that case.

The wiring does not seem worthwhile for a ripple flourish. If a designer said "I came up with this sweet design where our buttons tilt in 3D and follow your cursor," what kind of engineer would I be if I did not push back? Unless our application already happens to be written in WebGL, we're talking about a serious amount of extra engineering work for something that does not sound like it will give our end users a significantly superior experience to, say, a hover effect. It would be irresponsible for me as an engineer not to push back.

"I can build this as-is, but you may not be aware that this design has more engineering cost than lots of similar choices would. How about if we discuss alternatives?"

The above is something I've said over and over in my career—in JavaScript, in Java, in Scala, in Perl, in Ruby, in Groovy...and now in Elm. Balancing tradeoffs is a crucial part of effective software engineering. If we are banned from giving the feedback that "this nonessential flourish will be far more expensive to implement than any number of readily-available alternative flourishes" then we are effectively banned from doing a good job as engineers.

I get that sometimes managers or designers in positions of power are unwilling to discuss engineering tradeoffs. "Just do it this way; that's how it's written down, so go do it." That sucks, but changing Elm's design or recommended best practices is not the solution to the problem of self-destructively inflexible managers. That is a separate problem with separate solutions. :)

I starting to think one design pattern will not fit all use cases and some applications might end up using several.

Absolutely! I think the new Guide section on reuse has some good examples of how to handle certain cases, but it's not comprehensive.

Totally agree that there is no one-size-fits-all answer here. It's worth picking the right approach on a case-by-case basis. :)

Charles-Edouard Cady

olvasatlan,
2016. szept. 8. 5:49:002016. 09. 08.
– elm-dev
To put it bluntly, I think there's no point in implementing ripples in an Elm application: one of the advantages of having a language that compiles to Javascript in interoperability. I think it's generally a waste of time to reimplement an existing Javascript library of a certain size (eg. leaflet): just use ports; Same thing for ripples: use bootstrap & be done with it.
The whole point of Elm, I think, is to easily & reliably create web applications. To me, that's compatible with using external black-box code (possibly elm code) & concentrating on the business value of your application. That's where Elm will shine: you won't forget cases, your function parameters are what you think they are & you have very little syntactic noise which leads to more maintainable code.
That said, I totally get that some people want to make a pure elm version of Bootstrap, but that's a project in its own right (& it will always be chasing Bootstrap). For my needs, I'll just use what's available & implement the rest & be done with it.

I'm very happy with Elm so far (except for a few design choices I find questionable such as the removal of extensible records, not being able to traverse the DOM & triggering several msg) & I'm delighted that questions regarding code reuse are starting to get an "official" (i.e. from Evan) response. However, I consider that response incomplete because it only shows examples with no internal state. You need the following in the official Elm guide:
- Examples with one shared state for all components: done
- Examples with separate state for each component: done
- Examples with some shared state & some private state: todo
- Examples where a user action only has a global impact: done
- Examples where a user action only has a local impact: done
- Examples where a user action has both global & local impacts: todo

Peter Damoc

olvasatlan,
2016. szept. 8. 6:08:052016. 09. 08.
– elm...@googlegroups.com
On Thu, Sep 8, 2016 at 12:23 PM, Richard Feldman <richard....@gmail.com> wrote:
The wiring does not seem worthwhile for a ripple flourish.

Of course that in a lot of cases there are better alternatives, especially if the ripple is just a kind of flourish. 
But what if the aim is to mimic as close as possible a native interface. 
In those cases the ripple is not flourish but part of the specs. It is a non-negotiable element. It is unavoidable.  

Also, I feel the need to repeat what I've said in a previous answer. The ripple effect is a CLEAR example of small unavoidable statefulness. 

Instead of addressing the issue of "many small components that are unavoidably stateful" you have proceeded in creating a straw-man that you could easier dismantle.  
I am aware that the ripple effect might be esthetically inappropriate, that it might lead to layout thrashing of gargantuan proportions but all these are beside the point when the topic is "many small components that are unavoidably stateful". 

The question that brought the ripple example is how do we handle "many small components that are unavoidably stateful"? 





--
There is NO FATE, we are the creators.
blog: http://damoc.ro/

Peter Damoc

olvasatlan,
2016. szept. 8. 6:08:482016. 09. 08.
– elm...@googlegroups.com
On Thu, Sep 8, 2016 at 12:48 PM, Charles-Edouard Cady <charlesed...@gmail.com> wrote:
I think it's generally a waste of time to reimplement an existing Javascript library of a certain size (eg. leaflet): just use ports; Same thing for ripples: use bootstrap & be done with it.

There are two ways of using Elm:
- First is to have a nice Elm only app where all the html is generated in Elm (maybe with a very small index.html that mounts some CSS) 
- Second: embed Elm into a more traditional app. This is more in line with the article that Evan din on How to Use Elm at Work. 


If you want to someday do all of your app in Elm, the reimplementation of a certain set of functionality is required. Embedding Elm in JS might be a pleasant experience BUT embedding a JS component (e.g. a carousel) in Elm, is not so nice. 

Richard Feldman

olvasatlan,
2016. szept. 8. 6:41:372016. 09. 08.
– elm-dev
But what if the aim is to mimic as close as possible a native interface. 

If you need it to be 100% identical to native code, then you need to write native code.

If you want it to be "native-like" but written in a different technology for productivity reasons, then all the usual tradeoffs apply. This scenario is no different from the rest of the discussion above.

The wiring does not seem worthwhile for a ripple flourish.

Of course that in a lot of cases there are better alternatives, especially if the ripple is just a kind of flourish. 
But what if the aim is to mimic as close as possible a native interface. 
In those cases the ripple is not flourish but part of the specs. It is a non-negotiable element. It is unavoidable.  

Also, I feel the need to repeat what I've said in a previous answer. The ripple effect is a CLEAR example of small unavoidable statefulness. 

Instead of addressing the issue of "many small components that are unavoidably stateful" you have proceeded in creating a straw-man that you could easier dismantle.

Let me reorganize your points:
  1. "Of course in the case of a ripple there are better alternatives"
  2. "The ripple effect is a CLEAR example of unavoidable statefulness"
  3. "Instead of addressing this issue, you are creating a strawman"
So if I have this right, this is a thing that is simultaneously avoidable (according your first point) and unavoidable (according your second point), and by addressing this specific, real-world example of the non-obvious consequences of ripple effects in MDL and elm-parts, I am "attacking a strawman?"

And to be further clear, you are demanding that I instead stop discussing this specific case and instead address the broad hypothetical scenario you have invented ("what if you have a ton of small unavoidably stateful things") for which you can't provide a single real-world motivating use-case?

Peter, you have been around for awhile, so you know very well that the Elm community's design process is to focus on specific motivating use cases. You know I am going to say "If you have a specific application you want to build that needs lots of small independent pieces of state, tell me what it is so we can discuss specifics."

At this point the fact that you are repeatedly steering conversations away from specifics and toward broad hypotheticals is disrespectful of everyone's time.

You know better. Cut it out.

Peter Damoc

olvasatlan,
2016. szept. 8. 8:40:472016. 09. 08.
– elm...@googlegroups.com
On Thu, Sep 8, 2016 at 1:41 PM, Richard Feldman <richard....@gmail.com> wrote:
Let me reorganize your points:
  1. "Of course in the case of a ripple there are better alternatives"
  2. "The ripple effect is a CLEAR example of unavoidable statefulness"
  3. "Instead of addressing this issue, you are creating a strawman"
So if I have this right, this is a thing that is simultaneously avoidable (according your first point) and unavoidable (according your second point), and by addressing this specific, real-world example of the non-obvious consequences of ripple effects in MDL and elm-parts, I am "attacking a strawman?"

Yes, you are not addressing the real-world example of an unavoidable state, you are creating a strawman around the validity of the ripple example by pointing aesthetic considerations and implementation details of the current elm-mdl. 
It's like the old joke: 
- Doctor, it hurts when I do like this.
- Well, then don't do like that. 
The non-obvious consequences of a ripple effect implementation done by elm-mdl is not the topic. That is actually part of the motivation to have another solution to the issue of these unavoidable small states. 
I'm aware of the tradeoffs of elm-parts and Evan's position regarding functions in messages. This is part of why I kept pushing this topic. 
I want a blessed version that is at least as pleasant to use.


And to be further clear, you are demanding that I instead stop discussing this specific case and instead address the broad hypothetical scenario you have invented ("what if you have a ton of small unavoidably stateful things") for which you can't provide a single real-world motivating use-case?

What about the dropdowns or the floating label textfields? carousels? collapsible? tooltips? Aren't they real-world enough to motivate approaching this use-case?
I have created a repository where I implemented a simple, real-world example of a form and you have seen it and still tell me that "you can't provide a single real-world motivating use-case" ? 
Also, I'm not demanding anything here, I'm just pointing out what I see. It's just another perspective on things. From where I'm looking, the issue of handling small unavoidable state is not addressed. 
 
Peter, you have been around for awhile, so you know very well that the Elm community's design process is to focus on specific motivating use cases. You know I am going to say "If you have a specific application you want to build that needs lots of small independent pieces of state, tell me what it is so we can discuss specifics."

I am aware of the Elm community's design process. I have tried to do the best I could to present a motivating use-case. 
https://github.com/pdamoc/elm-boilerplate-example
Is this example not specific enough? What should I change in it to make it even more specific? 
 
At this point the fact that you are repeatedly steering conversations away from specifics and toward broad hypotheticals is disrespectful of everyone's time.

There was a time when the discussions around this topic revolved around a personal intuition so might have been broad hypotheticals. 
And then I took a leap of faith and tried to use Elm for a real-world project.
It stopped being hypothetical and it became about me trying to manage the complexity of my codebase. 
Now, I have spent the last few days procrastinating on writing a post-mortem for that project. 
Granted, the project failure has more to do with me not having enough JS/CSS experience but, at least some of the problem rests with scaling Elm code. 
The first 5000 lines of code were quite pleasant, the last 3000... not so much.
I started needing more complex widgets and spent inordinate amounts of time trying get something implemented in JS to work with the rest of my views. 

You know better. Cut it out.

I have said what I had to say. I'll stop here. 
I am sorry if my interventions lead to time being wasted for everyone. 
My intention was to contribute. 

Richard Feldman

olvasatlan,
2016. szept. 8. 9:04:272016. 09. 08.
– elm-dev
Yes, you are not addressing the real-world example of an unavoidable state, you are creating a strawman around the validity of the ripple example by pointing aesthetic considerations and implementation details of the current elm-mdl. 
It's like the old joke: 
- Doctor, it hurts when I do like this.
- Well, then don't do like that. 
The non-obvious consequences of a ripple effect implementation done by elm-mdl is not the topic.

Yes it is.


In response, I've stated my position that I would use private state with calendar and would question whether ripple is worth the implementation cost.

This is how productive discussions go: talking in terms of specific use cases.

 
I have created a repository where I implemented a simple, real-world example of a form and you have seen it and still tell me that "you can't provide a single real-world motivating use-case" ? 
I am aware of the Elm community's design process. I have tried to do the best I could to present a motivating use-case. 
https://github.com/pdamoc/elm-boilerplate-example
Is this example not specific enough? What should I change in it to make it even more specific? 

That example is extremely specific to elm-mdl's API. I have implemented plenty of forms in Elm without elm-mdl, and they do not look like that.
Granted, the project failure has more to do with me not having enough JS/CSS experience but, at least some of the problem rests with scaling Elm code. 
The first 5000 lines of code were quite pleasant, the last 3000... not so much. 
This seems worth its own thread! Lots to discuss there, I'm sure. :) 

What about the dropdowns or the floating label textfields? carousels? collapsible? tooltips? Aren't they real-world enough to motivate approaching this use-case?

Now we're getting somewhere! Can you do what OvermindDL1 did with ripple and make a separate post on elm-discuss for each of these like:
  • Here is what this thing is for
  • Here is the best API I can come up with to present it
  • Here is what I don't like about that API
This way people can discuss the specifics of each particular API.

Mark Hamburg

olvasatlan,
2016. szept. 8. 13:10:012016. 09. 08.
– elm...@googlegroups.com
On Sep 8, 2016, at 7:04 AM, Richard Feldman <richard....@gmail.com> wrote:

Yes, you are not addressing the real-world example of an unavoidable state, you are creating a strawman around the validity of the ripple example by pointing aesthetic considerations and implementation details of the current elm-mdl. 
It's like the old joke: 
- Doctor, it hurts when I do like this.
- Well, then don't do like that. 
The non-obvious consequences of a ripple effect implementation done by elm-mdl is not the topic.

Yes it is.


In response, I've stated my position that I would use private state with calendar and would question whether ripple is worth the implementation cost.

This is how productive discussions go: talking in terms of specific use cases.

My impression of the discussion has been:

"New guide on reuse is great, but how should we deal with components with internal state?"

"Such as?"

"Ripples."

"Ripples are needless UX flourishes. Don't use them."

This last response might be a legitimate side note leading to a discussion of UX design choices, but it is a dodge to the root question of "What pattern should we apply to handle internal state?" and even to the more specific question "How should I implement ripples in an Elm app?" To read it as an on point response, one would probably have to take it as "There isn't a good way to do that sort of thing in Elm. I don't think you should do it but if you have to then you probably shouldn't use Elm." Is that really the intended message and if so how many other contra-indicators are the for using Elm?

The WebGL argument is a straw man because it shifts the question from "We chose to implement our page using this particular programming language rather than JavaScript and we have complexity around implementing this increasingly common HTML UI element" (an argument where what had been a purely engineering choice to use Elm is what is causing the "problem" from the standpoint of designers and management) to "That sort of effect is really only works well by using WebGL. Do we want to pay the cost of embracing WebGL?" (an argument that applies regardless of the choice to use Elm or JavaScript). Arguing about WebGL is a different sort of argument from arguing about the use of ripples in the UX design.

Or if you want a different specific API design question: What is the stance on elm-mdl? Good pattern to follow or bad and if bad how should it have been implemented?

Mark

Mark Hamburg

olvasatlan,
2016. szept. 8. 13:31:102016. 09. 08.
– elm...@googlegroups.com
With regard to the new guide material on reuse and the old material on nested TEA from Elm 0.16, this does point to issues with using counters as the example since counters can be cleanly mapped to a view function that takes an integer and a message to set the counter value and in the removal case a message to remove the counter. (There are two ways to handle these message. One is as parameters. The other is as messages returned by the view that can then be mapped to appropriate messages for the parent. There are probably pros and cons to each.)

Counters are too simple to justify use as nested models — in particular, they have no internal state — and by using them as examples they lead people to get the wrong read on granularity decisions. On the other hand, by being so simple, the tutorial can focus on the wiring patterns that are the real subject rather than on the mechanics of implementing the thing being wired.

So, what is a reasonable example for which the implementation is still simple but the wiring choices are informative?

I've been contemplating the example of a counter with a stack of values so that it has buttons for increment, decrement, push, and pop. Is this actually useful? Actually likely to come up in a real world case? Probably not. But then neither was the list of counters.

The state we need to maintain somewhere is an integer and a list of integers. Operations triggered from the UI can change one or both of these. We could combine these into a pair or record, but then other code that wanted to use or adjust the counter value would need to look inside the pair or record. (We could also just use a list of integers and use the head value as the current counter value, but that introduces the case where the list is empty and still leaves other code working with the packaging.) We could store them separately but now an update to both in response to a pop operation is harder to convey as a simple message to the parent.

The example is contrived but it asks much the same question as something like the date picker widget without bringing in all of the details of building a date picker.

Functional programming takes a lot of inspiration from mathematics. It could arguably be said to be about making programs behave more like mathematics. Mathematicians (and physicists) try to distill real world problems down to cases that while no longer directly relevant to the real world, provide core insights into real world problems.

So, what is our core study case for internal state and what does it tell us about how to structure Elm programs when they have to deal with internal state?

Mark

Charles-Edouard Cady

olvasatlan,
2016. szept. 8. 16:00:182016. 09. 08.
– elm-dev
Wholeheartedly agree. This scaling/reuse/composition problem pops up regularly in elm-discuss but is often dismissed as "why ever would you want to do that?" which has but the faintest smell of hypocrisy to it: the language should not impact the visual design of your app, no matter how bad your taste is and how good the language designer's may be.
I think asking "why" turns the matter into a philosophical discussion rather than a more prosaic "how" and "I don't know" or "you can't" are both valid answers, albeit not very satisfying.

Charlie Koster

olvasatlan,
2016. szept. 8. 16:05:072016. 09. 08.
– elm-dev
So, what is our core study case for internal state and what does it tell us about how to structure Elm programs when they have to deal with internal state?

I've been on the sideline for this entire conversation, and I'll stay there for the moment. But if you're looking for a common example of a UI "thing" (what is traditionally called a component in non-Elm languages) then I suggest an accordion.

An accordion is extremely common and it has a simple internal state (which sections are collapsed and which sections are expanded?).

Maybe if we agree on a pattern for this simple yet common UI thing with internal state we can start exploring how it scales to more complex UI things with more complicated internal state. 

José Lorenzo Rodríguez

olvasatlan,
2016. szept. 8. 16:34:252016. 09. 08.
– elm-dev
Sorry if this has been brought up before, but why is it assumed that the state needs to be "internal"? What's wrong with the parent owning the state of the widget and passing it as an argument to the view functions?

Sean Clark Hess

olvasatlan,
2016. szept. 8. 16:59:362016. 09. 08.
– elm-dev
@Jose, "internal" state would still be passed in. It's more a question of whether it is opaque or not. In the old elm architecture nesting the part has no idea what the shape of the state of the child is.

Compare that to something like the Counter, where using the new approach, it would make sense that the parent would know it uses an int as its state and pass it in as an Int rather than Counter.Model
--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+u...@googlegroups.com.

Sean Clark Hess

olvasatlan,
2016. szept. 8. 17:06:002016. 09. 08.
– elm...@googlegroups.com
An accordion is a good idea but I'm pretty sure it can be implemented as a view function (or a set of them) without nesting.

I think a date picker would be a much more difficult use case. The month that the user is looking at has little value in the parent model, except to initialize it with the current date. Also whether it is popped up or not.

One thing I have been thinking about: look at the plain old <select> tag. Notice how much state is inherent in it? It pops open, it changes its display to match the current value. Sometimes I cheat and add JavaScript (bootstrap.js) if the JavaScript is only supporting something that could have been a native html tag. Then I can drive it from elm and pretend it's entirely data-driven, like select

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+u...@googlegroups.com.

Mark Hamburg

olvasatlan,
2016. szept. 8. 19:48:062016. 09. 08.
– elm...@googlegroups.com
Another way to put the concern that multiple people are voicing and the "don't use that widget" response only adds to is the question that almost every developer must confront: Will my choice of tools impair my ability to deliver what I want even when that deliverable is vaguely defined and likely to grow?

For example, JavaScript and Elm would both be bad choices for numerics intensive applications. That's easy to call out and developers are likely to know whether this will be an issue.

What's of concern here is that some of the responses on this thread suggest that Elm is ill-suited to some UX conventions. That raised the question: What's the shape of that boundary and will it matter to me? Saying you shouldn't use ripples in an Elm app raises the question of what else you shouldn't do and whether that will matter.

That uncertainty makes Elm a bigger adoption risk. I doubt that's the goal of anyone here, but it is a consequence of the responses.

Mark
Az üzenetet töröltük.

Mark Hamburg

olvasatlan,
2016. szept. 8. 20:35:562016. 09. 08.
– elm...@googlegroups.com
On Sep 8, 2016, at 3:48 AM, Charles-Edouard Cady <charlesed...@gmail.com> wrote:
>
> - Examples with some shared state & some private state: todo

No example here, but if the private state does not depend on the shared state — i.e., if we can update the shared state without having to update the private state, then the pattern could just look like:

view : SharedState -> PrivateState -> Html WidgetMsg

update: WidgetMsg -> SharedState -> PrivateState -> (SharedState, PrivateState, Cmd WidgetMsg)

The checkbox code in the guide is then the "optimization" that stems from recognizing that when there is no private state and the only thing we care about doing is setting the shared state, then we can simplify down to just a view function. (I would probably still present the simpler case first and just note that it's essentially a special case of the more general pattern.)

This gets more messy if the private state needs to be updated when the shared state changes though that's probably still just the matter of bottlenecking the code that does the update to the shared state.

Mark

Mark Hamburg

olvasatlan,
2016. szept. 8. 20:38:362016. 09. 08.
– elm...@googlegroups.com
If not clear from the above, both the shared state and the private state would be held in the model at the next level up.

Mark

Nick H

olvasatlan,
2016. szept. 8. 23:03:482016. 09. 08.
– elm...@googlegroups.com
(or a ripple.)

On Thu, Sep 8, 2016 at 1:18 PM, Nick H <falling...@gmail.com> wrote:
I think asking "why" turns the matter into a philosophical discussion rather than a more prosaic "how" and "I don't know" or "you can't" are both valid answers, albeit not very satisfying.

Richard answered the "how" at the same time that he asked "why": look at elm-sortable-table for an example of how to manage internal state.

Basically, encapsulate the state, throw it into your program's model, pass the state to the component's view function.

I think this approach should work as well for a calendar, a counter, or an accordion as it does for a sortable table.


On Thu, Sep 8, 2016 at 1:00 PM, Charles-Edouard Cady <charlesed...@gmail.com> wrote:
Wholeheartedly agree. This scaling/reuse/composition problem pops up regularly in elm-discuss but is often dismissed as "why ever would you want to do that?" which has but the faintest smell of hypocrisy to it: the language should not impact the visual design of your app, no matter how bad your taste is and how good the language designer's may be.
I think asking "why" turns the matter into a philosophical discussion rather than a more prosaic "how" and "I don't know" or "you can't" are both valid answers, albeit not very satisfying.
--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/22840747-a932-4356-9f29-4c37f8c2afe2%40googlegroups.com.

Charles-Edouard Cady

olvasatlan,
2016. szept. 9. 0:32:032016. 09. 09.
– elm-dev
All I'm saying is that the pattern in elm-sortable-table and its alternatives should be described in the guide along with an example where both internal and shared states are modified as a result of user action.
Maybe a simpler example than the calendar is a clock time picker? I made one using elm svg.

Nick H

olvasatlan,
2016. szept. 9. 0:34:522016. 09. 09.
– elm...@googlegroups.com
I think asking "why" turns the matter into a philosophical discussion rather than a more prosaic "how" and "I don't know" or "you can't" are both valid answers, albeit not very satisfying.

Richard answered the "how" at the same time that he asked "why": look at elm-sortable-table for an example of how to manage internal state.

Basically, encapsulate the state, throw it into your program's model, pass the state to the component's view function.

I think this approach should work as well for a calendar, a counter, or an accordion as it does for a sortable table.

On Thu, Sep 8, 2016 at 1:00 PM, Charles-Edouard Cady <charlesed...@gmail.com> wrote:
Wholeheartedly agree. This scaling/reuse/composition problem pops up regularly in elm-discuss but is often dismissed as "why ever would you want to do that?" which has but the faintest smell of hypocrisy to it: the language should not impact the visual design of your app, no matter how bad your taste is and how good the language designer's may be.
I think asking "why" turns the matter into a philosophical discussion rather than a more prosaic "how" and "I don't know" or "you can't" are both valid answers, albeit not very satisfying.
--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+unsubscribe@googlegroups.com.

Mark Hamburg

olvasatlan,
2016. szept. 9. 0:34:522016. 09. 09.
– elm...@googlegroups.com
I want to see Elm win v JavaScript because while it may be a bit more tedious (static types, etc) it produces more robust code without sacrificing expressiveness in any significant way. I fear the argument turning into "it may not be as fast or as capable as JavaScript but it's better long term" because that long term argument potentially gets undermined if a preference for having everything just work on the global state means that the code base is difficult to segment into comprehensible parts.(*) The examples showing that you need components less often than you think are great, but they need to be balanced with examples of how you handle "private" state (ripples) or shared state (global priority queue) or even just standard nesting of multiple independent instances of the same model needing its own internal logic. Just saying "don't do that" comes awfully close to saying "if you need to do that, don't use Elm" and that's not a great place to be for Elm adoption.

Mark

(*) For example, consider my past example case of wanting to run HTTP requests through a priority queue so that the most important requests get resolved first. We could build a function to do the request that takes the model (for access to the priority queue) and a URL and a decoder and returns a modified model and command, but now everything that makes such a request needs to be coded at a level where modifying the top level model is a reasonable thing to do and that could fast couple a lot of code to the top level of the model thereby inhibiting partitioning. Maybe extensible records could help, but there aren't standard Elm design patterns around using extensible records in this way.

On Sep 7, 2016, at 7:23 PM, Mark Hamburg <mhamb...@gmail.com> wrote:

On Sep 7, 2016, at 4:44 PM, Richard Feldman <richard....@gmail.com> wrote:

On Sep 7, 2016, at 9:38 AM, Richard Feldman wrote: 

> My point is that you're writing Elm code, not JavaScript code. Why would it be a good idea to evaluate whether to use something based on how well-suited it is to a technology other than the one you're using? :) 

What you are arguing here is that Elm is less useful as a general purpose programming language than JavaScript. When the programmer who chose Elm says "that's hard" and the JavaScript programmer says "no problem", what do you think the management reaction is going to be to Elm and people who choose Elm?

That's not supported by either what you quoted or the rest of what I wrote.

You made the point that one is writing Elm code not JavaScript code. So, that puts into play the question of what happens when the designers ask for an effect and the Elm programmers have more trouble than the JavaScript programmers delivering it.

Now, with respect to the specific effect in question in this thread — ripples — elm-mdl shows that Elm can deliver it but my impression from this thread is also that the approaches that elm-Mel takes aren't considered good form. When asked what good form would be, your answer was essentially "don't use ripples". That sounds like JavaScript can do ripples, people who use elm-mdl can do ripples, but people who use Elm the "right" way probably shouldn't try to do ripples. Someone looking in from the outside and just caring about ability to deliver on a design have evidence that the people doing Elm the "right" way may be making bad technical choices because they can't deliver. Is that really the desired impression to be making?


Here are two true statements:
  • JavaScript's pervasive mutable state makes it so you can write less code to obtain a ripple effect.
  • Elm's centralized state management makes it so you can write less code to implement an undo feature.
I suspect you could implement undo for the data model state — the thing that really matters for undo — using Flux and one of the immutability libraries for JavaScript.

Neither of these provides any basis for a claim like either of these languages is "less useful as a general purpose programming language" than the other. They have different designs, which implies tradeoffs. Balancing tradeoffs like these is a huge part of programming.

JavaScript can programmers can choose to use immutable data structures and centralized-state. Elm programmers have to. That's arguably a good thing but I know plenty of programmers and managers who would just say "don't write bad code." (See Steve Yegge on Static Typing's Paper Tigers.)

I think the tradeoffs Elm makes in comparison to JavaScript make Elm a better choice overall for building Web applications. Feel free to disagree. :)

But what you actually seem to be arguing is that Elm is a better choice for building web applications provided they don't do certain things in their UX designs. I would like it to be a better choice without that restriction.


And please don't read my message as a specific complaint about lack of components but rather a criticism of dismissing concerns with "don't design your UX that way". 
 
If you believe that "don't design your UX that way" is not a thing that responsible programmers should ever say to someone proposing a given UX, then please make that claim explicitly and I will respond to it.

I believe that programmers can argue about design but they need to argue in design terms when doing so. I hate it when engineers wield the "well, I'm writing the code so I win" cudgel. You argue that ripples are needless. Some might agree, but I don't see how that necessarily wins on the design front. Personally, I think Adobe Clean is hard to read and I will argue that to the full extent of my ability, but I expect to lose out to corporate consistency.

Sometimes engineers can argue about design from a technical standpoint. Apple's AppKit did not support z-order for much of its life which meant that perfectly natural mock ups in Photoshop would involve doing things like abusing the window system instead of the view manager. That's a legitimate basis for an argument between an engineering position and a design position. In the case of ripples, however, the web platform is clearly capable of supporting this so this is just a debate about Elm v the alternatives. (And in the z-order case, we had an engineer choose to do the work because he respected what the designer was trying to achieve though I think it would have been legitimate to argue that it simply wasn't feasible given how NeXT designed their view system.)


I liked the new guide sections but they raise the question of whether the new guide to reuse is a disavowal of the nested TEA architecture from 0.16.

I don't know what 0.16 thing you are referring to here. Can you link to something that explains what it is?

I don't have the Elm 0.16 documentation readily available anymore, but I remember plenty of examples of things like pairs of GIF fetchers and pairs or lists of counters where the outer model simply had routing messages to direct the messages for the inner model. We can see the evolution of this architecture in Html.App.map, but now there seems to be an aggressive push to say "just put everything in your top level model". I appreciate that the examples in the Elm 0.16 documentation were contrived, but examples often are because the focus needs to be on the techniques they are demonstrating. I also appreciate that Evan's new guide material shows that often you don't need components and that simply wrapping repeated patterns into functions is enough. But does this mean that the nesting approaches demonstrated for Elm 0.16 are now considered bad form?

Mark

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/88c34114-f8bd-44b1-a74e-9b337366e653%40googlegroups.com.

Mark Hamburg

olvasatlan,
2016. szept. 9. 0:35:472016. 09. 09.
– elm...@googlegroups.com

Nick H

olvasatlan,
2016. szept. 9. 0:37:182016. 09. 09.
– elm...@googlegroups.com
Hmm this makes me want to build a calendar module to see how simple I could get it. That seems like a difficult use case.

You should do it! Would be very interested to hear about your experience.

On Wed, Sep 7, 2016 at 12:16 PM, Sean Clark Hess <sean...@gmail.com> wrote:
I'm not aware of components being solved well in any language. Can you point me to an example of where you feel it is done well? It just seems like a hard problem to me.

I've only seen it done the way I described before, where complex functionality is put into a nice package, but the author has to explicitly support every use case. So of course it never does exactly what I want

So I feel like the way forward is to provide composable view functions that do require some boilerplate (regular composition) but which don't suffer from trying to pretend that disparate things (styling, update logic, etc) and actually one thing.

Hmm this makes me want to build a calendar module to see how simple I could get it. That seems like a difficult use case.


On Wed, Sep 7, 2016 at 8:50 PM OvermindDL1 <overm...@gmail.com> wrote:
On Wednesday, September 7, 2016 at 11:14:43 AM UTC-6, Richard Feldman wrote:
I hate untyped languages with an undying passion, and they don't care what language I use.  This is just one of the few warts in Elm design currently, the rest of it is wonderful.

I agree with Sean on this...architectural simplicity is not a wart! It's a design decision I very much appreciate.

Simplicity sure, but being a functional language it should be easy to compose functions to reduce such boilerplate, and indeed it is 'mostly' possible (see my version in prior email in this thread, try beating that), but the current espoused style seems against making this compartmentalized, which coming from a lot of languages, most functional, over a period of 3 decades, is still rather jarring to me as I've never seen it stated anyway to take the longer more wordy path when something like my prior style is readable and separates concerns well (don't mix view handling with business logic).
 

On Wednesday, September 7, 2016 at 11:14:43 AM UTC-6, Richard Feldman wrote:
I'm sorry to hear that your bosses are making it difficult to make good engineering choices. I've been there, and it sucks. :(

Oh if you want to see bad you should see how bad Xerox was, almost a decade with them, that was horrible...  >.<
My current job is utter bliss in comparison.  ^.^

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/aa9fdbc5-4bb0-4de2-bb33-50980776871f%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/CAAPcQhLF8NQGec5KiS6eCBJR4Z%3DePWgeOtZMBhc7gawc6qcWBQ%40mail.gmail.com.

OvermindDL1

olvasatlan,
2016. szept. 9. 0:37:182016. 09. 09.
– elm...@googlegroups.com
On Wed, Sep 7, 2016 at 1:16 PM, Sean Clark Hess <sean...@gmail.com> wrote:
> I'm not aware of components being solved well in any language. Can you point
> me to an example of where you feel it is done well? It just seems like a
> hard problem to me.
>
> I've only seen it done the way I described before, where complex
> functionality is put into a nice package, but the author has to explicitly
> support every use case. So of course it never does exactly what I want
>
> So I feel like the way forward is to provide composable view functions that
> do require some boilerplate (regular composition) but which don't suffer
> from trying to pretend that disparate things (styling, update logic, etc)
> and actually one thing.

Composable views are definitely the best for anything without state
and/or is used only a small amount of times or inside something
repeated in a list. For example, elm-autocomplete and
elm-sortable-table their current styles are absolutely perfect for
what they do. The main issue is the lack of another style that does
not fit this just yet, specifically such as in something like the
prior mentioned RippleButton. Such a RippleButton requires some state
and internal messaging, and yet it only has a 'view' type interface
exposed for usage as Messages are given to it like a normal html
element. This is the area that, for example, elm-mdl has been trying
to come up with a design with its elm-parts interface, not a bad
style, but still seems 'odd' somehow, yet difficult on how to resolve
it.


On Wed, Sep 7, 2016 at 1:16 PM, Sean Clark Hess <sean...@gmail.com> wrote:
> Hmm this makes me want to build a calendar module to see how simple I could
> get it. That seems like a difficult use case.

A calendar would be a more complex example, but does not necessarily
demonstrate the issue. The issue for my re-use here is when using the
'thing' more than just a few times or in a single area like an easily
iterable list or so, but rather it is something that is used all over
in various ways, like, say, a RippleButton. That would be more simple
to code up than a calendar, but would be a good test of the problem.
:-)
>> email to elm-dev+u...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/elm-dev/aa9fdbc5-4bb0-4de2-bb33-50980776871f%40googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "elm-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elm-dev+u...@googlegroups.com.

Richard Feldman

olvasatlan,
2016. szept. 9. 1:03:112016. 09. 09.
– elm-dev
the language should not impact the visual design of your app, no matter how bad your taste is and how good the language designer's may be.
I think asking "why" turns the matter into a philosophical discussion rather than a more prosaic "how"
Charles: I don't agree with any of these premises, so we may be doomed to talk past each other on this one. :)
 
My impression of the discussion has been:

"New guide on reuse is great, but how should we deal with components with internal state?"
"Such as?"
"Ripples."
"Ripples are needless UX flourishes. Don't use them."

This last response might be a legitimate side note leading to a discussion of UX design choices, but it is a dodge to the root question of "What pattern should we apply to handle internal state?" and even to the more specific question "How should I implement ripples in an Elm app?" To read it as an on point response, one would probably have to take it as "There isn't a good way to do that sort of thing in Elm. I don't think you should do it but if you have to then you probably shouldn't use Elm." Is that really the intended message and if so how many other contra-indicators are the for using Elm?

Mark: The intended message is this.
  1. There is no one-size-fits-all answer to "What pattern should we apply to handle internal state?" - in Elm, the only reasonable answer to a question that broad is "it depends on what you're doing." That's why the Guide section on reuse lists multiple examples, and each uses a different technique to achieve modularity.
  2. I would say the primary cost to Elm's state management approach is learning curve: you have to learn multiple techniques as opposed to one "hammer that works for nails of all sizes" that OO languages have: objects (aka components). In Elm you use functions in different ways to achieve these ends, and there is no avoiding learning those ways. (It also turns out to be a challenge just to enumerate the ways from memory, if you have intuition for them but were never formally taught them one by one.)
  3. If you must implement ripples in Elm because some hypothetical boss says "do this or you're fired" I'd probably try it like this: viewRippleButton : (ButtonId -> msg) -> List (Attribute msg) -> List (Html msg) - but again, I think going down the ripple road in the first place is a mistake.
The WebGL argument is a straw man because it shifts the question from "We chose to implement our page using this particular programming language rather than JavaScript and we have complexity around implementing this increasingly common HTML UI element" (an argument where what had been a purely engineering choice to use Elm is what is causing the "problem" from the standpoint of designers and management) to "That sort of effect is really only works well by using WebGL. Do we want to pay the cost of embracing WebGL?" (an argument that applies regardless of the choice to use Elm or JavaScript). Arguing about WebGL is a different sort of argument from arguing about the use of ripples in the UX design.

These are the same sort of argument because they both fit the same template: "We chose to implement our page using X rather than Y, which means implementing this UI element will be more expensive." You can arrive at the two cases I presented by doing nothing more than filling in X and Y with different values:

X = Elm, Y = JavaScript: "We chose to implement our page using Elm rather than JavaScript, which means implementing this UI element will be more expensive."
X = React, Y = WebGL: "We chose to implement our page using React rather than WebGL, which means implementing this UI element will be more expensive."

You included language that suggests the status quo is important here. You said "rather than JavaScript" suggesting that the default industry choice of JS is important. You also said "embracing WebGL" suggesting that the default industry choice of not using WebGL is important. These are relevant if you're trying to defend your choice of Elm to people in positions of power, but they're not relevant to the question of what will result in the best product—which is what I'm personally concerned with.

I'm getting the impression that you are coming at this from the perspective of strategizing about how to defend your choice of Elm to a risk-averse boss. Honestly I don't think that's a battle worth fighting. Adopting a non-mainstream technology confers intrinsic risk; if your boss is risk-averse, that's probably going to cause conflicts and bad times. Wait until it's mainstream and you won't have to defend your decision.

Or if you want a different specific API design question: What is the stance on elm-mdl? Good pattern to follow or bad and if bad how should it have been implemented?

I don't have a spare weekend to answer how I'd do it. It's a big API and I haven't personally used either elm-mdl or MDL in general. I'd have a ton of MDL domain knowledge to backfill.

If it helps, I know two of Søren's goals were (1) to support ripple and (2) to make using it "feel as close to using normal Html functions as possible." Personally I would not have chosen either of these goals, so it seems safe to assume I would have gone with a different API one way or another.

So, what is our core study case for internal state and what does it tell us about how to structure Elm programs when they have to deal with internal state? 

It is probably fifteen to twenty examples, each using a different technique to achieve modularity. 

Another way to put the concern that multiple people are voicing and the "don't use that widget" response only adds to is the question that almost every developer must confront: Will my choice of tools impair my ability to deliver what I want even when that deliverable is vaguely defined and likely to grow? 
What's of concern here is that some of the responses on this thread suggest that Elm is ill-suited to some UX conventions. That raised the question: What's the shape of that boundary and will it matter to me? Saying you shouldn't use ripples in an Elm app raises the question of what else you shouldn't do and whether that will matter.

Fair point. Reminds me of when virtual DOM became a thing: even with the general sense that vdom was almost always a massive improvement over the status quo, there was also an intuition that some small set of use cases would unavoidably feel less nice. I don't have a concise answer as to exactly which they are, but I do think it's a sensible question to ask.

I want to see Elm win v JavaScript because while it may be a bit more tedious (static types, etc) it produces more robust code without sacrificing expressiveness in any significant way.

I fear the argument turning into "it may not be as fast or as capable as JavaScript but it's better long term" because that long term argument potentially gets undermined if a preference for having everything just work on the global state means that the code base is difficult to segment into comprehensible parts.(*)

The examples showing that you need components less often than you think are great, but they need to be balanced with examples of how you handle "private" state (ripples) or shared state (global priority queue) or even just standard nesting of multiple independent instances of the same model needing its own internal logic. Just saying "don't do that" comes awfully close to saying "if you need to do that, don't use Elm" and that's not a great place to be for Elm adoption.

 
I agree that there should be more examples. I marked the parts I disagree with.

At this point we've pretty much gone around in circles on those, so we seem to be squarely in "agree to disagree" territory as far as those points are concerned. I suppose we'll see how things shake out. :)

Yosuke Torii

olvasatlan,
2016. szept. 9. 2:31:592016. 09. 09.
– elm...@googlegroups.com
Maybe too late? One feedback for "reuse" section.

I don't think JS people think "view" and "component" are different things. Is there any explanation of what "components" are? What is the definition of "component"? I know it's "views that are tightly coupled with their models" because I read this mailing list, but do JS people know that too?

The document says "not components but views!" but I think "checkbox with label" is also a component which doesn't have its state. I don't think it worth introducing new confusing "component" keyword, just like "monad".

It also has mentions about "parent-child communication", but it is also unclear what it means. "What is communication? parent to child? child to parent? both? triggering a Msg is not a communication?". I know it means something like `update : Msg -> Model -> (Model, Cmd Msg, Event)` because I read this mailing list, but do JS people know that too? Is the main target of this document people who reads this mailing list? For them it is good, but for others it is just a noise.

Also, parent-child communication only occurs when people deal with complex views. Mentioning "No parent-child communication" is bit too early in this document. "When component A triggers an event, another component B does something. How to pass A's state to B?" is the motivation of doing parent-child communication. This is essential case in real-world applications. But I don't think it is answered in this document. People don't want to do "parent-child communication", just want to implement the case above.

Others looks great to me. I think sortable-table pattern is really great! When sortable-table patterns are done in document, people won't even know about "communication" thing.


2016-09-06 5:48 GMT+09:00 Evan Czaplicki <eva...@gmail.com>:
Last week I got --debug to a really nice place. The next phase is to get "swapping" working in conjunction with elm-reactor, so folks can save code and see the new functionality in their browser automatically without losing their session history.

That next phase is a pretty big project and I found I needed to take a break to get productive on it, so I did the following things.


Blog

Finish and publish the blog post on performance. I felt the post could have done a lot better on Hacker News, so I found this release kind of frustrating. There were a lot of folks saying silly things. That motivated me to take a look at ways of making it so no one says silly things anymore.


Documentation

I channeled that motivation into:
  • Redoing the home page to be more visual and clear. (Would still love a PR to convert images of code into HTML blocks!)
  • Consolidating installation and "get started" docs in one place that also dumps people into the guide, so there is no way to miss the official documentation.
  • Adding a section on reuse to the guide to try to get us over this "components" confusion. So far, it has had quite a nice response!
So it sort of felt like a good time to return to elm-reactor, but the NoRedInk Elm Friday came up, and we decided to work on localStorage.


Local Storage

People have been requesting this for ages. I have worked on it multiple times in the past and never been happy with the results, so it kept getting scheduled for a revisit.

This time, I think I figured out why the results felt unsatisfactory, and I'm really excited about taking it in a different direction, described here.

I'll write a bit more about this in a separate post.

--
You received this message because you are subscribed to the Google Groups "elm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elm-dev/CAF7GuPGchZEARYEX5Qz0KNvKtetFrHO%2BFJm4LxZMYiceG88-eQ%40mail.gmail.com.

Mark Hamburg

olvasatlan,
2016. szept. 9. 12:19:472016. 09. 09.
– elm...@googlegroups.com
On Sep 8, 2016, at 10:03 PM, Richard Feldman <richard....@gmail.com> wrote:

The WebGL argument is a straw man because it shifts the question from "We chose to implement our page using this particular programming language rather than JavaScript and we have complexity around implementing this increasingly common HTML UI element" (an argument where what had been a purely engineering choice to use Elm is what is causing the "problem" from the standpoint of designers and management) to "That sort of effect is really only works well by using WebGL. Do we want to pay the cost of embracing WebGL?" (an argument that applies regardless of the choice to use Elm or JavaScript). Arguing about WebGL is a different sort of argument from arguing about the use of ripples in the UX design.


These are the same sort of argument because they both fit the same template: "We chose to implement our page using X rather than Y, which means implementing this UI element will be more expensive." You can arrive at the two cases I presented by doing nothing more than filling in X and Y with different values:

X = Elm, Y = JavaScript: "We chose to implement our page using Elm rather than JavaScript, which means implementing this UI element will be more expensive."
X = React, Y = WebGL: "We chose to implement our page using React rather than WebGL, which means implementing this UI element will be more expensive."

You included language that suggests the status quo is important here. You said "rather than JavaScript" suggesting that the default industry choice of JS is important. You also said "embracing WebGL" suggesting that the default industry choice of not using WebGL is important. These are relevant if you're trying to defend your choice of Elm to people in positions of power, but they're not relevant to the question of what will result in the best product—which is what I'm personally concerned with.

The status quo does matter in the politics. Choosing the status quo is often not even an active choice. It's just something one does. So, if JavaScript blows up, no one is going to be in the hot seat for the decision to use JavaScript. WebGL is not the status quo, so being in a situation where the non-use of WebGL becomes an issue is again not going to have political blowback. It may seem like politics shouldn't be involved in good engineering decisions and often it is a negative factor, but it also serves as a check on over wild enthusiasm and forces engineers to make the cost-benefit analysis about what will this let me do v what will this keep me from doing and does that analysis weigh out in a way that I would want to stand behind the decision rather than hiding behind "industry standard practices."

I'm getting the impression that you are coming at this from the perspective of strategizing about how to defend your choice of Elm to a risk-averse boss. Honestly I don't think that's a battle worth fighting. Adopting a non-mainstream technology confers intrinsic risk; if your boss is risk-averse, that's probably going to cause conflicts and bad times. Wait until it's mainstream and you won't have to defend your decision.

Actually, I'm more sensitive down than I am up but I'm in a somewhat special position. I've lead teams through using non-standard technologies (Lua, reactive and asynchronous UI's before they were cool, etc). Some of the people I've worked with and continue to work with acknowledge the benefits we've gotten from such moves but are also gun shy from experiences where we've had a harder time interfacing with standard components and services — everything has to start with writing bridge code — and have observed the downright hostility we've seen when more conventionally minded engineers have been assigned to teams that are using unconventional technologies. It's particularly the last issue that's a lurking problem because people with an attachment to status quo technologies will tend to use every opportunity they can find to denigrate unusual choices. That doesn't mean one has to build component architectures that look like conventional architectures, but having solid answers for how one does it in Elm is very useful.

Mark

(*) Integrating new engineers is also why something like the Elm Architecture page was much more useful than simply saying every case is different. I don't expect a one-size fits all answer but saying these are the pieces, these are the ways they fit together, and these are the ways they stretch and adjust to handle these common cases is really useful. Design Patterns became an overused and over formalized part of the OO community but they also provided a standard vocabulary with which to talk about program structure and a rubric for deciding which structures applied where.

Richard Feldman

olvasatlan,
2016. szept. 10. 7:59:042016. 09. 10.
– elm-dev
Actually, I'm more sensitive down than I am up but I'm in a somewhat special position. I've lead teams through using non-standard technologies (Lua, reactive and asynchronous UI's before they were cool, etc). Some of the people I've worked with and continue to work with acknowledge the benefits we've gotten from such moves but are also gun shy from experiences where we've had a harder time interfacing with standard components and services — everything has to start with writing bridge code — and have observed the downright hostility we've seen when more conventionally minded engineers have been assigned to teams that are using unconventional technologies. It's particularly the last issue that's a lurking problem because people with an attachment to status quo technologies will tend to use every opportunity they can find to denigrate unusual choices. That doesn't mean one has to build component architectures that look like conventional architectures, but having solid answers for how one does it in Elm is very useful.

Gotcha. Thank you for the context! This is helpful in understanding where you're coming from.

I think what I'd do in a situation like yours (where the engineering decision has so many political implications) is to say "if we think this ripple feature is essential, and a JS solution would be less work than a pure Elm solution, then we should use JS for it." I'd do this just for the ripple, though—a special case solution for an unusual political problem.

Specifically I'd write a small JS snippet to attach a click event listener to the document root which looks for click events whose target is something with a mdl-ripple class. If it sees one of those, then it directly mutates that element to add the ripple effect. I'd be very careful how I implemented it, and would probably label it a "polyfill" to emphasize the cultural aspect that this is not something the team should reach for when building normal business logic. This way 99.9% of my application could be in Elm code, and my day-to-day work would benefit from that while rarely (if ever) being impacted by the 0.1% of JS which served to prevent arguments with the pro-status-quo members of the organization.

I did something similar for performance reasons in Dreamwriter. When I switched from jQuery to React, I quickly learned that using a virtual DOM on top of the main editor ·a contentEditable that needed to hold 100,000+ words at once) was a total nonstarter for performance...so I just didn't use React's vdom for that. I had the rest of the page in vdom and made a custom API for handling contentEditable-specific logic. That way almost of my UI code got to be all nice and vdom-ish, and the non-vdom code was quarantined to that one contentEditable.

This is not a totally analogous situation, as in that case I just outright couldn't use vdom because of the performance, whereas I certainly could implement ripple in pure Elm—I would just be frustrated by how much engineering work was going into accommodate a nonessential design decision.

I can certainly see how a "quarantine a bit of JS code to accommodate an unusual need" can be the best way to navigate around not only performance roadblocks but also political ones. :)

Chad Morrow

olvasatlan,
2016. okt. 6. 13:31:162016. 10. 06.
– elm-dev
Extremely hesitant to necro this thread so if I should not have posted this I will happily delete the post. 

The discussion around material design implementation was concerning to me enough that I wanted to offer another perspective. 

Material Design is huge. It is based in a very well thought out philosophy for user interfaces and since it comes from Google, its everywhere. A lot of UX folks, product managers, marketing teams, etc. are all familiar with this design system and want to use it. Its about more than just a ripple effect; its about me telling every other department I work with that the stack we're using has a difficult time implementing a wildly popular and common UI framework.

Then there are the follow up questions of "what other simple (simple in their minds, that is) things are the developers going to pick a fight about? How many other ways has the development team caused us problems during this product release process?" 

Its just not my decision. I don't have the option to pick and choose which features I do or do not want to code. I have to work as part of a much, much bigger team. I think it might be a different story if they wanted to use a UI framework with less market dominance like Bulma or Milligram, SemanticUI, or even a framework we design ourselves. Material Design is a big deal though. 

Having said that, I really appreciated what Richard said last about how he'd potentially address the particular details about the ripple effect. I hadn't considered that solution and it may be a perfectly satisfactory way to resolve the issue. 
Válasz mindenkinek
Válasz a szerzőnek
Továbbítás
0 új üzenet