Urgent.News

What's breaking now, across thousands of outlets.

Tech

Adding Go's defer to the TypeScript Compiler

Adding Go's defer statement to the TypeScript compiler was an intriguing challenge. In Go, defer delays function execution until the surrounding function completes, often used for resource cleanup. TypeScript lacks a direct equivalent, but we can replicate its behavior.

TypeScript doesn't have a built-in way to implement defer. We need to output JavaScript code that mimics Go's semantics. The goal is to allow TypeScript code like this:

The TypeScript compiler is primarily a static analysis engine, mainly focused on type-checking a dynamic language. Incremental compilation ensures fast IDE response times. This simplifies our task since we don't need to worry about types or other analysis for our defer statement.

Adding defer means performing another AST transformation. tsc already performs various AST-to-AST transformations, so we don't need to add new tooling. The complexity lies in teaching tsc's parser that defer is a statement.

To match Go's behavior, we need to capture the callee, receiver, and argument values immediately when the defer statement is reached. This ensures that even if the callable method is redefined later, the deferred call still invokes the original method.

Each deferred call gets its own stack, and closures are pushed onto that stack when execution reaches the defer statement. When the function exits, the stack is drained in reverse order (last-in-first-out). This matches Go's behavior, where deferred calls are executed in the reverse order they were registered.

To prevent confusion, we reject defer await as an error. JavaScript exceptions are control flow, so when the compiled defer code throws an error, it needs to decide whether that error replaces, combines with, or is ignored in favor of the original failure.

After implementing defer, I concluded that it doesn't belong in TypeScript. The more edge cases I handled, the less convinced I became about its usefulness. TypeScript's error handling and aggregation policies differ significantly from Go's, making defer less natural in TypeScript.

However, hope isn't lost. The ECMAScript Explicit Resource Management proposal offers a different approach to the same problem. Using async-sema as an example, the proposal suggests using an unused variable to clean up resources when they fall out of scope. This approach aligns better with TypeScript's error handling and aggregation policies.

Written by urgent.news from Lobsters's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at healeycodes.com →

More in Tech

7 Real Problems I Faced While Building a Real-Time Chat Application

Building a real-time chat application sounds pretty straightforward at first. You create a login system, add a message input, connect a database, and display messages on the screen.

  • Managing real-time messages without duplicates or unexpected updates proved challenging
  • Prevented duplicate conversations between two users using deterministic conversation IDs
  • Made unread messages and read receipts work correctly by tracking message relationships

My game has one mechanic, so I taught the NPCs to lie

My game has one verb: you name a price. That's it. O'BLOCK is a sneaker-flipping game set on a spoof of early-2010s Chicago. Buying and selling are the same move from opposite sides of the table.

  • O BLOCK is a game with a single mechanic: naming a price
  • Liar NPCs provide offers in reverse, misleading players
  • Game released on Steam October 20 with multiple language support

TrailKit: An Offline Trail Companion

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass What I Built TrailKit is an app for hikers who want to explore trails without worrying about losing network…

  • Allows GPS tracking even when screen is off
  • Identifies plants, insects, and snakes from photos using AI
  • Provides safety information for dangerous species

More from Saturday 10 October →