HackerLangs
TopNewTrendsCommentsPastAskShowJobs

raphlinus

13,583 karmajoined 12 वर्ष पहले
I do research on fundamental UI technology and 2D graphics, with a focus on Rust and fonts. Principal Software Engineer at Canva, working on Graphics Platform.

@[email protected]

Submissions

Smooth-Maximum, the most useful function [video]

youtube.com
2 points·by raphlinus·13 दिन पहले·0 comments

Prediction: AI will make formal verification go mainstream

martin.kleppmann.com
10 points·by raphlinus·7 माह पहले·2 comments

I want a good parallel language [video]

youtube.com
117 points·by raphlinus·8 माह पहले·66 comments

Rust: A quest for performant, reliable software [video]

youtube.com
155 points·by raphlinus·10 माह पहले·94 comments

comments

raphlinus
·3 दिन पहले·discuss
The font is Roboto Mono, not Consolas.

There's something else a lot stranger going on, though. It is a proper monospace font, but the typesetting on the shirt is not. There's some kerning going on (I noticed it especially in the 'Iy' pair), and also it appears that narrower characters such as 'i' take less horizontal space. If I had to guess, I would say that it was set with a tool such as "optical kerning" in InDesign.
raphlinus
·7 दिन पहले·discuss
Greg Kroah-Hartman has given a talk entitled "Untrusted data in Linux — How Rust is going to save us"[1] which I think is fairly optimistic about the idea that Rust will have an increasingly large role in the kernel. The total number of lines of code is small today but that will change.

[1]: https://www.youtube.com/watch?v=Nzmj7K0FNRY
raphlinus
·10 दिन पहले·discuss
Jake has already mentioned how the type system enforces single-threading (using similar mechanisms as Rc in Rust), but it's not necessarily the case that read-write races from multiple threads are UB.

In particular, Java allows aggressive multithreaded access, and the memory model has some pretty strong guarantees. Informally stated, if a read and a write race, then the read is guaranteed to observe either the old or new value.

Go is something of a middle ground [1]. Races on simple scalar values are not UB, but "fat pointers" (slices and interfaces) can tear and can lead to "arbitrary memory corruption."

When I was reading about "stable shape" I was wondering if it might be something similar. You easily get the same UB problems when dealing with sum types, as a tear across tag and variant payload can cause all kinds of things to go wrong.

[1]: https://go.dev/ref/mem
raphlinus
·12 दिन पहले·discuss
The description of the BCE reminds me a lot of the PIO in the RP2040 and 2350 microcontrollers. From the article, BCE instructions include "Transmit Data, Receive Data, Load Timeout Register, Store Status, and Wait."

To me, these correspond more or less 1:1 with PIO instructions OUT, IN, SET, INT, and WAIT. These plus PUSH, PULL (which can considered auxiliaries of IN and OUT), MOV, and JMP are all the PIO instructions. Like the BCE, it runs with completely deterministic clocking, one instruction per clock, and like the BCE there are a bunch of them (a total of 12 state machines on the 2350), though they now run totally in parallel rather than being time-multiplexed.

As a hobby project, I've lately been implementing USB (aiming for higher performance than Pico-PIO-USB, which proves that it's possible), and that's been quite fun.

I wonder to what extent they were explicitly inspired, and to what extent you just get convergent solutions when there are similar goals and constraints.
raphlinus
·15 दिन पहले·discuss
Also see Fast GPU bounding boxes on tree-structured scenes[1] (unpublished paper) and notes toward a blog post[2]. This is a highly tuned GPU implementation of parentheses matching. It's actually used in Vello (the classic version in which we offload basically all the work to the GPU, not the newer CPU-GPU hybrid version in which tracking the blend stack is done on the CPU).

Earlier versions of the work were featured on HN [3][4], but this is much more sophisticated. (plus a few more zero-comment submissions)

The basic idea (bicyclic semigroup and binary search) is the same as the submission. I think earliest attribution is to Bar-On and Vishkin[5] from 1985. Another implementation of this idea is in pareas[6], an experimental GPU-accelerated compiler.

I believe this work is publishable and would love to work with a student to resubmit it. Especially if you're a student or prof in Sydney, please reach out.

[1]: https://arxiv.org/abs/2205.11659

[2]: https://github.com/raphlinus/raphlinus.github.io/issues/66

[3]: https://news.ycombinator.com/item?id=24385095

[4]: https://news.ycombinator.com/item?id=27164009

[5]: https://dl.acm.org/doi/10.1145/3318.3478

[6]: https://github.com/Snektron/pareas
raphlinus
·17 दिन पहले·discuss
This is plausible to me as well. A couple years ago we were trying to make dynamic memory allocation in Vello more robust and explored using async readback of a status buffer. In that case, the async task doesn't wake until the command buffer completes and signals a fence back to the CPU.

Long story short, performance was disappointing and we abandoned the approach. It's easy to believe it's a real problem especially when there are other factors including GPU being clocked down to save power.

Same caveat as parent, I have no direct knowledge of MacBook Neo or this specific issue.
raphlinus
·22 दिन पहले·discuss
No, a normal person would say, "I don't know them."

Silicon Valley bros, on the other hand...
raphlinus
·23 दिन पहले·discuss
Quite a few Ozzies who were in the US (especially Bay Area) and have decided to move back, but so far no other people with no real connection.
raphlinus
·23 दिन पहले·discuss
I'm in Australia.
raphlinus
·25 दिन पहले·discuss
Exactly this, there's rarely a single "correct" colorspace, you make a choice based on expressive goals and constraints. For example, for gradients you almost never want linear, something like Oklab is indeed much better.

The gradient examples between high-chroma colors of similar luminance are highly misleading in my opinion. In that particular case, linear just happens to do well (and device RGB of course poorly), but in other cases linear is not great. For example, blue to white is especially bad, with hue shifts as well as lightness non-uniformity.

You can experiment with this in the interactive tester in my Oklab review[1].

[1]: https://raphlinus.github.io/color/2021/01/18/oklab-critique....
raphlinus
·26 दिन पहले·discuss
Any time, friend. Your basic move is to set the lang metadata accurately and choose a font that does have these style differences implemented in the loca table.

Best of luck and feel free to reach out if you have more specific questions.
raphlinus
·27 दिन पहले·discuss
I love this question. Basically all scripts have things that make them challenging to render, sometimes little things, sometimes bigger ones.

Cyrillic for Russian is reasonably straightforward, but it's also used for many other languages. The variation in style is particularly notable for Bulgarian[1]. A sophisticated font might have a "loca" table with locale-specific adjustments, but this is not universal yet, for example the issue to add it to Open Sans is still open[2]. To see the differences, try [3] and use the Language dropdown to select Bulgarian.

[1]: https://en.wikipedia.org/wiki/Bulgarian_alphabet

[2]: https://github.com/googlefonts/opensans/issues/114

[3]: https://localfonts.eu/freefonts/traditional-cyrillic-free-fo...
raphlinus
·27 दिन पहले·discuss
Yeah, probably should have made a more substantive comment. I'm mostly thinking of the trio of Skrifa, Harfrust, and Parley, but there is other open source Rust work that qualifies as well.

There's also, very relevantly, the DWriteCore work from Microsoft. My understanding is that there's been some talk of open sourcing that, but it's still proprietary.

There are other things that count as high performance text in memory safe languages, for example implementations in Go, but in general those are not a good candidate to replace C and C++ in environments like operating systems and browsers.
raphlinus
·27 दिन पहले·discuss
The more interesting question is why we're not GUI yet. I have Thoughts on this, which I'll try to briefly summarize here.

* It's a genuinely hard problem

The state of GUI on Windows is a total mess, very disappointing considering the relative importance and resources that Microsoft has. SwiftUI was a success (Apple is uniquely good at this stuff), but the transition from Cocoa is still not complete. A large part of the reason why it's so hard is that the requirements for different apps vary widely; I think we are spoiled by the relative cohesion

* The infrastructure is in disrepair

A UI is built on top of lots of infrastructural pieces, obviously including graphics and compositing, but also text, accessibility, input handling, and many other things. When you look at support for those layers across platforms, it's like picking up a rock and seeing the bugs crawl. Take compositing: Windows and Mac have excellent compositors, Android and Linux much less so. But even there the features don't line up, Mac doesn't support incremental present (they don't really need to, considering how beefy their chips are, but it's really important on low end Android).

So a lot of the challenge is working around the brokenness across the various platforms. But, good news, there is really excellent progress on all these fronts. We now have solid text layout in Rust, a clear winner on accessibility, and even poor winit is making slow, steady progress.

I'd also like to say, by contrast the web has really been investing in infrastructure, and hides much of the lower level pain from developers. I think that's a major reason Electron is winning so much.

* The computer science is not quite done

We're still in an exploratory phase to figure out the best patterns for writing Rust UI. At the core of that is reactivity, which is at heart incremental computation. Most systems are converging on a hybrid of something generally React like (coarser grain reactivity) with fine-grained signals. I'd like to think there is a Right Answer here and that it's possible to find it.

This feels to me a bit like async. The foundations for async Rust were laid 10 years ago, but it still doesn't feel fully baked. I've seen some exciting recent work about improving the confusing Pin mechanism with something more principled. We'll get there, but it takes time.

I make three predictions:

* Rust UI will continue to improve, as the infrastructure is built out, we try more things, and projects mature. But not quickly.

* If we thought we had a lot of Rust UI projects before, wait til we see what AI wreaks. I predict we'll see dozens of vibe coded Rust UI toolkits.

* In the longer term, we're going to have Rust UI anyway, as browsers are increasingly going to be rewritten in Rust, and apps will be built on Web technology. And that's not just Electron, the modular browser approach pioneered by Blitz is also promising.
raphlinus
·28 दिन पहले·discuss
Welcome to the club of doing high performance text in a memory safe language!
raphlinus
·पिछला माह·discuss
Similar, in that it encodes length in the first byte. The differences are:

* It does not require canonicality, it allows multiple encodings of the same value. To make things even more fun, the QUIC spec requires shortest encoding in some uses but not others.

* It uses 2 bits rather than cutting out a range.

* It only encodes values up to 62 bits long.

So, some similarities but also some differences.

[1]: https://www.rfc-editor.org/rfc/rfc9000.html#name-variable-le...
raphlinus
·2 माह पहले·discuss
I'm not assuming anything about bit representations. In this case, the spec language is quite clear and unambiguous.

6.3.2.3 paragraph 7: A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned[footnote 68]) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

This is a subsection of section 6.3 which describes conversions, which include both implicit and conversions from a cast operation. This language is not saying anything about bit representations or derefencing.

I happen to be wearing my undefined behavior shirt at the moment, which lends me an extra layer of authority. I'm at RustWeek in Utrecht, and it's one of my favorite shirts to wear at Rust conferences. But let's say for the sake of argument that you are right and I am indeed misunderstanding the spec. Then the logical conclusion is that it's very difficult for even experienced programmers to agree on basic interpretations of what is and what isn't UB in C.
raphlinus
·2 माह पहले·discuss
The issue is not type punning (itself a very common source of UB), but the fact that the `bytes` pointer might not be int-aligned. The spec is clear that the creation (not just the dereferencing) of an unaligned pointer is UB, see 6.3.2.3 paragraph 7 of the C11 (draft) spec.

Of course, this exchange just demonstrates the larger point, that even a world-class expert in low level programming can easily make mistakes in spotting potential UB.
raphlinus
·2 माह पहले·discuss
People interested in alternatives to Lean should also look at Metamath. It has nowhere near the adoption that Lean is getting, but is holding its own in [100] theorems results.

It has some advantages and compelling properties, not least of which is that it's very simple, so much so that there are many implementations of checkers; most other proof systems are ultimately defined by a single implementation. It's also astonishingly efficient — the entire database can be checked in less than a second. Set theory is also a familiar foundation for mathematicians, though the question of which is a better foundation compared with type theory is very controversial. Mario Carneiro pushed forward the development of Metamath in his thesis [0].

There are downsides also, including junk theorems, and automation is weaker. It's possible that types really help with the latter. Even so, I think it's worthy of study and understanding.

[0]: https://digama0.github.io/mm0/thesis.pdf

[100]: https://www.cs.ru.nl/~freek/100/
raphlinus
·3 माह पहले·discuss
A different approach, refining the square root based sigmoid with a polynomial, is in my blog post "a few of my favorite sigmoids" [1]. I'm not sure which is faster without benchmarking, but I'm pretty sure its worst case error is better than any of the fast approximations.

[1]: https://raphlinus.github.io/audio/2018/09/05/sigmoid.html