Mu: A Human-Scale Computer
github.com
github.com
https://wiki.xxiivv.com/site/uxn.html
...and it's also awful.
I get sad when I see an idea that I like implemented to poorly. It sucks oxygen out of the room, or poisons the well, or whatever.
I think I basically want Deno with a decentralized ID / DNS system that has nothing to do with the hierarchy or Urbit... And using capability modeling for different apps... And with something like Wire Guard for end-to-end encryption... That feels like a federated version of Sandstorm.io...
That's what I'm daydreaming about.
https://github.com/urbit/urbit/blob/master/pkg/arvo/sys/arvo...
This is a kind of joke, isn't it?
That said I flippin love people re-inventing a computer into something not derived from a VAX timeshare machine from the 70s.
> Unifont Limitations
> Unifont only stores one glyph per printable Unicode code point. This means that complex scripts with special forms for letter combinations including consonant combinations and floating vowel marks such as with Indic scripts (Devanagari, Bengali, Tamil, etc.) or letters that change shape depending upon their position in a word (Indic and Arabic scripts) will not render well in Unifont. In those cases, Unifont is only suitable as a font of last resort. Users wishing to properly render such complex scripts should use full OpenType fonts that faithfully display such alternate forms.
So if your intention when choosing unifont was to support all of Unicode, it would be good to make it not too difficult to add more fonts.
It's not just a matter of supporting more fonts. I need to support smarter fonts with ligatures and more. I think we could preserve the constraint of a single font and just make it smarter. But it'll take me some time to learn enough to do that.
E.g. you list Myanmar, where it's possible to construct something like င်္င္င္င္ငြေေေေေေေောာာာာာာာ, which has "nga" င, "asat" ်, "virama" ္ combined to put င်္ on the following consonant, which in this case is four "nga" င separated by three "virama" ္ to form a cluster င္င္င္င (Noto Sans Myanmar apparently supports stacking up to height 3, the fourth "nga" င awkwardly overlaps), then there's a "medial ra" ြ which puts a box around the preceding consonant without overlapping, then 8 copies of "e" ေ which should be rendered to the left of the consonant it follows and then 8 copies of "aa" ာ which attach to the right.
You're not going to encounter something crazy like this in the wild (in Burmese, there's at most one of each vowel sign on a consonant, and I don't think stacking four consonants is ever necessary) but it serves as a demonstration of the edge cases that a font needs to handle. The lookup tables end up getting quite large, which I think is one of the reasons Noto isn't usually used as one file with all scripts.
Tamil, however, doesn't have this property. Does Myanmar?
At the moment a single diacritic is the extent of my ambition.
Anyways, if you could get Tamil to work with a generic approach, I guess most of the edge cases for Myanmar would be covered by that as well. (Edit: seems like Tamil only has at most one diacritic, so it would have to be more general for Myanmar still.)
Wish general computing was more customizable like that...
here are a few images showing the setup and sites using unifont. https://imgur.com/a/5gAZau3
- - - -
FWIW, I ran across this the other day: "4x4 ASCII Font"
> Small fonts have always been fascinating to me, so I decided to make the smallest font possible, which turned out to be 4x4 pixels per character. The font covers the entire range of visible ASCII characters, and most are immediately recognizable.
https://simplifier.neocities.org/4x4.html
- - - -
For display from small machines I keep going back and forth between simple memory-mapped raster screens vs. emitting a stream of, say, SVG to an external "display processor" (following the "Wheel of Reincarnation": "On the Design of Display Processors" http://cva.stanford.edu/classes/cs99s/papers/myer-sutherland... )
1024x768 is more than reasonable. Almost luxurious in a "small"/"personal" computing context, but in a good way. I still use computers with that resolution sometimes.
I started as an 8yr old, reading computer magazines, and initially coding in BASIC in 1K of RAM. I into Z80 Assembler and Machine Code at 10yrs - learning primitives like NMI's, Display DMA and Sound IO by hand with pencil, paper, and lots of reboot-causing mistakes. It was bruteforce, but still very influential in my understanding of a then-modern computer system.
Z80 was a simple-enough chip instruction set that I still remember most the mnemonics today, and many of the architectural principals are still valid even after so much time.
This is only true when you decide that the specific level of abstraction that you learned is the important one.
Sure, you knew the machine code. Did you know how the instruction set was implemented on the chip? The decode logic at a transistor logic to set the right signals to route your register to the ALU? Did you care about the equations that governed the flow of electrons through silicon?
Or did you trust the machine code to be your level of abstraction that Worked?
Also, the idea that you can say some abstractions (presumably in wide use) are "objectively" bad only makes sense if you've already applied your subjective criteria.
You can slightly the alter the claim to "most software engineers don't actually know how their code works at a level that's relevant for them to make good software" and it becomes solidly true.
Most (web) software engineers don't know anything about assembly, CPU cache, virtual memory, or pipelining, and application of knowledge of those things would change web applications from their current abysmal levels of performance to something acceptable.
Very, very rarely is knowledge of the microarchitecture, microcode, transistors, or physics necessary to make modern software reasonably correct and performant.
Most of the few software engineers that make their living writing code that needs to be fast, do know the things they need to know to make the code fast.
I don't agree even with your altered claim. Most software engineers do know how their code works at the level that they need into order to make good software.
This kind of thinking is why we can't have nice things!
If this were true we would have good software. As the world (currently) exists, we have a vast ocean of horrible software with a small number of islands of quality.
I'd argue "most" software engineers don't know enough. The fact that checking my bank balance online involves transferring 32 million bytes of information(!!) over nearly a third of a minute, or that bluetooth headphones have so much latency they're unusable for live music, despite radio waves traveling at the speed of light, or... any app written in electron, ever (or pick any other example of stuff sucking in modern life, it's ubiquitous)... these are all a result of engineers knowing way, way too little about how their stuff works.
Most people, including engineers, are idiots, slapping together components and using abstractions they have NO understanding of, stopping at an increasingly low bar of acceptability. (I make no claim to be special or otherwise a "non-idiot".)
correction: 5 million bytes of information, not 32. but still at least 4.9 million bytes too many.
The problem is that everyone has a different definition of "too much". Despite programming as a kid and now working on edge networking software at $TRENDY_CORP, I studied signal processing, distributed systems, and higher level math. I used to spend a lot of time with hardware. I knew layout engineers who used to scoff at hardware engineers that didn't know that their logic was going over the timing budget, hardware engineers who would scoff that folks writing firmware/embedded code didn't understand that their code didn't use the instruction pipeline correctly. Kernel developers who scoffed that OS developers didn't understand how kernel IPC works. And the list goes on.
The state we're in is only here because this is what the market is willing to tolerate. If you're designing the AV system for heads of state or the CEO of a large tech company, or maybe even a big esports competition, then you'll probably spend all your time optimizing for latency and jitter. If you're processing large amount of non real time data, you'll probably end up optimizing for throughput. Industrial control software usually has access to low-latency low-bandwidth links and need to work unattended for months at a time. Hardware that goes to space must be redundant and radiation hardened. Software has eaten the world, so if you're willing to take a pay cut and maybe get drug tested by your government, you'll have no trouble finding jobs with a different set of customer requirements.
The fact is, the modern internet is optimized for throughput and modern web apps are optimized for average user experience and ad revenue. Engineers working on net technologies are trying to push more through the pipe, latency be damned, because few people care about anything else. Most web developers are just trying to make their software usable enough to enable use of their product and ad revenue because very few people care enough to offer a market to these conpanies. At web startups you're struggling to make _anything_ and find anyone who's willing to pay you, let alone optimizing for some metric like latency. If you don't like this work, there's lots of fields that pay less but have different problems. You could work on MPLS VoIP networking to enable low-latency voice chat. You could work on high-throughput data transfers for research institutions to share sensor/telescope data. Avionics software has its own interesting challenges.
Personally, I'm knowledgeable and have a nerdy fixation on low latency, so I have a network of low latency services for my friends and family (along with a companion high latency high throughput set of services for bulk things like 4K video downloads). Some of my friends love using it, others like my parents barely understand the difference (except maybe that I'm not breaking up on voice chat as often). I recognize that this is my hobby and my passion but most people just don't care. I'm okay with that. I don't care about a lot of other things in life too that I'm sure somebody else cares about.
1. Indiscriminate use of third-party scripts and network connections, particularly for marketing cruft such as ads, analytics, and trackers.
2. Pulling in large blobs of code, particularly frameworks, because it makes things easier.
3. Back-end issues, particularly distributed monoliths disguised as microservices, delaying time-to-first-byte by 100s of milliseconds.
4. Lack of awareness of the latency and bandwidth characteristics of real users' devices.
Other reasons, too, but these are some big ones. Understanding CPU cache, virtual memory, etc. is way, way down the list, and certainly wouldn't "change web applications from their current abysmal levels of performance."
Mu: A Human Scale Computer - https://news.ycombinator.com/item?id=21242190 - Oct 2019 (12 comments)
So, a byte-code must be chosen to the project. Brainfuck is considered at first: it is extremely simple to implement but is rejected because has very little code density. Then, Chip-8 is considered: it is simple to implement and there are many programs and tools already available. Then p-code is looked at, but it is nowhere near as popular as Chip-8 and apparently not as simple to implement. Other vm's are considered but are rejected because they are not simple or not very popular: SWEET16, ijvm and tinybasic.
Now, what is a good choice for such a situation? What is a good byte-code for such an endeavor? Restrictions are: 64kb of RAM not counting graphics or overlays for drivers that can be dynamically loaded, possibility of running 3 to 10 tasks at the same time, with a good balance of code density and performance, easy to implement and possibly with available tools or good example programs?
[0] by which I mean the ability to tag functions and variables with an indication of what they're used for so the interpreter/jit is able to replace them with an efficient implementation if one is known to it. For instance, you possibly don't even need float types, just have routines for doing soft-float arithmetic tagged such that the interpreter knows they implement IEEE floating point operations that the processor may be able to handle on its own.
Maybe Mu is it. I don't know. My concern is that low level code with manual register allocations is too unproductive, and even C (not to mention C++ or Rust) is complex enough that I don't know what the compiler is doing at -O2, with or without TBAA, with or without restrict, etc.
Is it even possible to get a small understandable stack, and full Unicode support, OS-like text editing and keyboard shortcuts, system fonts, system font rendering and fontconfig, tab navigation to jump between widgets, maybe even OS file dialogs and accessibility? Lagrange is a Gemini client which depends on not much more than SDL (good), but doesn't use OS fonts rendering and text editing (bad).
* It still requires firmware. There's a whole lot of C down there. How deep do you want to go?
* No mouse. This is just my own ignorance. I can't get the damn IRQs and interrupts figured out.
* Doesn't work yet on real hardware. I live in Qemu. Debugging that is a whole new set of skills I need to learn.
* No networking, almost no persistent storage. Mu has a very simple and slow driver for ATA disks, but that probably won't suffice on most real-world machine configurations. There's 0 network drivers right now. I probably need a dozen to get any sort of coverage.
The stuff you mentioned around graphics and OS file dialogs, that feels easier once you're willing to put up with constraints like Mu's 1024x768 and so on. But yeah, there's major challenges on this road.
Partly due to these challenges, I've actually started to hedge my bets and make some compromises. My new project is https://github.com/akkartik/teliva which doesn't try to eliminate C, just minimize it. Linux kernel, libc, Lua (12k lines of C), some libraries for https. A gemini client is actually on my todo list there. I think I have everything I need to build it.
Would anybody like to compare/contrast this with https://mirage.io/?
As I understand it, unikernels want to let you bring your own application sources, and try to compile it to their substrate. Mu requires you to build your application for it. There's no compatibility with anything beyond the x86 instruction set (and Unicode).