$20k bounty was claimed
prettier.io
prettier.io
I was indeed wondering that but the answer doesn't really answer the question for me. Why not set a bounty to improve Prettier instead of building a competing project just to increase the motivation to improve Prettier? Or is the end goal to shut down the Prettier project and encourage people to switch to the Rust based one? Seems like an unnecessary fragmentation of an already confusing landscape.
Maybe I'm misunderstanding something though.
Less "the team" per se, and more vjeux, I think.
I think it's about escaping local minima? You can always look at the biggest sink for performance and say "there's definitely something we can do better in there" but unless you have something objectively better to compare it to, you'd never be sure.
Imitation is the sincerest form of flattery. And knowing that of the hard problems you solved, someone else can solve them and in a different language, I think there's quite a bit of value to be obtained just through the competitive process that emerges when there is competition.
You can't fully have competitiveness without an actual alternative to compare yourself against. If the Rust folks can do the problem slightly faster by shaving off just 5% or less of the test suite, what all does that tell us about the theoretical limits of a solution when compared against the canonical version?
I have only limited understanding of the problem space, but I think there's always something intangible to be gained from having a quite similar implementation in a different language.
Yes. It’s also been said (not often enough) “if we don’t compete with ourselves someone else will”. Getting out of one’s own head (and repo) is gold. It shows humility and respect as well as creates innovation and resilience.
https://biomejs.dev/formatter/#differences-with-prettier
Turns out Biome found several pain points that they chose to not follow the same decisions than Prettier, instead diverging from it. This alone could be already a reason why a parallel development is worth it.
Presumably the creators of the bounty believe that this bounty is in fact a good way to directly improve Prettier. The acceptance criterion of the bounty doesn't need to literally be "improve Prettier" for the work to improve Prettier.
My own experiences with open source suggest that no one would stick around for very long if they were motivated by fame or wealth. Being a FOSS maintainer seems to be a constant exercise in dealing with people whining at you for not fixing their problems for free, not something that brings any significant personal attention and certainly not something that provides a sustainable source of income.
I think that a lot of projects would be a lot better if they insisted on not solving everything, and stuck to solving one problem well, and instead of merging every new feature on offer instead help make it easier for others to "compete" with them by e.g. separating out shared functionality or writing about lessons learned...
I'd love to find each and every one of my projects are no longer needed because there's a better option (now, I may be very difficult about what is "better", so that's a tall order), because my list of projects I'd like to pursue is longer than I will stand any chance of getting to in my lifetime, so if some are taken off my plate, awesome...
Age for example always has someone complaining about a feature they want - the refusal to oblige is exactly why it's a better product than gpg.
Of course I'd love to learn rust! But, for the most part, I just need to get stuff done so I'd prefer to stick with what I know and can mod easily and leave the "learn an entire new language" part for something that actually needed that language.
Those are the two main things that rust is expected to help improve.
It's quite easy to empathize with somebody that sees a JS software having problem with those two and picking a language that is known to help with those instead of being known to increase those problems.
There are three reasons, I think:
1. Writing a rust compiler is separate from prettier project because of its nature. Prettier is not written in Rust, and Rust has proven to be a robust option to write a formatter, so the goal really is to write a formatter in Rust itself, and it can't be replaced with improving prettier within its current codebase
2. Asking someone to write a Prettier-branded and owned Rust compiler for $20k is not enticing enough. It is essentially equivalent to contracting someone to write some code for Prettier, with an open bid. It would cost a lot more to hire someone to write these code. Great programmer who has the skill to answer this bounty get paid at least $200 an hour (extremely conservative estimate), $20k is enough for 100 hours of work for one person, not enough to finish the project. But getting rewarded for $20k for stuff you write and will own is enticing!
3. Good ecosystem going forward. If prettier owns the winner project, prettier is responsible to maintaining and improving it. The good that the bounty did ends when the project is handed over. Prettier team get burdened with a project that they didn't write themselves, and the original team (the best people for the job) is not incentivized to keep maintaining it. There is no ongoing competition to keep this field active.
Dang! What do you base this estimate on? The Rust aspect, or parsing aspect, or intersection of both?
What I'm trying to say, I don't see the correlation between having a huge hourly rate vs family time. 40 hours a week of work is still 40 hours regardless of how much you're paid.
When I was doing pricing for service contracts it was usually around 1.50:1 burdened billing rate vs direct labor (income)
232/1864 is a base increase of 12.5% for PTO
Payroll taxes, Medical, workers comp, etc add about 30% - though medical is flat so at higher wages like discussed here the % increase it represents goes down further
I did not have to factor in increasing skill on the job or time between jobs - but I did have to account for overhead and g&a which would be similar to time between jobs since those would be for bills
Big companies would have a lot of markup on OH/g&a/fee, but a software dev working remote for themselves on contract could competitively go down to 5-10% or less here to simply cover the minor added burden to bills.
That totals up to about a 50% increase on the salary rate. You can't outright bill someone for time you spend looking for a new job or improving your skills. You may charge a premium that you use to do such things but that would have to go under fee which tends to top out at 15% with the government, not something that can be expected to be accounted for. In my experience at least.
Again though, this was for service contracts - particularly with the US government, subject to certified cost and pricing data disclosures.
I was genuinely curious about the 2.5 number though, as i have spent a lot of time dealing with market rates in various conditions I was interested to know the context. I could see a few ways that could happen, but I wouldn't want to speculate too much
I always used 2x, but probably 2.5x is a sensible way to think about it in a patio11 "charge more than you think you should" mold.
This is less true following the Affordable Care Act than it used to be. The unsubsidised marketplace rate for my Kaiser health insurance seems fairly close to what I pay for COBRA from my former big tech employer.
My Kaiser almost doubled from COBRA and coverage went from better-than-platinum to high deductible gold.
Google / SF market.
Age makes a huge difference to the marketplace premiums though.
Being a subject matter expert means that you can be paid well for your work, but the numbers of jobs that require expertise in the Kura-Aras river basin can be few are far between.
As a datapoint, the average Dutch contracting rates I see for IT development (think: Java, Swift, Kotlin) range somewhere from €75 - €150/h. Higher is possible, but then you're talking very specific expertise and typically shorter projects.
I'm on the hiring side, this is a figure across some 20 external devs. I think it's representative of the middle of the market.
It's not a perfect comparison/analogy, so I'd rather not get nitpicked, as the overall thrust of my argument is that $200/hr is not outlandish imho.
I once had some contractors in my team that were paid $500/hour due to vendor markup. I consider that extravagant.
It varies though, the market also exists for $80/hour java developers, which tend to be new grads
Contract Developers going to technical companies will earn more like $180+.
i have been a contract developer, and have worked at technical companies in canada, and have never seen rates that are even close (and im not a jr / have never used java for work outside of small amounts for mobile.) there's no way these rates are as common as you are all making them out to be, unless it's some niche, or you're talking about extremely short contracts, or there's some other missing piece of context
These rates are at financial services , banks, transportation / logistics, manufacturing, telecom, etc. in Canada, US, and Japan.
You should read patio11's posts on this topic on HN or his website, for example : https://www.kalzumeus.com/2012/09/21/ramit-sethi-and-patrick...
So if you hire an agency to perform a contract, they'll bill you $2000 per day and send you their employee who makes $100 an hour. Agency pockets the $1200 (it's a simplification, but should paint the picture).
Freelancer and agency both run the same business model. If you think like employee and charge extravagantly less, you will never grow.
You should typically charge enough, so that for any given project you could hire an employee to do the work, while you look for new leads or you can keep the money in the company and do the work yourself until you amass enough capital to move up the business ladder.
There's reasonably good data about this that contradicts this?
$1000 as a day rate isn't unusual or unreasonable for a specialist IT contractor; and I don't say that idly; I say it from both experience and you know; aggregated data:
- https://www.hays.com.au/documents/276732/1102429/Hays+Techno...
- https://www.itcontracting.com/rate-checker/
- https://news.ycombinator.com/item?id=32606348
Yes, if you want someone to slap a php website together (or javascript, or many other entry level frameworks), you can pay less.
...but that's not what they were asking; they were asking for a technically sophisticated analysis of an existing project and a performant re-implementation in rust.
They got a bargain.
That's a good question. But a new, Rust (or whatever is fast) version of prettier is effectively Prettier. If it has the same config, switches, and defaults, it's Prettier.
The value of prettier is that it's a standard most of JS/TS agrees on, saving discussions for more important topics. The code that gets us there is a side effect.
Basically I'd assume, if a project targeted at JS, switched to rust, the number of useful pull requests would be 50-100x less.
I wonder if anyone has any data on that (and similar projects re-written in C++ or Go etc...).
Furthermore, projects like Ruff show you can have a lot of contributors for projects like this. Maybe because there are lots of devs who use TS or Python in their day job, but want excuses to use Rust on the side.
But performance is a field that's really hard to accurately measure as there are so many variables, machines, benchmarks... You can see this in the JavaScript ecosystem where every project says that they are faster than the other one and they are in practice all right depending on which benchmarks they use.
So, creating a big bounty with something that's very hard to accurately measure is likely not going to work out very well.
In practice in the ecosystem, the Rust community really cares about performance. So it feels that this is the right audience to build something really fast. But, so far, none of the Rust-based printers were even close to outputting the same thing as prettier. They all decided to implement a different set of options, made different design decisions...
So every time somebody mentioned using one of those, I was getting annoyed that I would --love-- to recommend them, but it wasn't going to be the same. And I believe from experience that one of the main reason Prettier has been so successful is because of this --very very very very-- laborious last few percent of edge cases.
So goal #1 is to convince at least one of those projects to start being compatible with Prettier so that we had a viable alternative. In practice, there was no way I could talk to them directly and convince them to align with Prettier. So the idea of the bounty came to be, if I made a bounty big enough, it would be a way to convince them to do so (and it worked!).
The bounty to work needs to be very easy to test (percentage of tests that pass is very easy to test), cannot easily be cheated (unless you run prettier itself, you need to go through the laborious work of doing the same logic) and cover real world use case (all the tests were added over time based on using it in prod). It also mentioned a "project" and not a "person" to encourage collaboration.
It's a bit unorthodox but I've learned my lesson with code formatting that people are obsessed about discussing this topic so you need to find alternative ways to convince them.
Now, going back to Prettier, I've been very annoyed that nobody had looked at performance of the project since after I stopped working on the project. For example, I wrote a way to keep the prettier process alive for editor integration instead of paying for the startup cost every single time https://github.com/prettier/prettier-rpc and nobody used it. I needed to find a way to convince people that prettier's performance actually matters.
One of the most powerful way to get people to improve performance is to have two competing offerings battling against each others. We've seen this very successful between JS engines, JS frameworks... But, due to the success of prettier, there was no competition, the JS Survey admins even stopped asking about it because it was the only choice.
So having a proper competitor which is faster and uses a relatively controversial language, was a good setup to get a competition going. And it also worked, since the bounty was announced, Fabio Spampinato got nerd snipped thinking he can make the JS version faster than Rust and has been working every day profiling and rewriting the Prettier CLI to be orders of magnitude faster. We are using the open collective money to contract him to work on this.
Outside of performance, by having another group of people work on the same tests, they uncovered a lot of broken behaviors and edge cases on prettier that should be fixed.
Last but not least, having a bounty incentivizing another project was intriguing enough to generate a lot of discussion and therefore receive a lot more coverage than just asking people to work on your project.
----
So, overall, it achieved all the outcomes I wanted: by the end of the year, prettier itself is going to be a lot faster, and we actually have -less- fragmentation in the space where the other big project is now aligned in terms of the way code is formatted.
Would have I been able to spend $10k more effectively, I can't think of how. But I'm pretty sure I'm missing some better strats!
> By matching all the tests, the Biome project also found a lot of bugs and questionable decisions in Prettier that we will be able to improve upon.
For me, this means that they have another implementation for sanity checking their own.
This will help to bring maximum speed to formatting Javascript thanks to Rust, following the ruff (Python formatter) trend.
Just as a note, as it was not mentioned in the article, Wasmer [2] also participated with a $2,500 bounty to compile Biome to WASIX [3], and it has been awesome to see how their team has been working to achieve this as well... hopefully we'll get Biome running in Wasmer soon!
Also congrats to the Algora team, as they have been doing very good work with their landing and trying to help on the challenge moving forward [4].
Keep up the great work!!
Imagine you can safely assume that the formatter program will only have access to the directory you provide, and not anything outside of it (not even the network!).
In summary, Wasmer + WASIX is like Docker, but much more lightweight :)
We are not trying to push WASIX, we are trying to move forward sockets, threads, subprocesses so they can run fully in Wasm environments. And WASIX is the solution to that problem.
WASI Preview 2 on the other hand seems to be focused on other set of problems and doesn't solve any of the needs that got WASIX started in the first place.
So, in light of that, what is the reason for diverging from WASI and creating WASIX?
WASI Preview 2 still doesn't support threads, fork, subprocesses or longjmp/setjmp (among others). Not even that, when WASIX was created not even sockets were supported in WASI.
I'd recommend trying to compile bash or curl to WASI Preview 2 and WASIX and see how far you get in each before trying to polarize the readers between WASI Preview 2 and WASIX.
Just for you I did some googling: see here[0] for the current status of WASI threads overall, or here[1] and here[2] for what they are up to with WASI in general. In this PR[3] you can see they enabled threads (atomic instructions and shared memory, not thread creation) by default in wasmtime. And in this[4] repository you can see they are actively developing the thread creation API and have it as their #1 priority.
If folks want to use WASIX as a quick and dirty hack to compile existing programs, then by all means, have at it! I think that's great. Just know that your WASIX program isn't going to run natively in wasmtime (arguably the best WASM runtime with the strongest long-term outlook), nor will it run in browsers, because they're going to follow standards.. not WASIX. I don't think anyone believes exposing POSIX fork() to WASM is a good idea, even if it lets you build existing apps 'without modification'.
Please stop accusing me of being polarizing. I just don't want to live in a world with two competing WASI standards, two competing thread creation APIs, and a split WASM ecosystem overall. I want good tech to win, not shitty power plays.
[0] https://github.com/bytecodealliance/jco/issues/247#issuecomm...
[1] https://bytecodealliance.org/articles/wasmtime-and-cranelift...
[2] https://bytecodealliance.org/articles/webassembly-the-update...
[3] https://github.com/bytecodealliance/wasmtime/pull/7285
[4] https://github.com/WebAssembly/shared-everything-threads
WASI Preview 2 doesn't officially support threads. There are some ways to get it running as you mentioned, but threads are NOT part of WASI Preview 2. Which is what you initially stated and I corrected.
We don't want to have competing standards either, and we'd love to merge things upstream. However, based on my interactions with the WASI subgroup it seems clear they want to keep some of this things that WASIX needs out of the spec (and that's ok!). If you would not like to have that, then you shall probably direct your requests towards them, not us.
> I want good tech to win
Me too! I now understand this over-idealistic belief is the root of the issue. Good tech doesn't win, a good product does.
I wrote more about this, if you are curious, here: https://wasmer.io/posts/is-not-about-wasm-is-about-what-you-...
WASIX is a hostile fork of an open standard that does care about sandboxing.
I'd love to hear your thoughts, maybe we are missing on some nice business opportunities here!
I find it hard to believe that anything you would spend your company's time on would not push the mission of the company forward. This creates a financial incentive.
We don't plan to monetize WASIX. WASIX is just an enabler to allow any program compile to WebAssembly. If other open-source technology existed and fulfilled what we want to accomplish is more than certain we would not have created WASIX.
In our case, the community was asking to have sockets, threads, forking, subprocesses and more fully working on Wasm. And there was nothing that supported that (or that aimed to support it), so we worked on it.
Now, let me give more insight on what we actually plan to monetize: Wasmer Edge [1]. Wasmer Edge is the alternative to the expensive big-tech providers that allows any person or company to host their websites at a fraction of the cost.
Hope the insight was useful!
Meanwhile, Bytecode Alliance is a registered non-profit with many large corporate backers. They are building out the WASI standard with careful due diligence to learn from and avoid the mistakes we have found in POSIX. BCA has their own financial incentives, and they are aligned differently than yours.
BCA ultimately is moving slower than works for Wasmer. So I guess you were faced with three options: A) wait for BCA, and do nothing B) work with BCA and push it forward C) fork it and do it yourself.
So you chose to fork it and reimplement POSIX with all its warts. I assume because this applies pressure to the community (candidly, a good thing) while letting you make progress immediately.
Where I, and I assume others, have issue with all of this is:
You have chosen a name that has created confusion in an already confusing space.
You have whitewashed it by promoting it as a new open standard, but the controlling entity realllyy is just Wasmer[0].
You have demonstrated through your actions a complete lack of willingness to work with people in the community, preferring to strong-arm with veiled threats[1] or perverting incentives financially[2].
The issue isn't with WASIX, but with you and your actions. I have no confidence in your ability to lead this community forward in a way that has my (our) interests ahead of your company's.
[0]: https://github.com/wasix-org/wasix-governance-meeting-notes/blob/5135516d091d1bc3810677ea2cc755a67e10c669/meeting-notes-27-07-2023.md#meeting-attendees
[1]: https://github.com/bytecodealliance/wit-bindgen/issues/306
[2]: https://github.com/ziglang/zig/issues/17115Is refreshing to see at least some honesty. Haters gonna hate, so I personally don't mind. Have a great day!
Hope you have an awesome day
If you dismiss all criticism of your behaviour in this way, you'll never gain any insight into why so many people find your behaviour so objectionable.
It's not because "haters gonna hate". It's not because you're operating in a competitive and highly visible space, and so of course you're going to receive some "hate", or whatever other dismissive narrative you might have cooked up. Look around you: people in similar positions just don't generate the reaction that you do.
When Wasmer eventually folds, it will be your fault, because you refused to reflect on how your antisocial behaviour destroyed all trust in the brand.
I don't know how to stop that from happening. Maybe a good therapist could help? Heck, your board would probably even be happy to pay for it, given the potential upside for Wasmer.
A hater, for me, is someone that lacks of constructive criticism.
"Have curious conversation; don't cross-examine."
"Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith."
Under this interpretation, there would still be a financial incentive, but it would not be underhanded.
The broader context of Syrus' actions within the community (which reflect on Wasmer as its CEO) are what raise concern for me.
I'm incredibly happy to hear that
But the main difference is that it has sandboxed capabilities (similar to docker), do you can granularly add permissions to only certain directories or even disable networking when running.
For the same reason, it often makes code written using composition more difficult to read since it won't let you decide when to put a sub-call on its own indented line for clarity.
I do this occasionally, and especially with things like test tables. Linters/formatters are there to help in the common case, not to be some oppressive dogma.
I am sad it's not getting more popular
Prettier doesn't break template literals, but it will break non-literal sections of template strings. For example, if we wrote this:
const foo = `aaaaaaaaaaaaaaa${bbbbbbbbbbbbb}ccccccccccccccc${ddddddddddd}`;
prettier would fix it to const foo =
`aaaaaaaaaaaaaaa${
bbbbbbbbbbbbb
}ccccccccccccccc${
ddddddddddd
}`;
Which is not only much harder to read in it's own right, but now takes up 6 lines instead of one!Just needs another maintainer's stamp.
It treats new lines as significant in a lot of its formatting
How do you even justify that...
I think rustfmt will actually also widen code you have put newlines in sometimes. But it's heuristic is somehow much better than prettier's.
So the whole "extremely opinionated, if you want configuration go somewhere else" is great in principle, when people are choosing to use the tool. But if it becomes the only option for certain swathes of users, a touch more configuration would really be appropriate.
Besides that, I get the impression being a universal standard is kind of a non-issue for Prettier:
- If it was widespread, but highly configurable, that increases friction when switching projects, because there will be tiny formatting differences everywhere
- If it was not widespread, it would not be well known, increasing friction for users entering a project where it was used
Erm, that bounty was for the production of a program that behaves exactly like prettier in at least 95% of cases, as far as I understood what "prettier test suite" means.
This is clearly not true. Far and away the single most contentious JS style issue is ASI, and prettier has a config option for it and nobody bats an eye. Ditto for the prototypical style issues of indent size and tabs/spaces.
The value of prettier is enforcing a consistent style within a repo, and config options don't affect that. To the contrary, config options are part of why prettier is so popular - if they'd never added ASI then a lot of projects would never have adopted it.
If prettier worked more like gofmt I'd probably love it and have no complaints!
Wait, so prettier rewrites code incorrectly? Aka, it’s buggy?
This the same code, but I often use parens for semantic grouping or to be 110% sure the operator precedence is correct for a particular formula. It's not a dealbreaker, but it does remove some of the meaning I was trying to imbue on the code.
// before prettier
var matrix = [
1, 0, 0,
0, 1, 0,
0, 0, 1,
]
var result = (num % divisor) | bitmask
// after
var matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
var result = num % divisor | bitmask
No difference in actual behavior, but the linebreaks and extra parens were there to indicate the developer's intent, not to affect behavior.Prettier's outlook is that this is intentional, and the developer should add "// prettier-ignore" comments to every line of code that has semantic information they want preserved.
Prettier will affect your diff in ways you didn't intend to.
Remove a member from a destructuring assignment that brings it below the line length limit, and suddenly your diff is +1/-5 instead of 0/-1, making it slightly more difficult for your reviewer to see what the exact difference is between those 5 lines removed and 1 line added - it's not immediately clear which member was removed.
You try to rewrite a previous commit to fix a typo using Git's interactive rebase, and now the next commits won't replay on top if it because Prettier decided to reformat an entire code block.
Another fun thing to try with prettier: add a precommit hook that runs prettier, and then try to stage partial file changes.
No thanks.
But that's the purpose of such tools: to stop endless debates about style.
Does it? IME/O, styling only matters up until the point that it is consistent and reasonable. And I'm saying this as someone who used to want to debate and micromanage a lot of formatting standards in my projects. Ego is removed from the equation (unless you're the one trying to introduce Prettier to a reluctant team), and without ego, the debates no longer seem very important.
No, not really. Many of the decisions prettier makes are quite objectively bad for readability from first principles (e.g. breaking up lines where the RHS isn't relevant to most readers, left shifting RHS of assignments when the implementation details are less important than the abstraction over them).
I am totally in favor of a universal formatter, but at least justify the design decisions being made. Prettier formatting choices are often very lackluster and hard to defend objectively.
It will be replaced by something better eventually
I can imagine smaller teams/single individuals being very picky about how their code looks and there is nothing wrong with that. Once you have larger teams that becomes a waste of time since you'll likely have much larger problems to solve.
This is an oft-repeated myth. There are some style rules for which that is true, but for some, there are objective, logical reasons to prefer one style over the other.
For example, mandating the optional comma after the last time in a list whose items has been split over multiple times results in more readable and logical patches: if you mandate the comma, a patch that only adds items will only have added lines, whereas if you don't, a patch adding items can have a mix of add/remove lines.
Pushing operators to the subsequent line makes it fundamentally easier to read as they all align, vs. a ragged right edge, and this is doubly important if the operators aren't the same, as it makes that far more visible. (Though this is harder in some languages with odd behavior around this, such as JavaScript.) (This also affects patch readability in many languages, and in fact, I'd say patch readability is the driver of many objective reasons behind styling choices.)
And so forth. I'd wager as many rules have logical reasons backing them as those that actually do boil down to literally just stylistic decisions.
For interactive use we really should be using long-running, warmed up, processes too, where the start time of Node is irrelevant. Ideally type-checking, linting, highlighting and formatting would run in one language service doing incremental parsing and updates to a shared AST on every keystroke.
I think this is the reason Biome (originally called Rome) started. Rome's vision was a shared toolchain to yield better performance and to fix config hell.
On November 9th, we put up a $10k bounty for any project written in Rust that would pass 95% of Prettier test suite."
I don't see how better performance follows from the fact that something is written in Rust. One could have simply transpiled the existing codebase into Rust, and collect the reward.
Why didn't you, then?
But I'll do it for you, if you put up the 20k USD. Will you?
> There's a lot of fast web tooling being written in rust those days. https://twitter.com/Vjeux/status/1722769322299609565
I don't buy it. I think vjeux is riding the hype.
I'm not sure if this is already an internet saying somewhere, but whenever I read the word "simply", I assume that whatever comes next won't be simple, because if it was actually simple it wouldn't need to be qualified.
In this case, I don't know that transpiling a JS codebase to Rust is simple. The mental models, the libraries used, the way that code written is quite different between the two languages and I doubt that JS-to-Rust transpilers are robust enough to be used on a codebase the size of Prettier, if such transpilers even exist at all.
Idiomatic Rust will often by 5-10x faster than very similar looking JavaScript/TypeScript code without even trying to optimise it. It depends what you're doing, and this doesn't always apply. But parsers where you're doing a lot of string manipulation are one of the cases where it definitely does.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Forked because sebmck seems to have gone AWOL over the last year or so and contributors were unable to update many of the project's resources as only he had access. Hope he is doing ok though and glad the Biome project seems to be going strong regardless.
They claim 25x but the numbers are old so I'm not sure if I believe them now that a bunch of new functionality has been added. Either way, if it's anywhere within that ballpark it's still a huge achievement.
Webpack repository:
Biome ran
2.19 ± 0.11 times faster than dprint
4.18 ± 0.14 times faster than Biome (1 thread)
32.12 ± 1.18 times faster than Prettier
32.45 ± 2.56 times faster than Parallel-Prettier
I am not sure why Parallel-Prettier is slower than Prettier for the webpack repository.Prettier repository:
Biome ran
1.89 ± 0.21 times faster than dprint
3.47 ± 0.34 times faster than Biome (1 thread)
36.70 ± 3.41 times faster than Parallel-Prettier
46.66 ± 4.32 times faster than PrettierThis is a common sentiment in the fullstack community right now.
Strange.
Also, I had to check the winning implementation just for sanity’s sake. It is older than a week or two. Still, my hats off to them for being able to meet the compatibility mark and get the cash.
At my last job, we had a lot of fun with Prettier. We basically made our Typescript codebase look as much like Go as possible. I am not sure this is a particularly valuable endeavor, but it was fun. So if people are willing to spend $20,000 on making that faster, whatever. They can have that fun, I guess.
- I sometimes prefer lines to exceed maxLength (ex: template string, which prettier would horribly break on vars)
- allow `1 + 2 * 3` or `a || b && c` to be parenthesis-less because everyone know the precendence here
Prettier doesn't break a long template literal though...?
> allow `1 + 2 * 3` or `a || b && c` to be parenthesis-less because everyone know the precendence here
"Everyone knows" is usually an unwise assumption. And adding parentheses does make it easier to read even for people who know their order of operations.
const foo = `aaaaaaaaaaaaaaa${bbbbbbbbbbbbb}ccccccccccccccc${ddddddddddd}`;
prettier would fix it to const foo =
`aaaaaaaaaaaaaaa${
bbbbbbbbbbbbb
}ccccccccccccccc${
ddddddddddd
}`;
(or something similar) and it would be fully equivalent.I don't like it doing that either tbh but hey prettier is good enough in most cases its worth putting up with it
Just needs another maintainer's stamp.
Can't say prettier performance ever bothered me, but if it can run faster and leaner I'm all for it! Increase my battery life :D
In general it's really exciting to see the advancements in JS tooling, the quick successions of tooling in JS might be controversial, but I love it. Each step was a significant improvement over what was there before, and the current Rust rewrite wave has already given us great tools that I use daily.
I also like that there is some money being thrown at the problems!
Edit: See a contrived example of something gofmt doesn't touch (the behavior I want): https://go.dev/play/p/cKMKnFwT8tq
80 characters is a really good default. I have an extra wide monitor, and with 2 side panels open in my IDE, that's the perfect length.
I think we can all agree there should be a line length limit, it has to enforce it eventually. You could say “it’s just a couple more characters” until the line is 200 characters long.
Semantic diff is maybe the solution.
Last time I looked into it, the only reason I can't turn it off is that Prettier works off an AST that doesn't keep the line breaks that the user put into the code at all, and it "rebuilds" the whole code from this AST.
The problem is not the diff per se, the real problem is that I can't find a configuration of Prettier where I can have long lines where it makes sense and short ones where that makes sense.
Also, this means that there is more than one way to format the code, which stands pretty weird given the philosophy of Go.
- kilometer-long lines makes your eyes travel a lot more to read what is happening. travel is not that an issue, but context is. it is quite hard to get at a glance e.g. the argument list of a function. or know if e.g. a specific parameter is in the argument list.
- I almost never have my editor's viewport set to kilometers. It's usually in the ~110 chars range to fit multiple files at once (two side-by-side on 1080p, three on 1440p). Not that I am editing three files at once, but I'm usually editing the middle one with other files on the side for context and reference. In such a setup, the line ends up wrapped anyways, but with ugly wrapping that does not match indentation and in the middle of words.
As for hiding it, that's what editor folds are for.
Anyways, I guess we found bikeshedding topic not solved by formatters :D
If you want a line to be shorter because you as a human find it easier to read that way then you can add a linebreak yourself, and trust that your meaning will be preserved.
I really miss that gofmt applied some limit to line length. In TS I just write a too long line, and Prettier reformats it into a sensible set of consecutive lines, I don't even have to think if breaking before or after this or that parentheses or bracket. With Go, I have to, and I'd rather not.
Around 100 is a sane minimum while 160 is a sensible upper limit. There's no specific limit other than to prevent poor coding technique, illegible code, or inclusions of generated or minified atrocities.
Wondering what company would NOT be using prettier. Not many.
Some arguing that Prettier isn't foundational piece of software, I'd consider automated consistent readability enhancements as foundational though.
Am I missing stuff?
Are they planning to run Rust in the browser? Or make some sort of node module that calls down into rust?
Prettier is run mostly on the serverside though, not the browser. I assume supporting both is still desirable though
I don't think prettier is intending to do that in this case, they seem to want to continue to compete as a pure JS implementation but having a "worst case, we WASM wrap biome as the future of prettier" possibility opens up future opportunities and pushes "internal" competition.
when i'm in the thick of it working on a piece of code, writing some logic and have everything laid out the way that makes sense to me and then i hit cmd + s and BOOM all the lines get shifted and wrapped and i'm ripped out of my flow i wondering what the heck it is i'm now staring at. sometimes i disable prettier on save and just run it on a pre-commit hook because at that point who cares that the code is unreadable to me.
Would it be realistic to expect a solution for this issue now that "prettier needs to step up it's game"?
It's annoying, but not a reason to throw the baby out with the bathwater.
But, as well as the issue with line noise, it also encourages patterns that I think detract from code comprehension. It favours expressions over statements and even now, it’s not easy to set a breakpoint in the middle of one, so you end up rewriting into statements just so you can step through.
It will favour deeply nested ternary statements in react so your code reads more like a tree with densely tangled roots.
It will favour shorthand syntax for optionally merging properties into an object, which basically relies on a quirk of the splat operator.
There is fuck all standard library to speak of without pulling in an insane amount of dependencies, but surely stuff like deep merge and compact should be provided out of the box?
I've never had an issue setting an inline breakpoint[1] in VS Code, is it an issue in other IDEs?
[1] https://code.visualstudio.com/Docs/editor/debugging#_inline-...
(Most people I know just use console.log - print debugging works all the time but I like having a repl)
That's the opposite of what they claim: https://prettier.io/docs/en/option-philosophy
Isn't this an issue with every linter? At some point you're going to have to decide what to do with old code that doesn't match the new style rules.
You will - every time you extend a line which now exceeds the limit.
- filter: /\.(jimmy|jimbo|jeremiad)$/
+ filter:
+ /\.(jimmy|jimbo|jeremiad|james)$/
. And it's not clear where the change is. GP's article has an example of that in a linked tweet.If you prefer a CLI tool, check out https://github.com/Wilfred/difftastic. It supports more languages, but doesn't recognize when code has been replaced by an equivalent version ("invariances"). So it will show some changes (e.g. replacing a character in a string with an escape sequence) even though they are technically equivalent.
So we'd end up discussing what is the best choice. I bet I'd also end up discussing those things with Anthony Fu. If the limit is 80, then the limit is 80, not 81.
Come Prettier. No more discussions. I definitely buy the tiny amount of "noise" it brings, in exchange for freeing me from an immense amount of actual noise when having to discuss these things with other people.
EDIT: This comes from a backend dev (C/C++, sometimes Go, recently did some stuff with TypeScript). Prettier was a refreshing discovery, and other languages like Python are able to express the rule very sensibly (albeit I round it and go for 80 or 100):
I agree with that. But the limit should be 120 or 160, not 80 (and my formatter should allow me to set a wider limit like that without making all my lines extra-wide - I want to be able to put things on one line where appropriate and not where it's not).
> I definitely buy the tiny amount of "noise" it brings
Tiny? It makes a lot of my code 3-5x as long. And often breaks things in weird places. This is IMO not a small reduction in readability.
I get it, 160 looks OK and fits into a 4K display without any other windows open. I believe working with dual panes is more productive, so I'll always stand behind shorter line lengths that allow for it.
Even Rust, a modern language that is usually said to collect the best learnings from the industry, thankfully chose a conservative and sensible 100 chars limit by default.
My least favorite though no limit + soft wrapping, the philosophy being the code adapts to the user, but in actuality means the file looks completely different based on your monitor and setup removing visual aid to code navigation and familiarity.
Do you mean entire files are made 3-5x as long or just individual lines every now and then?
On my screen with 1920x1080, 2 side-by-side panels can fit 100 chars, but only if the sidebar is hidden (project layout, list of open files, that kind of stuff).
On my laptop, 2 side-by-side files won't fit if they exceed 90 chars.
I just don't want to concede to those devs who use a single editor pane with an ultrawide monitor, and believe that everybody must work like they do.
I think discussion on the perfect limit on public forum is non-sense. It might be slightly less non-sense to discuss it with your team, but even that I think it is bike-shredding most of the time, unless the entire team for some reason (like they share the same equipment setup and happen to have same preference) overwhelmingly share the sentiment.
It kind of sounds like you're promoting your own setup.
The funny thing I see the most is that people with these crazy widescreen monitors still maximize just one window, with just one file open. Not sure why, maybe for focus?
I don't see a reason to enforce this strictly. The goal is readability, the max line length is an approximate proxy for that.
I ignored this point on purpose, to be more succint. But yes, it could be possible to have a soft limit (e.g. 80, or 100) and then you would have to set a hard limit (say, 85 or 105). But in the end you'd end up having someone who complains because their beautiful line was 84 chars and after adding the closing paren and the semicolon, it got wrapped into something that they don't like because subjective tastes.
So in the end, we just moved the goalpost +5 chars.
- eslint only works on javascript + typescript (eslint + typescript needs _more_ configuration than eslint + prettier), while prettier works on https://github.com/prettier/prettier/blob/03ebc7869dc9e8f2fc...
- eslint + prettier doesn't need lots of configuration from the user. You add eslint-plugin-prettier and say `"extends": ["plugin:prettier/recommended"]`
For the record, prettier can also be extended to support more languages[3].
[1] https://eslint.org/docs/latest/use/command-line-interface#--...
For example, if someone changes:
function isUserBanned(username) {
return db.findUserByName(username)?.banned;
}
To: function isUserBanned(username) {
return
db.findUserByName(username)?.banned;
}
you want to see that diff because the second version always returns undefined. If you ignore whitespace changes entirely, it becomes possible for people to sneak in bugs intentionally or unintentionally.Also, adding braces from the start means that adding one new line of code is a one-line patch, instead of a four-line one - I do that for the same reason that I always put trailing commas on my array definitions
On the flipside, having three trivial early-return ifs at the beginning of a function will become 9 lines long with braces instead of 6 (or just 3, when doing single-line ifs). Very often, such cases never expand to multiple lines in the future.
I don't think many people who are serious about high "signal to noise" code formatting are supportive of the design decisions prettier makes. e.g. the staggered import lines, left-shifting and up-shifting of implementation details, not allowing trailing comments on the same line
We can have consistent formatting and also avoid tons of visual noise that prettier produces... I've wanted to build a competing solution for awhile, but never made the time for it. Perhaps Anthony's project achieves that... I'll give it a try!
With regards to the whitespace issue, that's down to the line length rules used I think. It's also down to the diff viewer how to show it, not the formatter.
It's incredible how little money some people get paid to build foundational pieces in a multi-trillion dollar industry.
I worked on a team without a formatter for more than 5 years. I'm certain many people have done the same. "Essential" is overselling.
All that time spent staring at code that could have been more readable, or writing style guides and reformatting code, is now spent doing what we were trying to do in the first place. And now, speeding up the time we wait to apply formatting or check it in CI by rewriting it in Rust™ gives us a bit more of that time back. :)
I don't know what to say other than, if these people are out of a job, and you're a company funding prettier or need good JS people, please hire them.
That said, it brings in _much_ more value than $1.5k/mo. It has eliminated styling arguments on teams that adopt it. The amount of time saved in PRs/reduction of bikeshedding is very valuable.
My personal impression is that the code style bike shedding is a sign of team immaturity. In the more mature teams (composed of more mature persons), I haven't really seen formatting bike shedding.
Since when did caring about readability equated to bike-shedding and immaturity?
> Since when did caring about readability equated to bike-shedding and immaturity?
Since never, I didn't claim that. On the contrary, Prettier leads to less readable code than what a human can produce. Bike-shedding is endless bickering about some specific, meaningless thing.
In mine, it used to be... at least half, because I was anal about code style and consistency and all we had at the time was ESLint, which only did partial code stile.
Nowadays, it's none. If you need to worry about code style in code reviews, use a tool.
But the big win for code formatters is fewer decisions. Decision fatigue is real.
What's wrong with the application of e.g. Prettier? Is it wrong enough that it's worth your time to manually format however many thousands of LOC, making countless micro decisions along the way?
It doesn't, really. On larger projects, you read much more code than you write.
Formatting well is not something complex - I basically just format with WebStorm, and only tweak that (mostly line breaks). People (including me) are going to read that code many times, I think it's worth the little effort.
On the opposite, I often have to work hard to make Prettier produce readable code. Like, "how do I need to write this code, so Prettier doesn't mess it up?", which is often difficult / frustrating.
When I embraced formatters, I started spending so much less time and effort keeping the style "correct" and worrying about how other people on the team format code. I love just hitting save in my editor and having the code formatted without having to fiddle with quotes, wrapping, etc.
With regard to bike-shedding about style, it mostly goes away once a team adopts one of the standard formatters for a given language. That's sort of the whole point.
Even a $20K bounty for that amount of work doesn't even seem worth it to boot up my IDE.