1. 119
  1.  

  2. 25

    Deno is worth checking for people that want JS/TS but don’t want Node’s design flaws. Comes from Node’s original creator.

    TSC must be ported to Rust. If you’re interested in collaborating on this problem, please get in touch.

    For once, I agree with a RIIR.

    1. 7

      I’m excited for this as well. See also: https://github.com/swc-project/swc

      1. 1

        RIIR

        I don’t understand why. Rust does not seems particularly suited for the task.

        1. 2

          For which reasons do you believe that to be the case?

          1. 3

            A compiler needs to do a lot of symbolic manipulations.

            More often than not, especially with a non-trivial type system such as typescript one, these implies manipulating directed acyclic graphs. Or even worse, arbitrary directed graphs if the processed language has a strong enough notion of recursion. Reasoning with lifetime and sharing of graphs is notoriously difficult. Even with logic stronger than the borrow model of Rust, such as separation logic. This alone is very annoying. If the graphs are local enough, as is the case with CFGs when doing intra procedural analysis, you can just keep allocating and release everything with when done with the function. But type systems not always lend themselves to local analysis. Then, like C/C++, Rust code tend to be efficient if computations have a regular structure (e.g. traversing arrays), not chasing pointers with hardly predictable lifetimes. Which again, is often the case when doing symbolic/static analysis.

            So two of “Rust selling points” are not really applicable, quite the opposite.

            1. 8

              I firmly believe that Rust today is the best language for compilery tasks, based on two observations:

              • The language for writing compilers is ML
              • The language of choice for production-ready compiler implementations is C++

              Rust, as an ML in C++ clothing, combines the relevant benefit of the two.

              I specifically disagree that “it’s hard to work with graph data in Rust” criticism is relevant. Even in a GC language, representing complex graph as a literal graph of objects is often inconvenient/inflexible, and you would use arena and indices, just like in Rust.

              My anecdotal experience tells me that Rust is a more convenient language than Kotlin for compiler front-ends.

              I think I can get behind an idea that a sort of “idealized ML” would be a better language to implement a compiler in, but I think Rust’s quality of implementation, today, in practice, blows all existing functional languages out of the water.

              1. 2

                And if you don’t care about a C++ clothing, you can just use ML. Rust compiler used to be fast when it was written in OCaml. ;)

                1. 1

                  … and way less features and checks…

                  1. 1

                    About C++ clothing and quality of the implementation :-) For example, Windows support and parallelism are just two major benefits of Rust in comparison to OCaml, which are mostly unrelated to language per se.

                2. 2

                  Being honest, anything but JS would be an improvement in this task.

                  I’m okay with Rust because being already used in Deno and the community has a considerable inertia.

                  Your points seem reasonable. Would love to see, in general, web-related compilers/transpilers written in more efficient stuff than JS

                  1. 1

                    Working on a compiler in Rust. It doesn’t seem to be an issue.

            2. 16

              Today I wrote a prototype of a project in TS/deno (circa 500 lines), a HTTP server that reads/writes files from FS and renders HTML.

              My current feelings are positive. I especially like ‘single-binary’ idea taken from go, and the ability to run deno install my_binary_name https://my-website.example/script.ts without publishing anything anywhere, aside from doing rsync to my web server.

              Other things of note:

              • Promises everywhere by default are nice, ditto await;
              • you don’t need to import tons of core modules to start coding (e.g., fetch is already available, Deno.writeTextFile(pathStr, contentStr) doesn’t require require), less boilerplate for trivial things;
              • self-contained imports make it easier to write one-off scripts (no need to create separate package.json and run/rerun npm install everytime you add/update deps);
              • deno run myfile.ts will compile it before running, which is great for one-off scripts (less tinkering with build setup, more tinkering with the code), but for deployment you’d probably want to transpile it to JS to avoid slow start;
              • it seems like TS version is fixed to deno version, which makes it easier for me (less versions of software to think about)
              • I suppose there’d be diamond dependencies problems on larger projects, where you’d need to coordinate the same versions somehow (in documentation there is a suggestion to make deps.ts, which imports and re-exports external dependencies).

              In summary, it feels fresh and suitable for small tasks right away.

              1. 12

                The TSC performance bottleneck is an issue that affects a ton of other projects. Rewriting it in Rust could even allow to plug it as a front end to V8 and Node/Deno, effectively allowing to run TypeScript files seamlessly, with little performance overhead. Stakes are huge, but TypeScript is a large language and TSC complexity is such that it might not be worth rewriting it in Rust. It could also get political given that there’s a certain company behind TypeScript and it’s current implementation.

                1. 4

                  An interesting approach (and what makes a ton of sense for deno I think) is to keep tsc as a primary incremental IDE compiler, and add a second batch compiler to the mix, which works in turbo-pascal style, bailing on the first error and sacrificing features for speed.

                  1. 3

                    Microsoft is already using Rust in other areas so they might actually get behind it

                    1. 2

                      I’m actually a bit surprised that Typescript is self-hosted. Always helpful for community involvement, but Javascript doesn’t seem like the fastest language for compilers.

                    2. 11

                      Oh my god, someone put an actual URL with a version number right inside the import statement. I’ve been dreaming about that (albeit on the Python side of dynamics) for years!

                      We kind of grown accustomed to the idea of what belongs to a language, and what’s tooling. But may be it’s time for our assumptions based on decade long habits formed in the times without even the idea of repositories and automated updates to finally become obsolete.

                      1. 3

                        Sounds like a pretty bad idea, to be honest. I can see why no one is doing this (outside of REPLs/scripts).

                        1. 6

                          It’s probably a good idea if you can expand on why it’s a bad idea for the benefit of discussion.

                          1. 6

                            Because doing that would mean spreading this information all across the codebase.

                            And if one goes “oh this is obviously bad, I’ll centralize all the imports into one file and export them to the codebase from there” – congrats, now we have reinvented status quo, just poorly.

                            There is a lot of value in having a dedicated dependency file that records the (orgName, libraryName, version)-triple for a project, such that changes are easy and guaranteed to be consistent.

                            1. 4

                              So I’m looking into this and I have to say I like the way it’s done. Importing by URL is the same way the module system works in the browser. Rather than using URL imports in all your files, you can use an importmap (and I think this idea comes from browsers too) so I don’t think it’s likely people will be reexporting all their dependencies from one file. Deno has integrity checking and lock files, and you can also choose to vendor your dependencies if that works better for you. You can pin versions in the URL in most CDNs and also deno.land, e.g. https://deno.land/std@0.50.0/http/mod.ts. It has a URL rewriting service for third party modules which works the same as the previous standard library example. Obviously you would use an importmap here so you only specify the desired version in one place.

                              1. 2

                                So, we can expect that no one is going to use imports with versions manually because it’s not a good idea in favor of importmaps, as mentioned.

                                1. 1

                                  I’m not quite sure what you mean? You use the versioned URL in the import map, and you use the lock file for integrity checking.

                              2. 1

                                I have an impression it’s an opt-in. Like, if your whole code base is one file, then you can do that instead of having a package.json.

                                1. 1

                                  Agreed…

                                  One feature, I guess, is that you could easily depend on different versions of a package in different files of the same project. I think that Golang already does it to some extent, but I have not needed that, yet.

                                2. 1

                                  one serious problem with it is that URLs are evanescent and can change both ownership and content trivially.

                                  1. 1

                                    That’s where integrity checking comes in. It doesn’t address availability (if that’s important then maybe you should vendor or backup a local copy anyway), but it does at least mean you’re safe from malicious changes at the source.

                            2. 9

                              I wish for this submission to have more about it in the title.

                              1. 5

                                The very first story submission guideline is “Do not editorialize story titles, but when the original story’s title has no context or is unclear, please change it.” It conveys what it needs to as it is, I’m not sure what else you would add without editorializing.

                                1. 4

                                  I disagree that the story title has sufficient context and clarity to be presented as-is.

                                  1. 2

                                    My feeling falls under

                                    when the original story’s title has no context or is unclear, please change it.

                                    Adding “A secure runtime for JavaScript and TypeScript” would not be editorializing

                                    1. 2

                                      “Deno 1.0: A Node reboot”..?

                                      1. 12

                                        That’s definitely editorializing.

                                        1. 2

                                          “A potential Node successor”, then? The article doesn’t use the word ‘reboot’, but apart from that it positions Deno as

                                          • Deno is intended for the niche now served by Node
                                          • Deno builds on what the authors learned while building Node
                                          • Deno does things that Node does, but better
                                          • Deno, being a new project, can fix things that can not easily be fixed in Node itself

                                          Hell, even the name is an anagram of Node.

                                          I’m not asking you to endorse the word ‘reboot’ like I do; but why does it feel like ‘editorializing’ to you; in other words, feel like it’s more like opinion than description?

                                  2. 5

                                    I’m curious if the team workv on this full time? If so where do they get the funding?

                                    And info appreciated as I’m stuffed curious how a project like this gets bootstrapped.

                                    1. 5

                                      It’s a shame that Deno’s community feels hostile. An example of when somebody suggested they should use a code of conduct,

                                      1. 4

                                        I’m excited for deno’s permission model, too. If I understand it correctly, you have to whitelist things like network access or file system access when running scripts, which makes it much easier to try out untrusted scripts without hosing your system. I look forward to more runtime environments trying that permission model out.

                                        1. 3

                                          I’ve been watching this project for a while and I’m excited to play with it now that it’s at 1.0! But I’m a bit confused at the HTTP server example they have in here:

                                          import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
                                          for await (const req of serve({ port: 8000 })) {
                                            req.respond({ body: "Hello World\n" });
                                          }
                                          

                                          Won’t this only ever handle one request at a time, or am I misunderstanding how async iterators and for await...of work? For a hello-world this doesn’t matter, but imagine instead

                                          for await (const req of serve({ port: 8000 })) {
                                            const body = await fetch('https://a-slow-api.com/v0/some_slow_resource').then(res => res.json());
                                            req.respond({ body });
                                          }
                                          

                                          Wouldn’t the server be unable to process any new requests coming in while awaiting the slow fetch, because a new loop iteration wouldn’t start until the previous loop body completes? Am I missing something here?

                                          1. 4

                                            fetch returns a promise. You’d chain that promise to req.respond, you wouldn’t await on it.

                                            1. 1

                                              Whoops, you’re completely right. It’s only a problem if you directly await in the loop body, so you can just… not do that. Either by regular old promise chaining as you suggest, or making a non-awaited call to an async function. I think something about the top-level async/await threw me off :facepalm:

                                              1. 1

                                                Even in the body of the loop, you’d be fine; await is just syntactic sugar for .then(...). A non-awaited call to an async function will return a raw Promise immediately; awaiting such a function will return the Promise, but chain any actions you’re doing to an implicit .then(...). So the original example is roughly equivalent to

                                                for (const reqPromise of serve({port: 8000}) {
                                                  reqPromise.then(req => req.respond({body: "hello, world"});
                                                }
                                                

                                                which makes it clearer that multiple requests can be served at once. And your example becomes

                                                for (const reqPromise of serve({port: 8000}) {
                                                  reqPromise.then(req => {
                                                    fetch('https://a-slow-api.com/v0/some_slow_resource')
                                                      .then(res => res.json())
                                                      .then(body => req.respond({ body });
                                                  }
                                                }
                                                

                                                which again hopefully makes it clear that lots of fetch calls can be running simultaneously.

                                                1. 1

                                                  I think if you do an actual await in the body of the loop (not nested in another async) it will block the next iteration (thus preventing handling multiple requests). The .then version won’t.

                                          2. 2

                                            What is the primary use case for Deno?

                                            1. 2

                                              We seek a fun and productive scripting environment that can be used for a wide range of tasks.

                                              1. 2

                                                This literally can be anything from Bash to PowerShell but more importantly Python. Is there a particular reason why you chose Deno over those?

                                                1. 8

                                                  We believe JavaScript is the natural choice for dynamic language tooling; whether in a browser environment or as standalone processes.

                                                  None of the languages you mentioned are Javascript.

                                                  Our original undertaking in this area, Node.js, proved to be a very successful software platform.

                                                  Deno is positioned as a potential successor to Node.

                                                  1. 1

                                                    I see, thanks.