[HN Gopher] PR that converts the TypeScript repo from namespaces... ___________________________________________________________________ PR that converts the TypeScript repo from namespaces to modules Author : Kyza Score : 189 points Date : 2022-11-02 17:49 UTC (5 hours ago) (HTM) web link (github.com) (TXT) w3m dump (github.com) | Kyza wrote: | > TL;DR: The TypeScript compiler is now implemented internally | with modules, not namespaces. The compiler is now 10-25% faster. | tsc is now 30% faster to start. Our npm package is now 43% | smaller. More improvements are in the works. | [deleted] | swsieber wrote: | > Finally, as a result of both of the previous performance | improvements (faster code and less of it), tsc.js is 30% faster | to start and typescript.js (our public API) is 10% faster to | import. As we improve performance and code size, these numbers | are likely to improve. We now include these metrics in our | benchmarks to track over time and in relevant PRs. | | > [...] | | > The TypeScript package now targets ES2018. Prior to 5.0, our | package targeted ES5 syntax and the ES2015 library, however, | esbuild has a hard minimum syntax target of ES2015 (aka ES6). | ES2018 was chosen as a balance between compatibility with older | environments and access to more modern syntax and library | features | | I'd be curious as to what percentage of the improvement comes | from modules vs comes from a different target. | berkes wrote: | I'm curious about that too. | | From my superficial knowledge of compilers, "modularization" | itself should not make code faster, if anything slower. | There'll always be some overhead of loading modules and | communicating between them, not? | | I presume, from my own experience when building software (not | compilers), that modules allow for a much easier to reason | about, much better isolated (cohesion, loose coupling). And | therefore for much easier improvements inside the module. I | would presume that, here too, modules allowed them to improve | the inner workings much better, allowing for the performance | increase. Or am I completely misunderstanding this feature? | constexpr wrote: | There are two performance implications of "modularization": | initialization-time and run-time. | | You are correct that initializing many modules is usually | slower than initializing one module [1]. However, bundling | puts all modules into one file, so this PR doesn't actually | change anything here. Both before and after this PR, the | TypeScript compiler will be published as a single file. | | At run-time, switching to ES modules from another JavaScript | module system can be a significant performance improvement | because it removes the overhead of communicating between | them. Other module systems (e.g. TypeScript namespaces, | CommonJS modules) use dynamic property accesses to reference | identifiers in other modules while ES modules use static | binding to reference the identifiers in other modules | directly. Dynamic property access can be a big performance | penalty in a large code base. Here's an example of the | performance improvement that switching to ES modules alone | can bring: | https://github.com/microsoft/TypeScript/issues/39247. | | [1] This is almost always true. A random exception to this is | that some buggy compilers have O(n^2) behavior with respect | to the number of certain kinds of symbols in a scope, so | having too many of those symbols in a single scope can get | really slow (and thus splitting your code into separate | modules may actually improve initialization time). This issue | is most severe in old versions of JavaScriptCore: | https://github.com/evanw/esbuild/issues/478. When bundling, | esbuild deliberately modifies the code to avoid the | JavaScript features that cause this behavior. | akiselev wrote: | For ES6 modules, the exports object is frozen (made read- | only) so the JIT can make some extra assumptions and | optimizations. With bundles, unless the bundler inserts | `Object.freeze` around `module.exports`, they have to be | treated as dynamic objects. | jakebailey wrote: | There are some key things here that maybe weren't clearly | stated in my writeup. | | Firstly, the old codebase is TS namespaces, which compile | down to IIFEs that push properties onto objects. Each file | that declares that namespace is its own IIFE, and so every | access to other files incurs the overhead of a property | access. | | With modules, tooling like esbuild, rollup, can now actually | see those dependencies (now they are standard ES module | imports) and optimize access to them. In this PR's case, the | main boost comes from scope hoisting. | | For example, in one file, we may declare the helper | `isIdentifier`. In namespaces, we would write `isIdentifier` | in another file, but this would at emit time turn into | `ts.isIdentifier`, which is slower. Now, we import that | helper, and then esbuild (or rollup) can see that exact | symbol. All of the helpers get pulled to the top of the | output bundle, and calls to those helpers are direct. | | That's why modules gives us a boost. There's also more | (modules means we can use tooling to tree shake the output, | and smaller bundles are faster to load), but the hoisting is | the big thing. | KingOfCoders wrote: | I don't care. I care when it's implemented in Rust. We've seen | reimplemtation of WebPack (in it's function as a transpiler) et | al. in something faster than Javascript. And I hope there is a | trend to decouple the language of the compiler from the language. | speedgoose wrote: | I think tooling of one programming language should be written | in the programming language. Otherwise the community will | hardly be involved. | | All these rust tools may be slight faster, but typescript | developers will not learn rust to improve the typescript | compiler. | berkes wrote: | If you think of typescript as "tooling" that makes sense. | | But if you think of it as compiler, or transpiler, not so | much. Python, Ruby etc "compilers" (runtimes, really) aren't | written in Python or Ruby. Or rather, there are alternatives | around, but they aren't the fastest nor the best. Such | "tools" are built in C. As are compilers for C++, Rust or | most languages really. | speedgoose wrote: | I understand your point. Compilers and interpreters are | traditionally written in C/C++, but we don't have to do the | same than before. | llanowarelves wrote: | What's the conversion rate on that though? | | For smaller languages that are much less supported that makes | much more sense. | | For bigger languages we treat it much more as a black box. | satvikpendem wrote: | > _but typescript developers will not learn rust to improve | the typescript compiler._ | | Why not? TS has much more in common with Rust than with JS, | in terms of typing. Compiler engineers are not that prevalent | in the community, but they are much more prevalent in the | systems engineering world which Rust is a part of, so I'd | assume it's actually _more_ beneficial to have a compiler in | Rust than in TS because it would mean more people interested | in contributing. | Kyza wrote: | I think a performance improvement in anything existing is | great. Especially for something as big as TSC. It has such a | large amount of usage that many people will appreciate. While | it would be great to have it reimplemented effectively in | something inherently faster, not improving what we have while | it's clearly still the best option wouldn't be helpful. | svnpenn wrote: | thats pretty harsh. I dont even like TypeScript/JavaScript, but | these are some pretty good numbers: | | > The compiler is now _10-25% faster_. `tsc` is now _30% | faster_ to start. Our npm package is now _43% smaller_. More | improvements are in the works. | TAForObvReasons wrote: | In every single one of these cases, it begs the question | whether "JS" is the problem or "backwards compatibility". There | are a huge number of inefficiencies that can be fixed with a | full rewrite. | | There was a recent conversation over ViteJS (a pure JS bundler) | vs rust-based tooling, and when you dig into the numbers the | real difference is SWC vs Babel. It raises the question whether | a new transpiler written in JS can be competitive with Rust, | but it's unclear if anyone tried. | RyanCavanaugh wrote: | Sucrase is written in JS and boasts the highest line | throughput of any competing transpiler | | https://github.com/alangpierce/sucrase | Time Speed | | Sucrase 0.57 seconds 636975 lines per second | | swc 1.19 seconds 304526 lines per second | | esbuild 1.45 seconds 248692 lines per second | | TypeScript 8.98 seconds 40240 lines per second | | Babel 9.18 seconds 39366 lines per second | merb wrote: | but the benchmark is stupid: https://github.com/alangpierce | /sucrase/blob/main/benchmark/b... | | > Like all JavaScript code run in V8, Sucrase runs more | slowly at first, then gets faster as the just-in-time | compiler applies more optimizations. From a rough | measurement, Sucrase is about 2x faster after running for 3 | seconds than after running for 1 second. swc (written in | Rust) and esbuild (written in Go) don't have this effect | because they're pre-compiled, so comparing them with | Sucrase gets significantly different results depending on | how large of a codebase is being tested and whether each | compiler is allowed a "warm up" period before the benchmark | is run. | | (worse it disables esbuild and swc's multi-threading... htt | ps://github.com/alangpierce/sucrase/blob/main/benchmark/b.. | . https://github.com/alangpierce/sucrase/blob/main/benchmar | k/b...) | | fake it till ya make it. | | it's like saying "if I disable everything and wait for 5 | minutes it's faster" | RyanCavanaugh wrote: | I don't see how this is a rebuttal to the claim. 636,975 | is more than 2x 304,526, so assuming the quoted paragraph | is correct, sucrase is still the highest-throughput | transpiler even during its warm-up phase. Probably this | isn't true for the first 100 milliseconds of execution | during the very first warm-up stages, but if the | transpile phase is that short, it's basically irrelevant | anyway. | merb wrote: | the warm-up phase is the whole reason why esbuild and swc | exists btw. and also the sample is basically a small | hello world. any real project would do a little more and | the jit would not optimize as much. | | also 2x 300k is not really the way how multi- | threading/concurrency/parallelism works... especially not | golang, which should not be run with GOMAXPROCS=1.... | cxr wrote: | As far as I can follow your argument, it seems to be that | the native tools perform better on the small inputs (that | only ever take a second or three to complete), and that | the creators ("maintainers"?) of Sucrase have their thumb | on the scale or something, since they emphasize in their | results the very large inputs that will involve longer | running jobs where their tool has had a chance to warm | up. In other words, the tools you're defending only do | better when it doesn't really matter, and the tool you're | downplaying outperforms the competition on the jobs where | it actually does matter. If anything is backwards (or | "stupid", as you put it) then _that_ seems to be it. | | Maybe I'm misunderstanding. In that case, please provide | a better benchmark. | ppseafield wrote: | SWC is written in rust, and Babel is written in javascript, | so you've proven the OP's point. Vite can be configured to | use SWC. | | The recent conversation was about Vercel benchmarking a tuned | Turbopack+SWC vs. a default Vite+Babel, not really an apples | to apples comparison. When Vite is configured to use SWC as a | compiler, Vite's HMR gets faster; but it's not the default | for compatibility reasons. | longrod wrote: | Sucrase is faster or really close to SWC (see rhe | benchmarks https://github.com/alangpierce/sucrase). | Everyone still uses Babel because of the transforms. | | And yes, Babel can also be made faster if enough effort is | dedicated into it. it's not an impossible feat. | ppseafield wrote: | For single core benchmarks only, correct? | tantalor wrote: | 500k lines changed, oof. Imagine the merge conflicts. | | Could this not have been done incrementally? | jakebailey wrote: | This is as incremental as it really could be; the entire build | had to change, all of the code needed to be unindented one | level, etc. | | I have tested the merge conflict problem, and thanks to the way | the PR is constructed (in steps), git actually does a good job | figuring things out. | darig wrote: | throwup wrote: | Does anyone have any insight about how to coordinate this kind of | change to a large project? This kind of thing touches literally | every file, so every branch will have merge conflicts. The best | idea I can think of is to announce the date ahead of time and | make every contributor rebase their branches on the day of the | merge. But there has to be a better way. | jakebailey wrote: | Surprisingly, at least for this PR, solving merge conflicts | turns out to not be too hard. By not squash merging it, we can | have a single commit that unindents the codebase all in one go | (and the commit is in the tree), which means that every line | has a clear path back to the current state of the main branch. | (And crucially, we can make git blame not point every line to | me...) | | Potentially, an approach like this might be applicable to other | changes; I have a commit in my stack which moves the old build | system config to the new build system config's path (even | though it's wrong), as git does a much better job understanding | where the code is going if you help it. | longrod wrote: | Sucrase is proof that JS is not the problem when it comes to slow | performance. JS is not slow. NodeJS is not slow. It's the code | that is slow. All these people wanting to write it in Rust or Go | or XYZ programming language need to acknowledge this. | | Yes, multithreading is awesome and really helpful but it's the | cherry on top, not the whole thing. If the same amount of effort | was put into optimizing the TSC codebase as it is being spent to | rewrite it in Rust, I have no doubt that it can become faster. | Perhaps it'll require some big changes but it won't create | compatibility concerns and it won't be a cat-and-mouse race | between the Rust version and the TS version. | | I don't think "Write it in Rust" is always the solution to fast | programs. Rust itself can be pretty damn slow if you don't keep | performance in mind. That is why you have to optimize and profile | and optimize over and over again. Can't the same be done for TSC? | | I think the biggest reason devs don't do this is because no one | likes profiling and optimizing since it is a slow and boring | task. Rewriting is so exciting! It's the thing you do when you | are tired of maintaining the old codebase. So just ditch it and | rewrite it in Rust. | | I have nothing against Rust, mind you. I love what it has done | but I don't think rewriting everything is either feasible or even | the solution. And waiting for that to happen for every slow tool | out there is utter foolishness. | foobarian wrote: | How far can you get with JS/other interpreted things in e.g. | optimizing for cache access etc? Sounds like you're at the | mercy of the JIT compiler (which may go far, but still). | meheleventyone wrote: | With stuff like TypedArrays pretty far. Where JS has problems | is optimising in the face of the things you can do with the | language and the current difficulty in multithreaded | implementations. | TAForObvReasons wrote: | The interesting question to ask is whether these Rust | rewrites are really taking advantage of cache optimization or | if they are making simplifying assumptions that the canonical | implementation cannot. In the latter case, Rust isn't the | root of the performance difference and a JS rewrite can make | most of those simplifying assumptions | z3t4 wrote: | JavaScript does not have any input/output (IO/syscalls) all | those functions like reading a file, socket, etc needs to be | implemented in the runtime language, like the browser, | Node.JS, ASP, etc. So you are at the mercy of the runtime | executable. The JS JIT slows down startup time as the | JavaScript first have to be parsed and compiled before | running, but the runtime can then cache the compiled version | for faster startups. When JavaScript was new it was slow, for | example string concatenation was slow, but most JS engines | now implement string concatenation with a "rope" structure | making it very fast. v8 (Chrome) and Spidermonkey (Firefox) | have got a lot of optimizations over the years, so if you are | doing things like incrementing a number in a loop it will be | just as optimized as something written in a systems level | language. | CSSer wrote: | This can vary a ton as well. I was talking to a friend | yesterday who said he was pounding a native browser | interface with an iterator and experiencing slow | performance. He switched to buffering the entire thing into | memory first and experienced huge performance gains. | | The aspect of the language you're using, if optimized, is | virtually always optimized for the most common use-case. If | your use-case isn't the most common use-case, you must | account for this. | [deleted] | notriddle wrote: | Yes, you technically can write high-perf JavaScript code... | | https://github.com/alangpierce/sucrase/blob/153fa5bf7603b9a5... | | But freaking _SIGH_ I don 't want to. I prefer coding in | environments that don't require unrolling loops by hand. | kasajian wrote: | When you write Chrome itself in JS, then you can talk to me | about performance. | eyelidlessness wrote: | AFAIK all of the major browsers (and other JS runtimes) have | implemented some performance-sensitive APIs in JS, | specifically because it performs better than crossing the | JS<->native boundary. Granted that's usually specifically | about JS API performance, but that's a lot of where | performance matters in a JS host environment. | cxr wrote: | Not sure if serious or not, but Firefox is a long-standing | example of this. It has always been a mixed C++/JS codebase. | (Since before it was even called Firefox, that is, though | nowadays, it's also Rust, too.) I routinely point this out in | response to complaints about the slowness attributed to e.g. | "Electron". JS programs were plenty fast enough even on sub- | GHz machines before JS was ever JITted. It's almost never the | case that a program having been written in JS is the problem; | it's the crummy code in that program. When people experience | Electron's slowness, what they're actually experiencing is | the generally low quality of the corpus that's available | through NPM. | | Arguably, the real problem is that GCC et al are enablers for | poorly written programs, because no matter how mediocre a | program you compile with them, they tend to do a good job | making those programs feel like they're performance-tuned. | Today's trendier technology stacks don't let you get away | with the same thing nearly as much--squirting hundreds or | thousands of mediocre transitive dependencies (that are | probably simultaneously over- and under-engineered) through | V8 is something that works well only up to a point, and then | it eventually catches up with you. | | Besides, there's no such thing as a fast or slow language, | only fast and slow language implementations. | merb wrote: | which proof? their faked benchmark? | Analemma_ wrote: | Sucrase consciously and deliberately breaks compatibility. | Which, to be clear, isn't necessarily a bad thing for some use | cases. But you can't really generalize from that to a tool like | tsc where this isn't an option. There might be a performance | ceiling here that can only be surpassed with a different | language. | swsieber wrote: | I suspect you have a point, given this line from the Sucrase | readme: | | > Because of this smaller scope, Sucrase can get away with an | architecture that is much more performant but less extensible | and maintainable. Sucrase's parser is forked from Babel's | parser (so Sucrase is indebted to Babel and wouldn't be | possible without it) and trims it down to a focused subset of | what Babel solves. If it fits your use case, hopefully | Sucrase can speed up your development experience! | Chyzwar wrote: | Average node.js app is slow. It requires godlike | understanding/experience to make JS perform well. That why you | see people re-writing JS to rust and go and zig, for example | SWC, turbopack, esbuild and rome. For most use cases JS is | plenty fast but average go code will be faster and easier to | maintain. | | As I am getting older, I do not want to spend my weekend | learning about new features in next.js v13[1]or rewriting tests | from enzyme to RTL[2]. I want to use programming language that | value its users time and focus on developer experience. | | [1] https://www.youtube.com/watch?v=_w0Ikk4JY7U [2] | https://dev.to/wojtekmaj/enzyme-is-dead-now-what-ekl | __s wrote: | I rewrote a card game engine, openEtG, from JS to Rust. It was | a pretty 1:1 rewrite. 2x improvement even when I was using | HashMap everywhere. I've since entirely removed HashMap, which | has only further improved perf | | As a bonus, the code is now statically typed | SquareWheel wrote: | I suppose it depends on your use case, but I don't really | consider 2x to be a significant difference. Between | programming languages we often speak in orders of magnitude. | | If JS is only half the speed of a compiled language like | Rust, that shows remarkably optimized performance. | MitchellCash wrote: | > _a change in the indentation used in our bundle files (4 spaces | - > 2 spaces)_ | | I find it interesting that one of the reasons given for the | reduction in package size is due to such a simple indentation | change from 4 spaces to 2 spaces. | | Not interesting that 2 bytes are less than 4 bytes, rather, | TypeScript is a large project and it would be interesting to know | how much size was saved from this one specific change? Seems like | a trivial change, so why not do it sooner? And assuming | readability isn't required in the bundle output why not bundle | with no indentation at all and put everything on a single line, | would this not be even smaller again? | IshKebab wrote: | Kind of funny because one of the benefits of tabs vs spaces | that people laugh off is that it saves space. | | I think it's probably correct to laugh this off though. Why | would you care about the non-minified/gzipped size this much? | RyanCavanaugh wrote: | > Seems like a trivial change, so why not do it sooner? | | Re: indentation: Literally, no one thought of it, as far as | anyone can tell. Linus's law appears to have its limits. | robertlagrant wrote: | Most minifiers already put things on one line, though. | jakebailey wrote: | TS has some unique restrictions due to downstream patching | of our package; my PR description briefly talks about this | as something we can try to improve in the future. | Minification absolutely would save a lot more size out of | our package, but I was not willing to change that in this | PR. | msoad wrote: | This opens up the door to going in there and replacing the slow | parts with Rust. | | There is a lot of interest in making typescript fast but all of | them want to do a rewrite. Swapping the slow parts seems a lot | more viable | redox99 wrote: | I absolutely hate how with Typescript and ES Modules, if you have | a file | | utils/foo.ts | | you have to import it as | | import Foo from "utils/foo.js" | | Even though there is no .js file on disk, and you might be | running ts-node or whatever that doesn't build a .js file. | | Importing a file that "doesn't exist" is so counterintuitive. | | In addition all code breaks because you have to change all your | imports, and /index.ts or /index.js won't work either. | lewisl9029 wrote: | Agree completely. It also makes interop between Node and Deno | more painful. But there is hope on the horizon. :) | | See https://github.com/microsoft/TypeScript/issues/37582 which | is referenced in the 4.9 Iteration Plan as "Support .ts as a | Module Specifier for Bundler/Loader Scenarios": | https://github.com/microsoft/TypeScript/issues/50457 | cypress66 wrote: | But that doesn't seem like it would fix the typical flow, | there still would be no transpiling of imports. So yes you | could use .ts in ts-node, but you would have to use .js in | tsc. Which is pretty awful (you want your code to work with | both). | codefined wrote: | Actually looks to be tabled for TypeScript 5.0, release date | of 'March 14th' next year. | bigyikes wrote: | Every TypeScript project I have worked on either: | | 1) enforces _no_ extension, e.g. "utils /foo", or | | 2) allows TS extensions, e.g. "utils/foo.ts" | | I have never imported a TS file using a JS extension. Maybe | your woes could be fixed with a configuration change? | Chyzwar wrote: | No, you were using non-standard ESM modules (compiled to | CommonJS defined by babel) Typescript recently added support | for ESM compatible with node.js see "module": "node16"[1][2] | | The Whole ESM saga is clusterfuck, not much better than | python 2 -> 3 migration. Large node.js codebases have no | viable path to migrate, and most tools still cannot support | ESM properly[3]. Stuff is already breaking because prolific | library authors are switching to ESM. | | As someone that maintain large part of TS/JS tooling in my | day job, I absolutely despise decisions made by node.js | module team. My side projects are now in Elixir and zig | because these communities care about DX. [1] | https://nodejs.org/api/esm.html#differences-between-es- | modules-and-commonjs [2] | https://www.typescriptlang.org/docs/handbook/release- | notes/typescript-4-7.html [3] | https://github.com/facebook/jest/issues/9430 | redox99 wrote: | Yeah it's pretty ugly. This whole thing is a prime example | of those cases in which maintainers for mostly arbitrary | reasons decide on something and then absolutely ignore all | the massive negative feedback they get for this. | | They'll cite some nebulous technical reasons of why it has | to be this way, but if you offer a PR that actually solves | the issue that the community complains about, they'll | reject it. | | In this case they decided that tsc won't transpile imports. | They just did and it's "policy" and it can't be changed. It | doesn't matter if it is awful for compatibility, developer | experience, etc. It's just the policy. Issues will be | closed. And no, even an optional flag to transpile imports | is off the table, even if you write the PR for it. | | There are many many issues opened related to this in | github, but to give an example | | https://github.com/microsoft/TypeScript/issues/16577 | Chyzwar wrote: | It is complicated but most user anger should be directed | to node.js module group[1]. TS is forced to follow | node.js standard. | | [1] https://github.com/nodejs/modules/issues/323 | cypress66 wrote: | And that's how it should work imo. But if you enable esm | (which you might need in the future because of packages being | esm only) you can't use those, only .js. | | That's because typescript developers are dead set that they | don't want to transpile the imports, they just want to copy | paste them into the resulting file when running tsc. | conaclos wrote: | This could change with an ongoing work to allow ts | extension [1]. | | [1] https://github.com/microsoft/TypeScript/issues/37582 | dickfickling wrote: | have you worked on Typescript projects using ES modules? What | you've described is the status quo for CommonJS modules, but | doesn't work when you switch to ESM (afaik, at least) | sebdufbeau wrote: | From my understanding, this is a fairly new predicament, for | projects that target ESM (type module in package.json) | instead of the default CJS | [deleted] | cush wrote: | Where are you seeing this? The PR that this thread is about | doesn't have this quirk. Maybe your setup has some issue...? | kuramitropolis wrote: | A thousand times this. It's not only the dumbest thing I've | seen a programming language do, it's also dumbest thing I've | seen in the JS ecosystem. Ended up having to implement an AST- | based post-processor to fix packages before publishing them. | zebracanevra wrote: | After this change, the TypeScript compiler will now be compiled | with esbuild. I feel like thats probably the best endorsement | esbuild could get, hah. | | Surprising they call out the 2 space indent level that esbuild is | hardcoded[1] to use as a benefit. Why not save even more bytes | and re-format the output to single tab indentation? I wrote a | simple script to replace the indentation with tabs. 2 indent | size: 29.2MB, tabbed size: 27.3MB. 2MB more of indentation saved! | Not significant after compression, but parsing time over billions | of starts? Definitely worth it. | | [1] https://github.com/evanw/esbuild/issues/1126 | CodeWriter23 wrote: | > Why not save even more bytes and re-format the output to | single tab indentation? | | For your answer search "programmers who use spaces make more | money" | throwup wrote: | I wish they had broken down that survey question further to | find out _how many_ spaces the highest paid developers use. | Then I could finally have a data-driven answer to put in my | prettier config! | tryfinally wrote: | Surely, on average, it's 3 spaces of indentation. Feels | great to finally be able to derive objective answers to | these ages-old conundrums! | jdrek1 wrote: | Correlation != causation | | Spaces are simply inferior to tabs since the latter conveys | the meaning of "one level of indentation" while the former | does not. It's also better for accessibility and file size. | There is not one single logical reason to ever use spaces for | indentation, not one. | | For some very fucking stupid historical reason someone in the | 80s made the idiotic decision of spaces being the default in | editors and people just went with it. The people earning more | are doing so because those are the seniors who have given up | on common sense and just go with the flow of the masses who | are unable to grasp "tabs for indentation, spaces for | alignment" yet insist on keeping alignment so the (terrible) | compromise is just using spaces. And I strongly question | whether "alignment" is worth anything, in almost all cases | it's just useless and in the rest you're drawing ASCII | diagrams in the comments which doesn't affect your code at | all. | | Also see the top answer at https://www.reddit.com/r/programmi | ng/comments/8tyg4l/why_do_... | ddoolin wrote: | Tabs are denoted by arrows and I don't like being told what | to do! :) | lmohseni wrote: | Also for blind programmers, tabs are much nicer for a | screen reader. | jsyolo wrote: | What's the difference between indentation and alignment? | jcparkyn wrote: | > Tabs are simply inferior to spaces... | | I think you wrote this the wrong way around? | jdrek1 wrote: | Ups, yes. I had it switched originally but then for some | reason switched it again. Apparently commenting late at | night is not a good idea. | CodeWriter23 wrote: | Testimonial: I experienced a significant increase in | earnings about 4 months after abandoning tabs for spaces. | Cause not known but that's what happened. | camjohnson26 wrote: | English is a bad convention too but we use it because | humans don't need the theoretically best systems to be | productive, they need something good enough. Spaces are | good enough, tabs are good enough, and anybody who gets | emotionally invested in one vs. the other is wasting time. | z3c0 wrote: | TLDR "Programmers who use spaces are more likely to respond | to StackOverflow surveys soliciting information about their | income." | robbick wrote: | I can see this is probably a calm point that will definitely | not escalate, programmers don't really care about tabs and | spaces that much, right??? | bnt wrote: | Tabs | Accacin wrote: | Heh, I always wondered what the big deal was. I'll just use | whatever the company I'm working for uses and not even think | about it. | | To be honest, that's why I love auto formatting cause I never | need to think about that stuff, I can just write code. | TOGoS wrote: | This was actually a significant issue in a large PHP codebase I | used to work on. Client hired a new guy who insisted that we | convert everything to spaces, and suddenly it took about twice | as long to check the thing out from Subversion. | ElijahLynn wrote: | That doesn't make sense that spaces vs tabs would result in a | 2x longer checkout. Something else is at play if that is the | case. | wombatpm wrote: | He did mention it was subversion | noduerme wrote: | Someone who comes onto a project and actually wants to charge | money to sit there and convert tabs to spaces or vice versa. | Incredible. | breck wrote: | Why a tab when 1 space will do? | marssaxman wrote: | Tab is ASCII 9 while space is 32. Tabs, having the lower | number, are therefore obviously cheaper. | Krizzu wrote: | Why not suggest this in the PR? Seems like it could be used in | pipeline to decrease size further down | siftrics wrote: | Jake Bailey was one of the best TAs I ever had in college. It's | great to see his name behind this. | jakebailey wrote: | I miss the Piazza days... | | Thank you for the kind words! | iainmerrick wrote: | A little while ago I asked | (https://news.ycombinator.com/item?id=33051021): | | _I'm curious, how many people are using TSC only for type- | checking, and a different system (eg esbuild or ts-node) to | actually compile /bundle/execute their code?_ | | Looks like my suspicion was correct; not even tsc uses tsc! | simlevesque wrote: | The headline is pretty misleading. The TypeScript compiler isn't | implemented with modules. This is an open pull request which | would make it that way. | RyanCavanaugh wrote: | It's a PR that will be merged within the next week or so, and | has been scheduled in the TS roadmap for quite a while. It's | happening. | simlevesque wrote: | Hi Ryan, thanks for chiming in ! I just wanted to make it | clear that the current HEAD doesn't implement this but maybe | I'm just nitpicking. | Kyza wrote: | Oops, I didn't mean to mislead. I updated the title to be more | clear. | simlevesque wrote: | Thank you | breck wrote: | Bravo. This must have been painful. Super excited to use a faster | tsc. That will make a huge difference in our products. Thank you. ___________________________________________________________________ (page generated 2022-11-02 23:00 UTC)