Show HN: Hasp – A minimal CSS preprocessor using the M4 macro language
github.com
github.com
M4 gives me flashbacks to nightmares trying to deal with sendmail and configure scripts.
Why did this horrible language become so popular? Why has it not been replaced?
Thanks!
> Why did this horrible language become so popular? Why has it not been replaced?
I don't know. Maybe just like other tools in POSIX systems -- it works :)
I wouldn't call m4 "popular" in the slightest, it's generally used by only a few well-known programs like autoconf, sendmail and SELinux.
It's used because it's a standardized way to bolt on substitution macros to a system without having it be intrinsically aware of them.
Why indeed. I think the answer is because it's available everywhere (at least, on all Unix/Linux). I found myself writing yet another m4 macro only a couple of weeks ago and despairing, again.
EDIT 1: there are alternatives [1] but this is the most well-known. Now I'm intrigued by pyexpander.
[1] https://en.wikipedia.org/wiki/General-purpose_macro_processo...
Paradigm macro preprocessor
Designed by Brian Kernighan, Dennis Ritchie.
First appeared 1977
Major implementations GNU m4
https://en.wikipedia.org/wiki/M4_%28computer_language%29That's a dealbreaker. Especially when you are working with a larger more complicated code base.
OP is learning Y language, wanted to make a project as a goal. Which is all well and good. But thinking its worthy to be shared seems like narcissism, especially when the description for the repository is, "Half-assed CSS preprocessor." And with 12 commits from the last 5 months, 3 of those being actual code, this isn't a serious project.
This is showing off homework. Though I suppose everyone seeks validation.
I'm not saying the tool I wrote will replace all preprocessors. My point is: I wrote one with just enough features in around 30 LOC. Can we use that to start a discussion around the current state of the art regarding frontend tooling? Or software in general?
But to each his own, of course!
But if you define bloat as "inclusion of features I'm not using," the Node ecosystem is lean and mean. If I only need 15 of the 250 functions that Lodash provides, I can include each of those 15 functions as an individual package. Yes, it increases disk space, because each dependency ships a package.json and a README and subdependencies aren't shared, but disk space is cheap. Decreasing the surface area of my library dependencies is worth it for my development happiness.
I think the criticism you want is "ultra-modular." You can make an argument that Node's proliferation of tiny, one-function packages is a maintenance burden and causes discoverability problems. Personally, I disagree: any effort to move towards a world where you never have to write a line of code someone else already has is well worth it. And from an end-user perspective, it shouldn't matter at all. `npm install` on average takes no longer than `gem install` for me, despite NPM pulling in orders of magnitude more packages.
(Python might be bloated; have you ever looked at the complete stdlib? There are some horrifying pieces: urllib2, email, turtle (?!).)
P.S. Check out libsass [0], a re-implementation of Sass in C with [probably] bindings to your favorite programming language.
Also, easy != simple. The fact that a tool is easy to install (after having installed another mega-dependency) shouldn't count as an advantage, in my opinion.
Trac(tm), on the other hand, had an important booster, it was promoted in Ted Nelson's 1974 cult classic Computer Lib, one of my treasured historical CS books that I bought in grad school the first time around. Nelson (famous for inventing hypertext, the notion of embedded active links decades before HTML) wrote that "You can and must understand computers now." He suggested learning three languages: BASIC, TRAC, and APL--all languages that he felt you could learn on your own. Trac, and the remarkably similar GPM, are very simple. I've implemented Trac-like systems several times. It's a fun project to implement in an afternoon when learning a new programming language.
What made these two languages interesting is that they are equivalent to a Turing machine and hence capable of arbitrary computations. Furthermore, they really aren't impractical to use (but see my comments below). If locked in a dungeon by an evil genie and forced to write a real program on bare hardware before I could be released, I would certainly consider developing TRAC or GPM as the first step (or maybe FORTH).
m4, developed by Kernighan and Ritchie in 1977, looks like it was inspired by GPM. It's been a useful tool for me a number of times, but it is good to not let it's generality and flexibility suck you into outsmarting yourself.
The power of these macro systems (and TeX's as well) comes from the arbitrary rewriting that they enable, a bit like Chompsky's Type 0 (unrestricted) grammars in his hierarchy. These macro systems, once popular, have now fallen out of favor. Although almost trivial to implement, programming in them is a bit like playing Othello, it's hard to see very far ahead: what will unfold when a macro that will be expanded is passed arguments that will be re-expanded.
Sendmail's configuration files are processed by m4--seemed like a cool idea in the early 1980's--but that made it hard for non-experts to understand what was happening.
Thanks for sharing this. Really made my day.
I also learned about http://entrproject.org/ through your README.md . Being stuck on OSX for work, this looks very handy. Thanks!
That said.
> Anyway, they all require Node.js, a huge dependency for this simple problem, in my opinion.
While I personally agree with this opinion, isn't it typically the case that a frontend dev's workflow already heavily relies on Node? It's probably already installed for all that Wangular.js nonsense, so it being tacked on to one of the heavier CSS preprocessors probably doesn't make much of a difference, no?
This would be most helpful for those who still haven't introduced Node as a dependency and trying hard to get away without it :)
In any case, as I mentioned in another comment, the fact that one can write a minimal preprocessor in ~30 LOC could be useful to start a conversation about the current state of the art regarding frontend development.
libsass is amazingly fast. I generally see it churn through ~20k lines of CSS (don't ask) in 6ms.
That said, Sass encourages practices that I consider bad. Nesting, @extend, etc.
Sass's design also makes it difficult to implement a basic feature like grouping all media queries for a single output. Check this issue from 2011: https://github.com/sass/sass/issues/116
If you don't mind a bigger tool and the dependency on Node.js, then PostCSS looks very good: https://github.com/postcss/postcss
Representing hierarchy in the class name makes the output shorter, in most cases, and makes the HTML and CSS code easier to understand. For instance, when you see <div class=title>, you need to go up to find context to understand what that "title" class is. If you have <div class=widget-title>, that's much better. Let alone that generic ("title") classes can lead to problems with conflicting rules depending on their specificity.
By the way, classes at the top level are faster to parse and apply.
This articles expands on some of these issues: http://www.sitepoint.com/beware-selector-nesting-sass
Thank you!