Live data from Hacker News

We're building a browser when it's supposed to be impossible

awesomekling.substack.com

331–340 of 349 posts

Re: We're building a browser when it's supposed to be impossible

#331
post #62

> So instead of [building the browser one feature/spec at a time], we tend to focus on building “vertical slices” of functionality. This means setting practical, cross-cutting goals, such as “let’s get twitter.com/awesomekling to load”, “let’s get login working on discord.com”, and other similar objectives. Seems similar to how Wine is developed: instead of just going down the list of API functions to implement, the…

This approach works better for Wine where the Windows binaries are a fixed target. On the web, you may get Twitter's feed rendering acceptably, and then two days later they ship an insignificant redesign that happens to use sixteen CSS features you don't have and everything is totally broken again.

In general the Windows binaries are not really a fixed target for Wine either - many applications (e.g. multiplayer games) have online components that require you to run the latest version. And even for others, people will demand the latest version work. Fixing things that are actually work first is still a good way to prioritize things - it's not like you stop implementing functionality once one target program works, you just move to another one. And if you run out of interesting programs then you can look at 100% API coverage.

Re: We're building a browser when it's supposed to be impossible

#332
post #174
post #156

Earlier quoted context omitted.

Sure but Wine is a tool where if 90% of the stuff user wants to run in it works, it's still great. Say if you use it for gaming you can play most of the games and only boot into windows every few months once you hit one you can't. But that's not how you use web. If 90% of the pages worked in browser I wouldn't use that browser, ever, because chances are I'd hit one that didn't at least once every few days.

> If 90% of the pages worked in browser I wouldn't use that browser, ever They don't care.

Nor should they. If 100% Chrome compatibility is the only goal that matters for someone ... then there is Chrome for them.

Re: We're building a browser when it's supposed to be impossible

#333
post #156

Earlier quoted context omitted.

Sure but Wine is a tool where if 90% of the stuff user wants to run in it works, it's still great. Say if you use it for gaming you can play most of the games and only boot into windows every few months once you hit one you can't. But that's not how you use web. If 90% of the pages worked in browser I wouldn't use that browser, ever, because chances are I'd hit one that didn't at least once every few days.

I completely agree. The people advocating for this type of development style are in another universe. Web is incredibly fragile. There's a vast difference between a page being degraded by all browsers in a consistent manner per W3C specs (especially the critical parts of a webpage such as JS execution or malformed HTML) vs the damn thing breaking in such a unique way that the web devs will never be able to fix the pa…

Web devs shouldn't be fixing pages for individual browsers but instead using features conservatively and degrading gracefully where features are not available. Browser bugs shuld be fixed in the browser.

And for 99% of websites security doesn't matter at all because it's just a one-off visit to read an article or look at some funny pictures without any user account.

Re: We're building a browser when it's supposed to be impossible

#334
post #101

Earlier quoted context omitted.

Do we really pretend this is a architecture decision? This is the classic Agile Management wants to show result for reward fast, that leads to huge tech debt build up, as layers are not properly designed and reuseable.

Looks like regular TDD to me but tests are well defined real world use cases

I guess technically the term test driven development does not specify unit-test driven development.

Re: We're building a browser when it's supposed to be impossible

#335

I've been working on CSS Layout as a library recently[0] (we have Flexbox and CSS Grid support so far). It seems to me that librifying everything (much like is already done with JS engines) could be a good approach to making building a new browser engine more accesible. Because that way any one wanting to build a new one can starting by pulling in a bunch of libraries (layout, rendering, etc), and then just customise…

> It seems to me that librifying everything (much like is already done with JS engines) could be a good approach to making building a new browser engine more accesible. ... Because that way any one wanting to build a new one can starting by pulling in a bunch of libraries (layout, rendering, etc), and then just customise the bits they need (ideally publishing them as a new iteroperable library that others can also us…

Libraries for a lot of this stuff exist (albeit in many cases not very mature yet):

- https://github.com/pop-os/cosmic-text does text layout (which Taffy explicitly considers out of scope)

- https://github.com/AccessKit/accesskit does accessibility

- https://github.com/servo/rust-cssparser does value-agnostic CSS parsing (it will parse the general syntax but leaves value parsing up to the user, meaning you can easily add support for whatever properties you what). Libraries like https://github.com/parcel-bundler/lightningcss implement parsing for the standard css properties.

- There are crates like https://github.com/BurntSushi/bstr and https://docs.rs/wtf8/latest/wtf8/ for working with non-unicode text

We are planning to add a C API to Taffy, but tbh I feel like C is not very good for this kind of modularised approach. You really want to be able to expose complex APIs with enforced type safety and this isn't possible with C.

Re: We're building a browser when it's supposed to be impossible

#336

Earlier quoted context omitted.

I'm not surprised, it usually takes many words of English to describe very little code. For example, changing "greater than" to "greater than or equal to" might require only a single bit of change in the machine code.

I think the opposite. Sure, in your example that is true, but that's assuming we speak to the code line by line, in English. But we don't, really. Example: Write a function that keeps track of the name and weight of each person added, then prints the list, sorted by weight, lightest to heaviest. I asked GPT this. My 140 character, unoptimized query resulted in 816 characters of c++ code.

Your example is heavily underspecified. In what form are people’s details added? How is the list printed? A spec that’s actually implementable will be a good deal longer. One that defines behaviour completely (what ordering should you use for equal weights?) will be longer still.

The HTML and ECMAScript specs that comprise most of what we’re talking about are very much closer to line-by-line, because they’re designed to be both implementable and completely specified.

Re: We're building a browser when it's supposed to be impossible

#337
post #101

Earlier quoted context omitted.

Looks like regular TDD to me but tests are well defined real world use cases

I guess technically the term test driven development does not specify unit -test driven development.

This is a common misconception. I practice TDD at work and side-projects and find it very productive. TDD is best done with end-to-end tests (or automated integration tests, whatever you wanna call it). You write an end-to-end test (I give input A to the entire system, expect output B), first the test fails (because it's unimplemented) and then you implement and it passes.

It works because then your tests become the spec of the system as well, but if you only write unittests there is no spec of the system, only modules of your code. Which is not useful because if you refactor your code and change this module you need to rewrite the test. Whereas in TDD your tests should never be rewritten unless spec changes (new features added, new realization of bugs etc). This way "refactor == change code + make sure tests still pass".

You're of course free to write unittests as well, when you see fit, and there is no need to target a religious X% coverage rate at all. I think coverage targets are cargo-culted, unnecessary, time-consuming and religious. The crucial thing is, while you're writing new code (i.e. implementing a new feature or solving a bug) you need to write an automated test that says "if I do X I expect Y", see it fail, then see it pass, such that "if I do X I expect Y" is a generic claim about the system that will not change in the future unless the expectation from the system changes.

In other words, the example in this comment chain: "run a game, see 'opcode X doesn't exist', implement X, rinse repeat" is actually how TDD is supposed to work.

Re: We're building a browser when it's supposed to be impossible

#338

Earlier quoted context omitted.

I think the opposite. Sure, in your example that is true, but that's assuming we speak to the code line by line, in English. But we don't, really. Example: Write a function that keeps track of the name and weight of each person added, then prints the list, sorted by weight, lightest to heaviest. I asked GPT this. My 140 character, unoptimized query resulted in 816 characters of c++ code.

Your example is heavily underspecified. In what form are people’s details added? How is the list printed? A spec that’s actually implementable will be a good deal longer. One that defines behaviour completely (what ordering should you use for equal weights?) will be longer still. The HTML and ECMAScript specs that comprise most of what we’re talking about are very much closer to line-by-line, because they’re designed…

If I change my query to be more specific

Write a program that keeps track of the name and weight of each person added, sorted by weight, lightest to heaviest. The input should be a command line prompt asking for input in 3 fields - first name, last name, weight. If two people have the same weight, order them alphabetically by last name. At the end, when a blank line is entered, print the list with headings first name, last name, weight. Check the input, if it's not 3 sections or empty, print an error explaining the input format.

497 input characters, 1317 output characters.

In the case of a detailed or verbose spec, you're probably right. I'm just replying to the assertion that it generally takes many words of English to equal little code. If that were true, nobody would be using ChatGPT to scaffold.

Now, if you're going to be detailed about -how- each line should look, I'd agree that English would be more verbose than code.

Re: We're building a browser when it's supposed to be impossible

#339

> So instead of [building the browser one feature/spec at a time], we tend to focus on building “vertical slices” of functionality. This means setting practical, cross-cutting goals, such as “let’s get twitter.com/awesomekling to load”, “let’s get login working on discord.com”, and other similar objectives. Seems similar to how Wine is developed: instead of just going down the list of API functions to implement, the…

> Console emulators (especially of the HLE variety) seem to have a similar flow.

Good insight.

I was going through this same spiel in my head the other day.

It's a flow that if properly managed can provide a good feedback system. It provides the developer positive feedback and at the same time successful milestones.

Say I'm building an emulator for a simple architecture with a few dozen opcodes...

"Alright. Let's start. Where do I start? How about NOP." So you implement NOP. You write some tests for it. Maybe you build a pretty printer into your opcode and you test it on disassembling a single byte file with a single NOP opcode.

Suddenly you have a working dissassembler! It's obviously an artificial toy, but it works.

Maybe next you add an INC instruction. Add some tests. You'll need registers...

Build a simple one INC opcode binary file. Maybe add an executor in addition to a dissassembler. Suddenly you've got registers working. And if if add another INC opcode byte, you can see your emulator changing behavior based on real external input!

And so on. It's an interesting flow, you're right.

Re: We're building a browser when it's supposed to be impossible

#340
post #33

Earlier quoted context omitted.

Chrome used an already existing render engine and improved on it.

More specifically, Chrome used Safari's rendering engine, and Safari used Konqueror's rendering engine, because even in 2001, starting a browser engine from scratch seemed like too much work.

In the end, it all leads back to Konqueror. Pretty sad to see that piece of software go, considering its historical significance
Post reply on HN