The extra abstraction layers you're talking about are invisible to the user... while our GUIs are slower, and our processors faster. It feels like, after 30 years, we should be able to have our GUI cake and eat it, too.
In the "good old days" the user interface was 640px x 480px (original VGA[1], skipping past the original MDA, CGA, and Hercules graphics cards[2] since they predated "modern" GUIs). Then it was expanded to 800x600, etc. The programs of those days were hard-coded to the graphics adapter resolution. If a program did not support the graphics adapter you had, you had to run your GUI in lower resolution compatibility mode. Sometimes it didn't work at all.
In lower resolution compatibility mode, the program's display got uglier and uglier as the screen resolution went up.
The abstraction layer today is adaptive and high DPI. Since the abstraction layer abstracts away the actual display resolution, programs (generally) can take advantage of the resolution that is available on a given display without change, allowing a program to run on small hardware displays (phone/tablet form factor) up to mega 4K++ displays, looking better and better as the screen resolution goes up.
GDI was originally designed to run on printers as well as screens, where the DPI values are completely different.
The declarative model of CSS has nothing to do with it. You can specify pixel values in CSS if you like.
And many (most?) do... leading to the reinterpretation of what "pixel" means in the CSS spec. Yes, CSS pixel does not mean a physical pixel on the screen.
Integer pixel coordinates are right there in the most fundamental functions:
HWND WINAPI CreateWindow(LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam);CSS people still think a grid is a choice of "small" "medium" and "large" columns/rows. Haha.
> CSS people still think a grid is a choice of "small" "medium" and "large" columns/rows. Haha.
CSS Grid is literally Microsoft taking the WPF grid layout and porting it to the Web!
And even now it's still not mature and supported in all browsers.
> we don't need the new stuff
> how about we throw both away to shut everyone up, would that make either side happy?
There's nothing special about javascript the language. The nice thing about web development is that the really fast framework iteration cycles. And everyone complains about them, but as a result we have some fantastic APIs for UI development in javascript land now. (Eg, react.)
What I want to see is someone port those lovely abstractions across to native languages. For example, a port of choo[1] to swift on top of uikit would be gloriously fast, efficient, small and easy to work with.
Edit: I'll add, I frequently see people say that Windows XP was the best OS ever made. Why the rose-tinted glasses? It was the tail end of the era when hardware was getting faster, faster than software was getting slower.
Yes, I know, he's still around...
The thing is, using C++ instead of React for mobile development of a simple application would probably make me miss deadlines... So we just stick to whats popular.
This is absolutely not true.
Going to windowing GUIs from character-mode DOS was a massive usability improvement. No more exotic ctl-alt-function key combos (or control-control sequences for WordStar users like me).
Going from desktop apps to webapps changed the abstraction layer of how we access and share documents. No more installing software on the desktop. Docs are available on every computer we log into. Multiple people can edit the same document.
Maybe you don't care about document sharing and would be happy installing old school word processors and spreadsheets? That's a fair statement to make, but the market appears to be voting otherwise.
At least VS Code has to be installed. It is a plus for Google Docs & Co, but not universal. And in most cases, instead of installing you now have to create an account.
>Docs are available on every computer we log into. Multiple people can edit the same document.
Those features are completely independent from the platform the application uses. Those features are commonly implemented in web apps because for a long time they had no other choice, but cloud storage and collaborative editing can be equally well implemented in a destop application.
cough Blender ...
I would point to Eclipse as another classic example of "obviously designed by an engineer". There's tons of functionality under the hood and it's a fantastic jumping-off point for further customization... but its layout is intensely non-intuitive in so many ways compared to a purpose-built IDE.
Everything is locked away in menus and "perspectives". If you're writing a Java web app - do you want the Java perspective, the Java EE perspective, the Web perspective, or the Debug perspective?
I hear GIMP's no picnic to work with either but can't confirm personally.
It used to be that OSS was developed by people that actually used it. Maybe it wasn't pretty, it had a steep learning curve, but it got things done and was efficient once you learned how. Often you got fresh perspectives on how an interface could be done, since people got fed up with existing solutions.
Nowadays you get UX experts preaching how an interface is supposed to look like, which mostly means copying Apple or Google. You get tons shiny whitespace. Burger menus, because that's what "everybody is used to".
GIMP with "good UX people" would turn into a bad copy of Photoshop.
No, we don't. With Windows API there's no sandbox and extra embedded language overhead (it's still native code like in DOS, and even optimized better, able to use more available memory than DOS would allow, etc.).
Oh, and you also got the benefit of a FULL graphical interface over DOS. Here you have slower performance, extra cruft, bad apis AND the same final output (as a GUI app).
Not to mention that the Windows API UI toolkit, while bad, is sane compared to the web stack.
The lack of games was mostly due to reluctance of game developers to abandon Assembly and using directly PC hardware, specially because C and C++ compilers were "too slow".
And the "assembly" argument doesn't make any sense. You can program Windows games in assembly if you want.
Sure you can use Assembly on Windows and there were a few books teaching exactly that, but you weren't allowed to touch the graphics hardware any more, unless you were doing a graphics driver, and do all those graphic card tricks, specially mode X.
Completely disagree. Charles Petzold's HELLO.C is hundreds of lines of code. Hello World on the Web is, well, "Hello world!".
"Sane" environments don't force you to make up a distinction between "long pointers" and "pointers" if you want to conform to the house style in order to match 16-bit x86 real mode. Or route all events through one WndProc, forcing use of "message crackers" to poorly recreate the ergonomics of addEventListener. Or have to recreate the vector graphics stack not once but twice in order to deal with the lack of forward thinking (GDI, GDI+, Direct2D). Or deal with incredible apartment threading complexity to maintain VB6 compatibility. Etc. etc.
If you had said .NET, maybe. But Petzold-style Win32 is bad.
It's actually 87 lines of code, with a disclaimer comment, ample empty lines, a callback to play a wav when clicked, and an error message for when it's not run on NT. So, like 30-50 lines of actual Hello World necessary code. And that includes the starting up boilerplate.
That's about as relevant as complaining about the large binary size of a hello world program in a language creating static binaries. It might be larger than expected, but it usually includes a whole runtime. So once you add actual code, the binary's size doesn't scale linearly with the code size.
For comparison, a modern CSS "reseting" file, which just removes empty values is usually larger than the hello.c example.
This is the problem with trivial/contrived examples. They don't show you how the thing you're discussing scales in actual use.
In this case, the hello world in HTML is not representative of what you need to do to create a medium/large SPA in HTML.
And the old Windows api you could always wrap in higher order stuff, or even use as a basic layer to create your own UI library (still native).
The web stack, because of how it is done, you can't.
Petzold's Hello World is far more than what I'd consider a Hello World in Win32, because in addition to what you noted, it also creates a "full" window with all the associated complexity of managing its drawing yourself. A more suitable Win32 Hello World is not that much more complex than the traditional C one:
#include <windows.h>
#include <winuser.h>
int main() {
MessageBox(0, "Hello World!", "Hello World!", MB_OK);
}
From there, one can progress onto "dialog-based applications", where the bulk of the layout is declarative (in the resource file) and the C part is two functions, a callback for messages and a main() which just calls DialogBoxParam(). No WM_PAINT handling is necessary for those. A "full window" application is actually not necessary for many use cases. I've been working with Win32 for over a decade and a half and written at least a dozen little apps for various things, but the vast majority of them are not "full window" apps.In other words, I'd say Petzold was at least partially responsible for giving the impression that Win32 is impossibly complex even to start with. Fortunately others have come up with better introductions like http://www.winprog.org/tutorial/ or even https://win32assembly.programminghorizon.com/tutorials.html since then, but it seems that the damage has already been done and a whole generation of programmers have gotten the "Win32 is hard" notion embedded into their minds.
I was unfamiliar.
As much as I want as few layers between me and the hardware as possible, I would rather have many sane layers like much of the web than 1 insane layer like the win32 API. It doesn't follow good C, C++, std library or other conventions. Many functions have multiple poorly documented modes based on which structs you pass are empty or null pointers. It also just fails often for no reason I can understand, and the distinction between windows application and console is quasi magical and counterproductive.
Posix... Is a blessing by comparison. Every time I need to touch it it take me something like a single hour and I have a function that works reliably and just does what I need. Until we get to X11 and manipulating those windows. Then I just want to punch everything, but at least X11 works once the code is written, even though its inside out and backwards.
Now I just strongly prefer to use a good library to get at OS facilities. Things like SDL, boost or Intel Threading build blocks, etc. They are fast and generally tight enough I can open them and understand down to the hardware when I want.
Moving from text-based to graphical is a much different shift than what we are talking about here. The idea here is that we are creating many abstractions to get the same basic result. I can't rewrite Atom.io for DOS, but I could rewrite Atom.io to use the Windows API directly rather than being Electron-based.
We're talking about VS Code using 13% of the CPU while idle to render a blinking cursor. What benefit does the user get from this? We could render a blinking cursor with less then 13% of a much less powerful CPU years ago.
(Not that Qt is a bad library, but it's bizarre that such an important area is so neglected by our industry).
And it does seem very very strange. I'm imagining this Socratic dialogue:
---
Socrates: What is the most popular programming language?
Developer: Java.
Socrates: And why is Java so popular?
Developer: It's the first language most people learn nowadays, so everyone knows it.
Socrates: So it's popular because it's popular?
Developer: Well, it's very similar to C++, which was the most popular language when it first came out, so it was easy for people who already knew C++ to learn.
Socrates: So why not keep using C++?
Developer: C++ had a lot of problems that made it hard to use, and Java solved a lot of those.
Socrates: Such as?
Developer: If you wrote an application in C++ that ran on any given operating system, like Windows, you wouldn't be able to run the same code on another operating system like Linux or Mac; you would have to rewrite much of your work from scratch to support more than one operating system. Java is "write once, run anywhere." Your Java program will run exactly the same way, without having to rewrite anything, on any operating system that has a Java implementation.
Socrates: Interesting! Can you show me?
Developer: (Writes "hello world," demonstrates it runs the same in both cmd.exe and Bash)
Socrates: And that works with real programs too?
Developer: What do you mean? This isn't a very long or useful program, but it is an real program.
Socrates: What's special about what you just showed me? Can't you write these command line things in any language? Look: I learned a bit of Python a few years ago. (enters python -c "print 'Hello, world!'" in both terminals)
Developer: OK, maybe that wasn't the best example, but when you're doing more complicated stuff it gets harder and harder to write code for more than one operating system in a language like C++, so a language that runs the same everywhere, like Java, or Python, is better to have.
Socrates: So like an application that you would install?
Developer: Exactly!
Socrates: OK! So could you show me a real application then? Like, it says "Hello, world!" in a window, with a menu and buttons and stuff? And it will be the same on both Windows and Linux?
Developer: No, that's not possible.
Socrates: Hm?
Developer: You can't do that in Java.
Socrates: So, Java is the most popular programming language, but you can't use the programs you write in it?
Developer: Alright, you got me there. Usually Java is used for writing applications that run on servers, not PCs.
Socrates: Servers?
Developer: Yeah, like if you go to a website, there might be an application on its server to fetch your account information from a database.
Socrates: But why do you need a special application for that? Can't you just ask for the information you need directly?
Developer: Good question. We're moving in that direction. But for some things you really do need some kind of custom logic, and for those things Java is a good solution across different platforms.
Socrates: What different platforms are there in servers?
Developer: There aren't really that many platforms. Almost all servers run Linux. But there's also a few that run Windows, or FreeBSD, which is very similar to Linux.
Socrates: So if you were on a less popular operating system, like Windows, you would use Java to be compatible with Linux?
Developer: Probably not; really, the only reason you would use Windows on a server instead of Linux is if your application were written in C#, which is Microsoft's Java competitor.
Socrates: So Java is the most popular-because-it's-popular programming language you can't write programs in, and it's useful because it runs on every platform, on only one platform?
swing? awt? javafx?
Ugh, reddit's standard, snarky response: "you do realize... right?"
There's simply no way to get around the fact that by and large, many in-browser apps are poorly performant by any modern standard.
To me, it seems like there's a faction within the web development community whose goal is to take things that worked perfectly fine as native apps and re-implement them with poorer performance in the browser, with seemingly no benefit.
I wish these people all the success in the world, if that's what they enjoy doing. But for the most part I simply cannot tolerate the work they produce.
Effectively we are back to the world of time-share terminals.
This realization that always-connected apps might be joined by disconnected apps is emphasized when looking to markets across the world. There are more disconnected people in the world than always-on, high-speed, low-latency connected. There is a burgeoning middle class characterized by sporadic, low-speed, high-latency connections, who are willing to spend some money online, for those times they make it online. They might spend pennies each today, but whoever captures those markets is addressing billions of underserved online customers. I'd take a billion $0.01 payments a day any day.
But if you set the cookies
document.cookie = "age_checker=pass; expires=Thu, 18 Dec 2037 12:00:00 UTC; path=/";
document.cookie = "is_legal=yes; expires=Thu, 18 Dec 2037 12:00:00 UTC; path=/";
It does work elsewhere, too. (Otherwise it just redirects to your local wolfenstein info site)Just because a design introduces extra indirection into a system does not mean that the design is providing any abstraction.
Likewise just because a design changes from one implementation to another does not mean anything has been abstracted.
Your example of moving from DOS to Windows is really good for illustrating this. DOS had almost no hardware abstraction support, you had to include drivers for a lot of hardware into your application. Moving from DOS to Windows 3.1 only provided abstractions over the video drivers, for example when it came to network cards you still had to use DOS drivers.
Moving a text editor from DOS to Windows does not provide you with any abstractions for things like the cursor. It is only changing the API for the sake of having your text editor run on a different platform.
Guess what? This is the same with trying to get your cursor and text rendering working on a web browser. There is absolutely no abstraction here, you are just changing your code to work with the very awkward DOM API.
But hey, thank god we finally have a framework we can inject ads in at will.
When Windows was developed, we had enough CPU power to do the basic tasks people wanted done with a computer at a reasonable speed - the idea was that spare capacity was being traded for user friendliness.
For some applications, even today, when maximum efficiency is necessary, purpose built machines ('soldering together the flip-flops that make up your logic and memory') are still used - it's just that it's often an ASIC that is fabricated.
And in many cases that led to an instant drop in productivity. Those old green-screen systems were not pretty but they were quite efficient to use.
Having worked on the system myself, they were right (this was as a noobie to both systems).
There is something to be said for a small, tight system.
This because the doctors insisted on using a DOS based patient journal, as they could operate it completely by keyboard while maintaining a conversation with the patient.
I speculate that one reason for this is that DOS allowed each program to have full keyboard access, while Windows and other GUI has to reserve certain keys for managing the UI (switching between windows etc).
Thus what was earlier a series of single key presses now involves holding down a modifier for the duration. And that is if the developer even remembered to put in a hotkey for said action.
It's just that software makers don't do it; most everyone thinks everyone loves to do things with mouse et al.
Ultimately, computing has always been one of abstraction from the lower "layers". Taken far enough, one could spuriously argue that if you aren't soldering together the flip-flops that make up your logic and memory, you just aren't being efficient...