No more Haml or CoffeeScript
kirillzubovsky.com
kirillzubovsky.com
1. Neither are particularly hard to learn, assuming you understand HTML and Javascript reasonably well to begin with. In fact, there isn't much to these abstractions at all. Coffeescript probably has more rough edges to be aware of though. Which is to be expected, all programming languages have their dragons to be sure.
2. Both offer non-trivial gains in terms readability of the written code.
3. Both can make future change of code non-trivially easier
4. Both seem to offer less friction for what is a fairly trivial learning curve.
I've never been able understand the argument that on teams using these abstractions things makes it harder because not everyone "knows" them. I guess my response is "what is there to know?". This may come across offensively, but I'd be pretty dubious of anyone who struggled to "get" HAML/SLIM or Coffeescript.
I used to hear a lot of similar arguments working in .NET for not using open-source frameworks, things that were vastly superior or easier than the MS ordained stuff (nHibernate, Nancy, ServiceStack, etc.). In the end that perspective hindered the teams growth and abilities far more than it helped them.
I also don't seem to experience this added friction people say is there. Don't get me wrong I see the bulk of the problems that HAML/SLIM and Coffeescript have, they're far from perfect. But I still find them more comfortable and notably lower friction than working with HTML and Javascript directly.
I've never seen non-trivial gains by either, either in readablity or expressibility. A few less lines != more readable.
I've been using CS wherever possible for the past couple of years, and I find it much more readable than JS.
I disagree. this might be the case for Rails devs and people familiar with the Rails stack. But I have worked on a large enough team with enough people coming and going with different backgrounds to see more people having difficulties picking up and using haml && coffeescript than just erb/good 'ol javascript.
Sure they'll figure it out eventually, but the learning time adds up, and I haven't seen any actual gains from eventually knowing both of them well enough.
> Both offer non-trivial gains in terms readability of the written code.
Please elaborate on this, because I've seen the opposite. Everybody working on the web knows html and javascript. Usually having to layer haml and coffeescript on top of that knowledge slows them down unless they've been doing it for long enough
CS also eliminates boilerplate code like hasOwnproperty() checks, loop variable initialization, null checks on object properties (null soaking), etc. It's visual clutter.
I can code in JS just fine, but it looks rather busy compared to CS.
They may have the syntax memorized, but they aren't seeing the bigger picture. HAML and Slim are just alternate ways of getting at that bigger picture.
I learned it very early in my career, and it was once of the first things that really accelerated my work. I'm not, and have never been, a rails dev.
Coffee is a bit different (IMO) because it changes the way the language works, instead of being a 1-1 conversion like HAML. I personally don't like it, it just seems like a big bag of syntax sugar tricks thrown together. If I'm going to learn a js preprocessor language, it will be something with a cohesive design as a language (like Clojure or Wisp https://github.com/Gozala/wisp) instead of Coffee's grab bag of gee whiz.
Why learn a new way of writing html at all though? what exactly is wrong with HTML as it is that necessitates learning a new way of doing it?
* HTML's ceremoniousness is burdensome (I hate XML declarations)
* I've never liked the appearance of regular code inside an XML document... visually, HAML looks a lot more like "code", so template code is more visually pleasing (this is a matter of taste)
If you have a team of people who love and want to do haml/coffeescript. have at it. If not, its just another thing to learn for people who'd rather not.
Having external factors such as a diverse team, or wanting to draw from a larger pool of developers should factor in to your decision to adopt CS. But as a language, I can say it's objectively better in my experience.
"I've been able to ..." indicates that it is subjectively better (better for the individual reporting.) It is not the kind of information that supports a claim of objective superiority.
I would argue that it is objectively better to have less boilerplate code (hasOwnproperty(), loop var initialization, lack of splats), visual clutter (brackets, braces, etc), strict comparison by default, string interpolation, array range notation, destructuring assignment, etc. My experience does back that up, but again, I can't source any objective empirical evidence.
And it's important to have a thorough knowledge and experience with both languages. I find in arguments about CS, there's a lot of knee-jerk reaction from people who haven't given CS a fair shake. It had (has?) a "Ugh, hipster" backlash against it.
On the individual level, I do think you can find actual objective gains in developer productivity, but on a aggregate level, it becomes muddier because of the variation of developer habits.
Personally, I eliminated a lot of problems associated with close tags in my markup by using Haml. But my coding habits aren't someone else's coding habits, so Haml (or Coffeescript) can go from being a solution to being a problem for someone else.
The problem with HTML is the closing brackets that don't need to be there if you use indentation. If you are using indentation anyway, what is the point if closing tags? You can eliminate a lot of extra characters. It's not always perfect, but in many cases it is a lot cleaner.
It's still probably a win on the whole, but there's one thing that coffeescript advocates should never do. And they frequently do it.
And that is answering javascript questions with coffeescript. If they want to write Jasmine tests, don't show them coffeescript. If they want an answer on stackoverflow don't give them coffeescript.
Coffeescript is not javascript, and it should never be given unless specifically asked for.
> The syntax for functions that take parameters after
> an anonymous function isn't obvious.
Eh? A function is an argument list (), an arrow ->, and an indented body of code. Putting 'em together: request(url, (response) ->
handle response
, (error) ->
handle error
) request url, ((response) ->
handle response),
(error) ->
handle errorI prefer your first example, personally.
request(url, (response) ->
handle response
, (error) ->
handle error
)
request(url,
(response) ->
handle response
(error) ->
handle error
)
request(url
(response) ->
handle response
(error) ->
handle error
)
request url, \
(response) ->
handle response
,
(error) ->
handle error
request url, (response) ->
handle response
,
(error) ->
handle error
It's very reasonable for a JS developer to be confused when seeing those.It's just syntax, people.
The principle argument against whitespace significant languages is separation of concerns. Punctuation only for syntax and whitespace only for formatting.
That said the benefits of CoffeeScript still outweigh the tradeoffs for me.
There's also a productivity thing: familiarity is a really big deal in UX design, and dev environments are no different - you might already have your build system all setup, and be accustomed to read non-HTML/CSS syntax, but others may not be up to the same speed and the requirement for a non-standard tool may bog them down more than help.
Time and again I've seen people say their setup is great, but then try to get someone else setup too, and it's a never ending series of downloading this and installing that and some typing some undocumented command line thing and oh you need a VPN connection to see the database in order to auto-gen that other thing, and to start the web server you type this, and oh crap how do I edit hosts files in Macs again, etc etc
In my opinion, the opposite is true – HAML adds a lot more than CoffeeScript. As a very experienced front-end developer, this example from the HAML documentation is completely inscrutable to me:
%div[@user, :greeting]
%bar[290]/
Hello!In any case, your argument kinda reinforces my point about familiarity...
I love coffeescript (not a huge fan of haml) as well, but the article is spot on, haml has an adoption problem ... and by that I mean I could pull a guy who can do html/css layouts off the street corner and they can figure out erb templates in an hour or so, but with haml they're still having trouble working with it weeks later. Thats because haml was built to solve Rails developers problems not frontend developers problems like say less or sass was (and you can see how those are doing).
With coffeescript, the two problems are
- writing coffeescript is fun, coming back to make sense of what you wrote months later is an absolute nightmare
- debugging it is a massive PITA
Coffeescript is mostly syntactic sugar that gives you a lot of other benefits but, again, if you want to move quickly as a dev team its one more thing for people to learn or know when they come on line and maintaining it can be a real hassle.
On my current team, we started out on an app that had an even split between haml and erb templates, we stopped doing haml and only do erb now. We started out with some coffeescript but after running into the problems mentioned above, we don't write any new coffeescript.
That is not to say certain teams won't prosper by embracing these two abstractions, just that in my experience the benefits aren't usually worth it. As always YMMV
[1] I'm natively wired to run toward very dense 'interfaces' (ui, syntax)
[2] Honest open question, don't wanna 'argue'.
Haml feels like just an unnecessary abstraction on top of something (html) that was just fine to begin with. But a lot of engineers seem to like it, so I think its great for those people.
> So called "front-end engineers" who can't understand haml after 3 minutes have no business calling themselves "front-end engineers"
Gotta love the arrogance of the remark :)
Remember that there are tons of people that aren't classically trained "engineers" that have to work on apps around the world, lets spare a thought for them ;)
More seriously, I don't think the argument is them understanding haml. The problem is the learning curve. Its not that steep but having to look up how to do stuff that you could just type right away from memory in plain html every 5 minutes, slows you down, and people want to move quickly.
Theres also the fact that when haml breaks you get a Rails error vs the way html breaks which is that the display just looks all wonky. Lets not underestimate that.
> Is HAML really that hard?
Again, what are all the objective "benefits" of haml that necessitate having to learn this new abstraction? I can tell you why I use Rails over Cakephp, but what is the problem that haml is trying to solve exactly?
Speaking only from personal experience (and I'm talking about my own bad habits with HTML), I have had plenty of bugs related to mismatched open and close tags in heavily nested HTML code, which would result in time consuming debugging. I've all but eliminated these types of issues by using Haml. I no longer have to worry about accidentally deleting the wrong close tag when de-nesting a block of markup.
Is it a cure-all for everyone? Not at all. But for some people, it's a godsend.
Plus, I've heard that syntactic sugar causes cancer of the semicolon.
With javascript, there is SO MUCH there that it can be hard to read through.
Brackets, semicolons, insignificant whitespace, var keyword, and named functions are some of Javascript's strengths. List comprehensions are nice, but be honest, how many times per year do you use them?
I'd take JS over Coffee any day
Some others are loop variable initialization, better hasOwnproperty checks, destructuring assignment, null soaking on objects, string interpolation, and array ranges.
I've never found a good case for named functions over function expressions, other than maybe arbitrary order of source code. Even then, I usually put functions at the top of my files before they would be used in the script's execution. But to each their own.
I don't use list comprehensions that often.
I'd take CS over JS any day.
Apparently a future version of CS or CSRedux will have it so that this CS:
myFn = ()->
# function body
Gets compiled to this JS: var myFn = function myFn() {
// function body
}if you document your code properly, there should be no issue figuring out what does what month later, I dont really find JS very readable,you often need to guess the intend of the programmer since there are little structures available.
> debugging it is a massive PITA
no problems with source maps.
I use Coffeescript because it's more productive than writing Javascript , on average i write 40% less code with it.I dont have to lint anything,worry about prototype inheritance done right and my code feels more descriptive than imperative,thus more readable.
The class system allows really powerfull metaprogramming. With nodejs and the source-map-support module, there is 0 issues. As for documentation there are tool that allow doc generation from cs source files, test generation for from cs classes ,etc ... There is a reason why there is all these transpiled languages around js, because most people just dont like writing JS code.
And yet, by the end of the day you will have implemented the same amount of functionality. Reading and testing is what takes time, not writing.
HAML and Coffeescript only change the syntax.
To me, this adds little value. If Javascript appears scary, spend more time with Javascript so groking it becomes easier for your brain. Making a tangental change to a completely different syntax seems like a wasted investment. When debugging in the browser, you're still going to require knowledge of JS, even with source mapping. Delving into other libraries will still require knowledge of JS. The entire JS community is not hardened in Coffeescript, so the pivot you make to learning Coffeescript is time not spent learning JS, setting you behind when groking other source.
HAML seems to add even less. HTML is just markup, it can only ever get so scary, and if you're in control of the source, you should strive to not make it scary. HAML seems like the worse case scenario for hand-holding.
That is to say, I'm not against precompilers that actually add something useful. I'm in the middle of evaluating TypeScript, and depending on its 1.0 release and its community support, I may very well choose to fully adopt it. But for me to start using your precompilation tool, you better be adding more than just syntactical changes. If you're worried about needing tools to help you remember to close an HTML tag, your problem isn't with the language, you just need to become a better programmer.
I knew JavaScript better than probably 99% of JavaScript developers. I was skeptical of CoffeeScript until I was forced to use it for a couple weeks, and haven't looked back since.
> First, compiler languages require some learning.
Every new technology require some learning. This shouldn't be the number 1 reason not to use one.
> Second, both languages make debugging a harder process.
Haml harder to debug than html? How so? Coffeescript harder to debug javascript? Maybe there is an extra step, but how do you weigh in the better readability in CoffeeScript when it comes to debugging complex code?
> Lastly, there are just too many dependencies.
"Every time I touch code, I am forced to touch two levels of abstraction." I seldom if ever need to touch the javascript file compiled from the coffeescript. And I really don't see how come more coffeescript files is more complex to handle than a couple of coffeescript? I can assume that you don't manually compile them one by one right?
> First, compiler languages require some learning. HAML is awesome, but the number of people who know how to write it is small. That means every time we need to make a change to Scoutzie, not everyone can get tasked with updates. Same goes for Coffee.
I'm sorry to hear that you don't have a culture of learning and teaching other people at your company new technologies.
> Second, both languages make debugging a harder process. When something breaks and I try to fix it, I can't always tell right away whether it's due to poorly written logic, or simply improperly written code.
Both CoffeeScript and Haml have syntax errors so you can tell whether your error is syntax related or not.
> Lastly, there are just too many dependencies.
If you're using Rails, which it sounds like you are, the coffee-rails gem is in your Gemfile by default. I've never had any issues with the coffee-rails or Haml gems in 3 years of using them. I hardly notice that they are even there.
Granted, I don't use HAML because it's syntax is ugly; I prefer Slim. I vastly prefer using SLIM as opposed to raw HTML with horrendous tags. Compare:
<p><%= @user.name %></p>
p= @user.name
We're in the future, let's use smarter tools.I can't get many HTML developers to write valid markup. A preprocessor that won't build your HTML file until you satisfy its syntax prevents that.
And I can never accept "because learning it is hard and what we know works fine" as a valid argument.
We have tons of little modules that are all in coffeescript that need to be compiled to js before we run component-build. Just not having to deal with that step would simplify everything. We're starting to value simplicity over fancy things at scale.
Kind of made me appreciate the thesis of Go a bit more now. I was initially unimpressed with the lack of language features in Go. Once you get to a larger sized codebase you start caring less about fancy features and more about agility and build times funny enough.
I love Coffeescript and use it whenever I can, for the reason that the compiler output generated by it is better than my own Javascript. I consider the complexity of the added layer to be worth it. 95% of the time Coffeescript saves me time writing, and the 5% of the time spent debugging is made easier with the tool at coffeescript.org. My javascript workflow has only been enhanced by Coffeescript, not hurt. Then again, I don't write large, sprawling programs in Javascript and consider it a smell when it does start getting complex.
I can't say the same about Slim, it hasn't been an unqualified boon, but still overall I feel it's an improvement.
So what does CoffeeScript give me, that JavaScript does not already have? It actually doesn't give you anything. It takes things away from JavaScript, things like explicit variable declarations (I throw "use strict" everywhere these days), and white-space independent syntax. It renames "function()" to "()->". It renames "if(condition)statement;" to "statement if condition".
Regardless of whether or not you like these things, the ultimate point is that CoffeScript, as a language, does not give me anything new, it doesn't provide anything which which I can do things any differently than JavaScript. At least for now, we need to know JavaScript, because there is too much in the wild to be ignorant of it and the transpilers aren't 100% perfect yet (leaving too many cases where you have to inspect the generated code). So why ever bother picking up another language that is, at best, a wash in terms of productivity?
On the other hand, something like ClojureScript (which I don't use, for other, unrelated reasons) gives me something. It gives me a Lisp-like language in which to write client-side applications. I know people say "JavaScript is a Lisp", but try writing good macros in raw JavaScript sometime and see how long it takes you to blow out your brains.
Similarly, TypeScript gives me static type checking, instead of having to hand-write all of my duck-typing checks. A much more explicit syntax for doing object oriented programming. A module system (though I'm not very much in love with require() style includes, I prefer namespaces).
So CoffeeScript won't likely ever be in my toolbox. Curly braces don't make my eyes cross, and I don't understand how they could ever be such a huge distraction to warrant brittle, white-space based syntax. You Pythonistas confuse the hell out of me: what are you programming that to curly brace or not to curly brace is a significant concern for you?
Note that I have no experience with Haml, so I will refrain from comments.
You assume this is why people use Python instead of Jaascript. It's simply what the ignorant latch on to as "different" when they need something to blather about. I make just as many cut/paste errors in Python as I do in Javascript--very few.
I use Python because I can generally count on the fact that it has what I need "built-in". Last example I had about this was that I could open a promiscuous socket and suck up UDP packets quite easily from Python, while doing that in Javascript was a mess. There are lots of little examples like this.
I'm actually waiting for a replacement for all of my current "go to" languages: C, Python, and Javascript. A language that does concurrency well would cause me to leap from those.
And while I don't like white-space syntax, personally, I don't get the general debate as a whole, for the reason you mentioned: haven't made more than a handful of copy-pasta errors in the last decade. It seems like a 6-or-one-half-dozen issue, so if it's being used as a selling point of a particular language (i.e. one of the more substantial differences between CoffeeScript and JavaScript), then it's not much of a selling point at all.
Your last sentence is actually very closely to my point. Yes, the languages we have aren't perfect, but there aren't any better alternatives yet. Give me an alternative and I'll gladly use it. I'm actively evaluating languages as we speak. But I need real advantage to switch from what I'm already using. A handful of regex's in a loop over stuff I already know isn't enough.
This seems like the core of your argument against CoffeeScript, but it's fundamentally flawed. CoffeeScript fixes javascript's warts, eg. it gives consistent scoping rules, simplied/sane classes, list comprehensions, enforces per file encapsulation etc.
You seem to think that CoffeeScript is about aesthetics, but that's probably the least important feature of it.
If you are writing docs, you should be writing JavaScript.
You don't have to use my code, so I'm going to use the tools that I think give the best results.
On the other hand, people learn JavaScript. It's the language of the web. CoffeeScript is something some developers prefer, and others do not prefer. Any CoffeeScript developer can read JavaScript, its native parent, but the opposite is not true.
Therefore, I respectfully stand by my original argument. :-)
What I see here is exactly what I've read in a rather old book (might've been the mythical man month, but not sure): There'll always be those people who don't care to wrap their heads around new ideas, because in their eyes they don't have an advantage. E.g. in the early days, assembly developer could not see an advantage in using a higher-level language such as C (:D), and when FORTRAN eventually came around, C programmers didn't really want to use that either. Why? Because if you spent time and energy on becoming proficient in something, be it assembly or javascript, the defensive but natural position of most people is to be skeptical of new ideas, because they diminish the value of their knowledge. If you're an expert in writing OO-code in JavaScript, and suddenly CoffeeScript comes around and lets everyone write "class" and be done with it, your JavaScript OO knowledge becomes less valuable.
Bottom line, I can hardly imagine anyone who'd be able to learn CSS, JavaScript, HTML and perhaps another backend language, including all the quirks and weirdness associated with these technologies, and then _not_ be able to wrap their heads around e.g. HAML, if presented with proper guidance. The same goes for CoffeeScript, even if the learning curve might be a little steeper than for HAML.
So are these specific technologies good ideas? I'd definitely say "yes" for HAML, and "don't know" for CoffeeScript (TypeScript perhaps?)... For both technologies, I agree with lucisferre:
> 2. Both offer non-trivial gains in terms readability of the written code.
> 3. Both can make future change of code non-trivially easier
HAML is so dead simple that if it takes your engineer more than a day to grok it, you have to admit that they're probably not yet cut out for anything but a junior role. HAML has zero debugging overhead because it's not a programming language; it's just not that hard, period. HAML does add an extra step to the build process, but who cares? It's trivial. In a world where CI and single command deploys are commonplace, the idea that an extra build step would prohibit the use of any developer tool seems absurd. It reminds me of people who argue against unit tests because "ugh, just another tool to learn", or "I end up writing more code in tests than actual code, I just want to ship". God forbid you actually have to learn something. While we're at it, please avoid the use of languages that compile to machine code because who the hell wants to deal with a linker in their build process?
Now, although I'm a huge CoffeeScript fan, CoffeeScript is an entirely different beast, and requires a deep understanding of JavaScript to use correctly. I can understand not wanting to devote time to teaching engineers about the finer nuances of CoffeeScript, especially if they aren't that experienced with JavaScript to begin with. In an ideal world, they'd pick up CoffeeScript as quickly as HAML since in my experience, CoffeeScript creates very readable code, especially when the script makes heavy use of anonymous functions, sadly, it's not always that simple. However, CoffeeScript debugging is a non-issue for an experienced JavaScript developer, CoffeeScript produces excellent JavaScript code that is easily understood. Individuals who like to minimize context changes can use sourcemaps.
Finally, dependencies for both tools are pretty trivial. I'm not sure how the author has managed to introduce 100 different gems into his project in order to support these tools, but it's certainly not a requirement.
https://github.com/haml/haml/blob/master/Gemfile
That's like 4 gems for HAML. CoffeeScript is often distributed as a binary, so zero gems required in that scenario. All in all, I'd say the author's case against these tools is pretty weak.
So, if you're going to be working in a particular environment, be committed and embrace the experience.
I think that if your coworkers won't learn something new that's their problem to fix, not yours.
When these things work they may make your development experience slightly nicer, but when they don't, you'll be sad about it. Just learn Javascript.