Your solution redefines the word "local" to mean "global." Yes, you can store a component's intrinsically local state as field in your global model and then use a specialized update function that is reached by a switch from your global update function. The question we are addressing is: Is that a good idea?
GHCJS is bees-knees. But unfortunately, minimizing-code-size/mobile-performance has not been a priority. (It's understandable, as Luite can't do everything himself.) (Aside: the best solution I've seen -- in terms of generated code size -- in GHCJS-land right now is: https://hackage.haskell.org/package/react-flux. Anecdotal, though. YMMV.)
I can't wait for GHCJS to be ready for prime time. I wish all these alt-JS-haskellish language authors (of Purescript, Elm, Roy, etc.) would just work on making GHCJS better.
It's a bummer that Clojure and Scala are much newer than Haskell and yet they both have a mature, production-ready JS compiler. The statically typed ML-family is too small for multiple JS compilers. The entire community needs to pick one and let the others die. Otherwise, we end up with several half-baked solutions and not a single industrial-strength one.
> I wish all these alt-JS-haskellish language authors (of PureScript, Elm, Roy, etc.) would just work on making GHCJS better.
All three of those have very different goals and trade-offs from GHCJS.
I agree that it would be nice to share more work/knowledge though. One of the nice things about AltJS is that several languages can coexist in the same codebase.
> "All three of those have very different goals and trade-offs from GHCJS."
And therein lies the problem. In my view, the most important goal is to have at least one really good AltJS-Haskellish language with a fully-featured ecosystem of libraries. (I'm fine if that language is PureScript, btw. PureScript is fantastic.) The problem -- which Clojure and Scala programmers seem to have sorted -- is that our community is too small to support several Haskellish-AltJS compilers. Do we really want several perpetually nascent solutions?
> "One of the nice things about AltJS is that several languages can coexist in the same codebase."
Theoretically, you're right. But how many production code bases are there in AltJS-Haskell (vs. say, Clojurescript)?
In other words, you never use the value attribute on the input; rather, you give it a unique key and don't touch it directly. Whenever you want to change its value, just send the desired new value to that port and let the JS snippet do the "stash cursor position, set the new value, restore cursor position" bit.
If you need to do this for multiple elements, send a DOM query string to the port and call document.querySelectorAll (or the like) with it to apply the logic to the correct element."
Clearly, you don't even believe that all component local state belongs in the atom. And kicking the issue to JS-land is just hiding the problem.
Almost everything should be unidirectional, but @boubiyeah has a valid point. Not everything belongs in a single state atom. (I say this having written a 4000 LOC Elm app, which I'm porting Clojurescript/Re-frame due to precisely this issue.) Even Haskell uses mutable references for this stuff.
That's not at all disingenuous; the two are completely unrelated. :)
The DOM uses local state extensively, and sometimes you need to interact directly with its API. When you do, you can either do more work to translate it into your preferred architecture, or not.
In this case I didn't think the extra work required to wrap the DOM API for cursor position would be worth the trouble.
That's certainly not an endorsement of the DOM's architecture. ;)
> "The DOM uses local state extensively, and sometimes you need to interact directly with its API. When you do, you can either do more work to translate it into your preferred architecture, or not."
> "Local component state is the new two-way data binding. . . If you listen to people who have spent a lot of time with both systems, what you hear are a lot of single state atom converts and not a lot of people saying "yeah it wasn't awesome so I went back to local component state."
> "I wouldn't maintain cursor state in the model . . . Whenever you want to change its value, just send the desired new value to that port and let the JS snippet do the "stash cursor position, set the new value, restore cursor position" bit."
The question we were addressing is where your state should live. @boubiyeah questioned the wisdom of storing all component state (e.g., the current position of a cursor) in a global atom. You responded that "[l]ocal component state is new two-way data binding." Yet yesterday you advised that component local state should live outside of the global atom.
Maybe it wasn't disingenous, as perhaps you've simply changed your mind. But then you should make clear that your opinion today is different from what you advised yesterday, as it bears on the credibility of your current advice.
When did evidence-backed criticism become synonymous with trolling? Also, which statement exactly was angry? (Let alone rubbish? Or, gasp, vomit?)
It seems you want all Elm news to be positive Elm news. So does the language's author. In fact, when addressing the announcement re: Hacker news, he wrote this:
"Just an FYI, if you go to a HN post via direct link and vote on it, those votes either do not count or are used as demerits because it indicates that people are trying to artificially boost things. I guess getting a kickstarter to the top of HN can be worth a lot of money, so they try to protect against voting rings."
1. You don't get to define evidence-backed criticism to be only the criticism that you appreciate.
2. I didn't "attack" Richard. I pointed out an inconsistency with other recent statements that he has made, that bear on the credibility of his current advice.
3. I'm not sure how my identity is relevant to my ideas. But the reason I don't post under my own name has to do with requirements of my job. (I'm not a programmer by trade.) I can't have social media accounts. In any event, this isn't a throwaway account. These are, in fact, my first posts to HN.
Nope, just that the effort required to wrap something in a nicer architecture sometimes outweighs the benefits you'd get from the upgrade. This was one of those cases.
Maybe the answer is for elm-html to put a cursor-state attribute on textual input elements, and have event handlers for selection change? Then you can have the cursor state in your atom if you need it without ports....
That might solve the cursor issue, but it's a bigger issue than cursor state.
The real issue is that Elm doesn't treat its programmers like grown-ups. That sounds harsh, so let me explain . . .
I've drank enough of the Haskell Kool-Aid to realize that, despite the surface discourse, Haskell is not about religious devotion to purity and lazy-evaluation. It's about managing side-effects, and being honest about them in your type signatures. Yes, Haskell allows functional purity but its real genius lies in how well it helps you manage state. (I did an imperative Algorithms course completely in Haskell, and the language really shines. Mutable unboxed arrays, mutable atomic references . . . it's all there when you really need it.)
Unfortunately, the folks driving Elm development take a paternalistic tack. (If someone seeks to argue this point, it's not hard to come up with many, many examples from the Elm mailing lists.)
I think it's healthy for programming languages to have a point of view; that is, languages should lead you in a direction. (Clojure does a great job at this.) Yet, ultimately, a language shouldn't censor its programmers.
Upshot: Component local state should be an option in Elm when you really need it.
The <~ for Signal.map is a good example for a "clever" thing which makes languages hard to read for newbies. It looks like it's part of the syntax and not a function. It's not hard to understand, but it's another thing to learn. I am very happy that things are removed from Elm (or not added in the first place, like type classes) because design is not finished when there is nothing more to add but when there is nothing more to remove.
I've seen Evan's talk. Evan confuses the presentation of features with the value of those features. (I suppose one could solve the difficulties people have in learning Mathematics by throwing out everything after Algebra I; another solution, however, might be to do a better job teaching the more difficult stuff.)
Just because you shouldn't expose new programmers to advanced concepts on the first day doesn't mean they shouldn't be a part of the language. Similarly, the fact (<~) might confuse someone new to Elm isn't a reason for removing it from the language.
I'm sympathetic to the concern that some code is too "clever" or dense; but Elm swings the pendulum too far.
This is what I expected would already be setup - it'd be a pain to deal with cross-browser stuff when implementing it, but it'd be a dream for app developers (me).