tag:blogger.com,1999:blog-8768401356830813531.post8946206495463550866..comments2023-01-12T13:01:39.386-05:00Comments on Software Simply: Ember.js is driving me crazymightybytehttp://www.blogger.com/profile/15198998578494149797noreply@blogger.comBlogger24125tag:blogger.com,1999:blog-8768401356830813531.post-74330409574612025262014-03-06T15:50:07.244-05:002014-03-06T15:50:07.244-05:00As a follow-up to all the people who have been arg...As a follow-up to all the people who have been arguing that Ember's behavior with .get and .set is well-motivated and documented...<br /><br /><a href="https://mail.python.org/pipermail/python-ideas/2014-March/026647.html" rel="nofollow">Nick Coghlan in the Python midnight boolean thread</a> has a very eloquent description of the problems with this mentality.<br /><br />"There's a great saying in the usability world: 'You can't document your way out of a usability problem'. What it means is that if all the affordances of your application (or programming language!) push users towards a particular logical conclusion (in this case, 'datetime.time values are not numbers'), having a caveat in your documentation isn't going to help, because people aren't even going to think to ask the question. It doesn't matter if you originally had a good reason for the behaviour, you've ended up in a place where your behaviour is confusing and inconsistent, because there is one piece of behaviour that is out of line with an otherwise consistent mental model."<br /><br />In my case here, all the affordances of Ember pushed me towards the particular logical conclusion that .get and .set behave like plain vanilla getters and setters. And indeed, having the caveat in Ember's documentation didn't help me because I didn't even think to ask the question.mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-59597191338967287682014-02-24T10:07:38.467-05:002014-02-24T10:07:38.467-05:00Have you considered something in the reactive fami...Have you considered something in the reactive family, like bacon.js, Facebook's React, etc.?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-28029193866811994022014-02-03T05:23:04.808-05:002014-02-03T05:23:04.808-05:00This whole discussion is an excellent illustration...This whole discussion is an excellent illustration of what's wrong with the JS community: whereas the Haskellers here know what they are talking about, the JS people "safely assume" and "think" and say "almost certainly". It's just weak. And the language *is* flawed: When you inherit a superclass in JS, one has to *correct* the child constructor pointer after doing so, otherwise it points to the parent constructor. <br /><br />Correct me if I am wrong here, I'd only be glad if that part is *completely* incorrect. <br /><br />And @Dumitru, "Feel free" is all I can say to your flaming remark. Since you can't meet any of my complaints and instead resort to smearing me on a basis of *assumed* qualifications, I think you have quite clearly shown the validity of your own arguments.<br /><br />/Flamin' FredrikAnonymoushttps://www.blogger.com/profile/10066859973651234163noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-39784215204431366522014-02-01T10:01:38.383-05:002014-02-01T10:01:38.383-05:00You absolutely can't say that RWH plays the sa...You absolutely can't say that RWH plays the same role for Haskell as "Javascript: The Good Parts" does for JS. The JS book suggests (and we all know) that JS has features that you shouldn't use in real development. Other than a couple very specific things like unsafePerformIO that's not true with Haskell. Haskell is not quirky. It is very principled. It probably seems quirky to non-Haskell people, but that's just because it is very different from what those people are used to. Different != quirky.<br /><br />Testing and debugging is a universal truth, and you get a LOT more of it out of the box with Haskell than with any other language of similar or greater popularity.<br /><br />I am absolutely a lazy programmer. Programming is about getting the computer to do things for you. If all other things are equal, I'll take code written by a lazy programmer over a non-lazy programmer any day of the week. I'm not the first person to say this either. Here's a list of the things I found about this from a 30 second Google search.<br /><br /><a href="http://blogoscoped.com/archive/2005-08-24-n14.html" rel="nofollow">Why Good Programmers Are Lazy and Dumb</a><br /><a href="http://threevirtues.com/" rel="nofollow">The Three Great Virtues of a Programmer</a><br /><a href="http://undefined.com/ia/2006/10/24/the-fourteen-types-of-programmers-type-4-lazy-ones/" rel="nofollow">The Fourteen Types of Programmers – Type 4: Lazy Ones</a><br />mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-68700692600206736842014-01-30T22:13:05.759-05:002014-01-30T22:13:05.759-05:00Haskell has Real World Haskell.
JavaScript has i...Haskell has Real World Haskell. <br /><br />JavaScript has its own Javascript: The Good Parts.<br /><br />Based on these texts, we can safely assume beginner's mistakes are abundant in both languages, and both languages are rather quirky. This is to deconstruct the notion that any of the language is easier to master for beginners.<br /><br />The approach is different, and it shows plenty with this thread. And a programmer shouldn't really expect the same from two such different environments.<br /><br />But I think you got the wrong idea. Unit testing and debugging is the universal truth. It seems you let Haskell turn you into a lazy programmer (see what I did here? ;) ).Anonymoushttps://www.blogger.com/profile/04367504761552812231noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-32846659303003228042014-01-30T21:16:56.532-05:002014-01-30T21:16:56.532-05:00@Dumitru
No, those situations are not equivalent....@Dumitru<br /><br />No, those situations are not equivalent. In Javascript, you will get an error ONLY when a code path executes that exercises the missing function. In Haskell you get the error before execution for all symbols in your program. This can be a big deal because it can mean that you find errors a long time after you actually broke the app. It can be much harder to debug things in this situation.<br /><br />It is also much clearer what needs to be done. Haskell tells you exactly what function is missing. You go to Hayoo or Hoogle and search for it, and you add that import. All Haskell programmers, even beginners know this. More modern IDE/editor plugins can even insert it for you. I've frequently seen Javascript error messages that I couldn't get rid of that seemed to have no effect on the correctness of my app. Therefore I conclude that error messages aren't always related to my bugs even when the code path that generates the error message does execute. So maybe you're right that a much more experienced Javascript programmer could have found it faster. But that makes Haskell better because you don't need to be an expert in order to efficiently debug things.mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-91172425508515203802014-01-30T20:10:52.612-05:002014-01-30T20:10:52.612-05:00So far your complaints are not with JavaScript, fo...So far your complaints are not with JavaScript, for a JavaScript programmer, or any programmer for that matter, they are about your low level expertise in testing and debugging in JavaScript.<br /><br />The missing library bug would definitely happen in Haskell too:<br /><br />-- import System.Info<br /><br />main = do<br /> print os<br /> print arch<br /> print compilerName<br /> print compilerVersion<br /><br />This fails with "Not in scope: ..." messages that will not point you to System.Info any more than your browser console errors will point you to jQuery UI.<br /><br />It fails in a different way, but still, that's the job you have to take care of both in Haskell and in JavaScript.<br /><br />If you don't have the time or the will to get a better grip on JavaScript,that's fine. Just be honest about it, don't be so quick to get on a high horse.<br /><br />We prove JavaScript is worthy without relying on the perfect language and the perfect scenario and the perfect environment each and every time, like you Haskellers depend upon.Anonymoushttps://www.blogger.com/profile/04367504761552812231noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-29947848654788302562014-01-30T19:20:01.049-05:002014-01-30T19:20:01.049-05:00@David
I have definitely considered the idea that...@David<br /><br />I have definitely considered the idea that GUI programming might be inherently more complex. I don't have a lot of GUI programming experience yet, but there are definitely things about it that seem tangibly different enough from, say, backend development that there might be legitimately more complexity.<br /><br />However, I can assure you that my negative opinion towards Javascript is not misplaced. GUI programming complexity might account for some of my issues, but it does not account for all of them. The issues I encounter almost always could have been significantly less painful in a language with purity and strong static types. In fact, just yesterday three people in my company were blocked by a bug. One person had recently done a major restructuring of our HTML markup. Two days ago he discovered a problem with a GUI control. Since we didn't have any other related changes that should have caused the problem he tried for some time to figure it out. Finally he gave up and threw it over to me since I wrote all the Javascript code. Another coworker also noticed the problem, which prevented her from working on certain tasks. Finally after trying to trace the source of the problem for awhile I finally figured out that we were simply missing the jquery-ui import!<br /><br />This bug would never have happened in a language like Haskell. This is not my opinion, it is a fact. I can point to all kinds of other problems that either never would have happened or would have been resolved much more quickly in Haskell. You have not used Haskell, so how could you possibly know? Some might argue that it's our limited Javascript experience that led to this bug. But that's an invalid argument because in Haskell the bug wouldn't have happened to anyone of any experience level.mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-12155359334087332372014-01-30T10:41:16.689-05:002014-01-30T10:41:16.689-05:00Dear author. I believe your hate towards Javascrip...Dear author. I believe your hate towards Javascript is misplaced. Often I've encountered people complaining about Javascript but what they were complaining about is GUI programming. <br /><br />Yes, Javascript the language has its oddities and flaws but the problems you've talked about are issues that occurs whenever there is an event driven GUI system.<br /><br />It doesn't matter if you use C, Javascript, Ruby, Java, etc. When you have complex interactive GUIs you encounter that type of issues (it's one of the cons of the Observer patterns).<br /><br />I've not used Haskell enough but you should try to create a desktop application of similar complexity with a GUI library of your choice and using Haskell as programming language. <br /><br />I believe you will encounter similar difficulties.<br />Give it a go and let us know.<br />Davidhttps://www.blogger.com/profile/03980639037814519502noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-30458993328495260412014-01-29T10:37:27.937-05:002014-01-29T10:37:27.937-05:00@Fredrik Carlén: I'm absolutely convinced that...@Fredrik Carlén: I'm absolutely convinced that if this was a potatoes vs. potatos talk, it wouldn't matter which side, you'd still be flaming pointlessly.<br /><br />Less bugs recipe: grow up, learn better programming and do it so in more than one language. It works every time. Uni-dimensional CS guy is something of the past.Anonymoushttps://www.blogger.com/profile/04367504761552812231noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-39954173547440742742014-01-29T04:19:58.068-05:002014-01-29T04:19:58.068-05:00Oh, come on, you Javascripters. Are you so serious...Oh, come on, you Javascripters. Are you so seriously afflicted by Dunning-Kruger that you have to defend the language - warts and <b>all</b> - by saying that Javascript and Haskell are created <b>equal</b>? I sit on both sides of the fence, and I would trade my JavaScript sessions for Haskell any day of the week. <b>All</b> my bugs are to do with JavaScript. Strange? Not at all - not all languages are created equal, and Javascript has evolved from a little <i>industry</i> toy language whereas Haskell has some serious research behind it - ever expanding. I am ashamed to say I work in JavaScript when I encounter this kind of blatant ignorance. I do think that the language has its merits, though, and I do think that it's probably for the best that it's not typed strongly and statically. But can we agree it was not designed for coding big frameworks? It's <i>possible</i>, yes, but hardly advisable. And I really am sorry, but any retort to this of the less informed kind will be filed under "ignorant" and ignored. <b>Inform</b> yourselves, for the love of all that is good. People in CS and the programming industry will take you much more seriously if you concede to the language having its flaws - I see Haskellers do this all the time. But I suspect that being a Javascripter comes with a lot of identity building around the language, that it's hard to do this. Anonymoushttps://www.blogger.com/profile/10066859973651234163noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-35234432273092601522014-01-29T00:14:19.303-05:002014-01-29T00:14:19.303-05:00JavaScript and Haskell are similar in this way. Ea...JavaScript and Haskell are similar in this way. Each one is easy to get started with, but it takes some time to write quality code in either of them, and it's a challenge to choose a path or another when coding in either of them.Anonymoushttps://www.blogger.com/profile/04367504761552812231noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-74783263675159939242014-01-28T18:51:38.673-05:002014-01-28T18:51:38.673-05:00@Anonymous
"proxying unhandled attempts to g...@Anonymous<br /><br />"proxying unhandled attempts to get and set"...that's about as clear as mud. Might be clear if you already know, but not at all clear if you don't.<br /><br />The ObjectProxy phrasing is much clearer. But this is in the API documentation, which people are much less likely to read. I did refer to these API doc pages significantly, but for things like Ember.Select where it was obvious what I was going to find there. I couldn't find anything in the guide indicating that ObjectProxy/ObjectController is the place where I'd find out about this special case behavior of get and set. I'd actually expect to find the get/set behavior defined in the Object class. So I just don't think it's reasonable to expect users to know to look in ObjectProxy to find out about this weird behavior of a ubiquitous concept.<br /><br />Yes, some amount of this pain is to be expected when learning any new significantly complex system. But my observation is that you see a LOT more of it in Javascript than in Haskell.<br /><br />@Dumitru<br /><br />I totally get what you're saying, but I actually think that's actually backwards in a way. It definitely seems like Javascript is easier to get started with than Haskell in terms of understanding concepts and making progress out of the gate. But in another way, I think there's an argument that Haskell takes less seriousness because it's constantly pushing you in the direction of good design. To be effective with Javascript you have to learn all kinds of best practices that people have learned after years of the school of hard knocks. I'm really not interested in doing that because my experience with Haskell has led me to believe that much of that best-practice knowledge is accidental complexity. Yes, there are still a set of best practices to learn in Haskell, but that set is much smaller than the corresponding one for Javascript because Haskell has the right defaults. So I think it's easy to be a casual Haskell programmer and still effectively contribute to large complex projects.mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-85501306228354181772014-01-28T18:11:24.638-05:002014-01-28T18:11:24.638-05:00That's why "I can quickly do JavaScript t...That's why "I can quickly do JavaScript too" works only up to a point. After that, JavaScript requires the same seriousness it would take to learn Haskell, for example.Anonymoushttps://www.blogger.com/profile/04367504761552812231noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-61081868976904330102014-01-28T17:52:15.454-05:002014-01-28T17:52:15.454-05:00To be fair, the documentation for ObjectController...To be fair, the documentation for ObjectController says at the very <a href="http://emberjs.com/api/classes/Ember.ObjectController.html" rel="nofollow">beginning</a>:<br /><br />"It is intended to wrap a single object, proxying unhandled attempts to get and set to the underlying content object"<br /><br /><br />The docs on ObjectProxy <a href="http://emberjs.com/api/classes/Ember.ObjectProxy.html" rel="nofollow">also metion it</a>:<br /><br />"Ember.ObjectProxy forwards all properties not defined by the proxy itself to a proxied content object."<br /><br /><br />I personally wouldn't give up the proxying behavior, which is hugely beneficial, in order to get around that confusion. <br /><br />The fact that <a href="https://github.com/emberjs/ember.js/blob/v1.3.0/packages/ember-runtime/lib/controllers/controller.js#L44" rel="nofollow">'model' is an alias for 'content'</a> is one of those emberisms you learn after you work with the framework for a bit.<br /><br /><br />To a certain extent, these are the downside of convention over configuration frameworks (or really any new thing you're learning, but I found this to be especially so for Ember). Sometimes the conventions aren't totally intuitive so you have to be OK with the fact that when you're starting out you'll see surprising things that only become clear later. When I was starting with Ember I felt like this pretty frequently. The more I work with it, though, the more I enjoy the way the whole package fits together. Hope you don't give up on it just yet.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-37755781826050130432014-01-28T16:54:52.716-05:002014-01-28T16:54:52.716-05:00@wagenet @ebryn To address the setting of the `con...@wagenet @ebryn To address the setting of the `content` issue we could add Ember.Logger.(log|info|warn)("The content object is magical. Resetting it may result in behavior you don't expect.") to this function:<br />https://github.com/emberjs/ember.js/blob/master/packages/ember-runtime/lib/system/array_proxy.js#L137<br /><br />There might be a better solution that will have fewer false positives (model being set for the first time, etc.) but there is real value here. One of the first things that I coach new devs on our team to do is "make sure you can explain why you're setting the `content` property if you're doing it." (It <em>always</em> gets flagged in code review.)Anonymoushttps://www.blogger.com/profile/14583782547787097736noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-65850344253636526302014-01-28T16:37:35.792-05:002014-01-28T16:37:35.792-05:00@mightybyte:
What you're describing in the fi...@mightybyte:<br /><br />What you're describing in the first situation, is the behavior of ObjectController as described here http://emberjs.com/guides/controllers/representing-a-single-model-with-objectcontroller/. I understand that this may have caught you by surprise, but a ton of Ember's power comes from its ability to do things like this. I would assume this is part of the reason you chose Ember in the first place.<br /><br />I think in the second case, you probably tried to comment out Handlebars code with HTML comments. The problem with that, is Handlebars is not aware of the the surrounding syntax. Your end result is that the *evaluated* Handlebars is wrapped in the comment.<br /><br />Again, I understand your frustration, but it seems like you're blaming Ember for behavior without attempting to first fully understand it. I've never used Haskell or any functional programming language. I imagine that if I jumped in, I would find many things that would surprise me and probably enough for me to write a "Haskell is driving me crazy" post. However, this would almost certainly be because of my shortcomings and unfamiliarity with its style, not because there was something fundamentally wrong with it.<br /><br />(Reposted due to formatting errors.)Peter Wagenethttps://www.blogger.com/profile/17392424917403816813noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-86880338751903784382014-01-28T14:23:09.410-05:002014-01-28T14:23:09.410-05:00@Peter Wagenet and @Erik
For "Spontaneously ...@Peter Wagenet and @Erik<br /><br />For "Spontaneously Changing Values" here's a <a href="http://jsfiddle.net/paMFr/" rel="nofollow">jsfiddle</a> that demonstrates the problem exactly. I asked about the problem on IRC on October 29 and mmun gave me a solution.<br /><br />My problem was caused by the special treatment of the content field. I was setting foo, but Ember was actually setting content.foo because I didn't have a "foo: null" declaration in my class. This meant that when I did a set to content, foo got magically cleared out. This is absolutely Ember's fault because Ember devs made the decision to treat content in a special way. Now you may have good reasons for it, so I'm not actually criticizing that decision. Design decisions are usually complex tradeoffs and I'm not going to claim that you made the wrong one. But I will claim that it violates the principle of least surprise and led to an incredibly frustrating situation.<br /><br />Regarding the zombie code error, I don't have the time or desire to investigate it. All I can say is that it happened exactly as I said. I think I commented out the template references with an HTML comment, but it's possible that I completely deleted it from the template. Then I kept the controller and view definition around exactly like I showed in the post. Deleting the code or commenting it out would fix the problem with a completely different control. There's an outside chance that maybe after some other modifications that unused code ended up with an error condition. I don't remember. If that was my problem, I place the blame squarely on Javascript's dynamic typing, and possibly on Ember if it did something to execute this code that seemed like it should be unused. If that wasn't what was happening, then I really have no idea what might have been causing it. But again, it was massively frustrating to see what seemed to be quite reasonable expectations violated.mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-11919528688053764032014-01-28T13:48:38.740-05:002014-01-28T13:48:38.740-05:00Hey, I'm Erik, an Ember.js core team member.
...Hey, I'm Erik, an Ember.js core team member.<br /><br />I'd be happy to help you track down the issues you came across and explain to you what is going on.<br /><br />You can reach out on Freenode or Twitter, I'm @ebryn. Otherwise, email me at erik.bryn -at- gmail.Erikhttps://www.blogger.com/profile/03100922872900771223noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-44547331651031786352014-01-28T13:08:09.617-05:002014-01-28T13:08:09.617-05:00@Peter Wagenet I think the confusion explains grea...@Peter Wagenet I think the confusion explains greatly on what the issues with EmberJS. Ember is not straight forward and is harder to understand than others, like AngularJS. This was my perception when deciding which framework to use. AngularJS feels natural.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-55419633121232405542014-01-28T12:41:09.970-05:002014-01-28T12:41:09.970-05:00I'm on the Ember Core Team and I'm a bit c...I'm on the Ember Core Team and I'm a bit confused by some of your complaints. It seems like you've either encountered some bugs, or there's more to the situation that you're explaining. Unfortunately, it's also very possible that you were provided some bad explanations about why things behave the way they do. I'd love to see some more details on these issues, especially in a JSBin or JSFiddle that I could play around with. At this point you might be over it and not care to help out, but if there's still any interest, I'd love to work with you.Peter Wagenethttps://www.blogger.com/profile/17392424917403816813noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-72038073569228953242014-01-28T12:03:17.437-05:002014-01-28T12:03:17.437-05:00avoid frameworks with magic.avoid frameworks with magic.Joeyhttps://www.blogger.com/profile/14877146025800167568noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-68238123599635097092014-01-28T11:55:27.558-05:002014-01-28T11:55:27.558-05:00None: In this case it wasn't any kind of asyn...None: In this case it wasn't any kind of asynchronous onchange event. The value was actually being changed by the this.set('bar', ...) call.mightybytehttps://www.blogger.com/profile/15198998578494149797noreply@blogger.comtag:blogger.com,1999:blog-8768401356830813531.post-34519833822536497932014-01-28T11:53:24.100-05:002014-01-28T11:53:24.100-05:00"console.log(this.get('foo'));
this.s..."console.log(this.get('foo'));<br />this.set('bar', ...);<br />console.log(this.get('foo'));"<br /><br />Almost certainly some "onchange" event or binding being triggered on the bar change that updates foo. <br /><br />Javascript frameworks built around objects calling .get(identifier) and .set(identifier, value) cause your application code to degenerate into total spaghetti pretty quickly. Tracing these pseudo invocations in code becomes impossible. Nonenoreply@blogger.com