I don't know what you mean about easily composing immediate mode API's, or agree that different immediate mode APIs don't need to know about each other. They depend on a lot of behind-the-scenes implicit hidden state (practically a hidden shadow-DOM-like retained mode), so I suspect in many cases they'd walk all over each other (especially text editors dealing with input focus and keyboard navigation). Unity3D has two immediate mode APIs, one for the editor and one for runtime, and they sure don't mix.

I've implemented various adaptor wrappers for composing different retained mode API's myself, including wrapping The NeWS Toolkit OPEN LOOK widgets in HyperLook widgets, which I used for the first Unix port of SimCity to HyperLook/NeWS. (The OPEN LOOK pin-up menus and pie menus and buttons and sliders are implemented in TNT, but I wrapped them for HyperLook (which has its own persistence system and class hierarchy), so you can dynamically create and edit them at runtime with property sheets and script editors, ala HyperCard.)

https://medium.com/@donhopkins/hyperlook-nee-hypernews-nee-g...

For X11/NeWS at Sun, we even made an ICCCM X11 window manager that wrapped X11 windows in NeWS tabbed window frames with pie menus! (The X11 window manager was written in object oriented "retained mode" PostScript code, subclassing standard and custom NeWS window and menu widgets, like tabbed window frames and pie menus. While PostScript has an immediate mode drawing API, it was driven by extensible "retained mode" widget instances and classes represented by PostScript dictionaries, pushed on the dict stack.)

Open Window Manager PostScript source: https://www.donhopkins.com/home/archive/NeWS/owm.ps.txt

Tabbed window extension:
https://donhopkins.com/home/archive/NeWS/win/tab.ps.txt

Discussion of problems with NeWS: https://news.ycombinator.com/item?id=15327339

Political discussion from the Window System Wars, about Sun's problems merging X11 and NeWS: https://donhopkins.com/home/archive/NeWS/sevans.txt

More recently (and more successfully), I've wrapped HTML components and floated them over OpenLaszlo/Flash (not so recently) and Unity3D (quite recently) retained mode user interface layouts in the web browser.

For example, I'm embedding an ACE code editor in a Unity3D retained mode user interface running in WebGL, that falls back to a regular TextMeshPro input field on other builds. There's no way you could do that practically with an immediate mode API.

WebGLAce_TMP_InputField.cs (C# retained mode GUI TMP_InputField subclass): https://github.com/SimHacker/UnityJS/blob/master/Libraries/W...

WebGLAce.cs (C# P/Invoke Unity extension wrapper): https://github.com/SimHacker/UnityJS/blob/master/Libraries/W...

WebGLAce.jslib (JavaScript library Unity extension, compiled by Unity to WebAssembly, converts between C#/WebAssembly and JavaScript data types and thunks messages back and forth between the browser and the Unity3D app): https://github.com/SimHacker/UnityJS/blob/master/Libraries/W...

WebGLAce.jss (ACE code editor adaptor, pure JS source loaded by the browser, as well as ACE JS libraries themselves): https://github.com/SimHacker/UnityJS/blob/master/Libraries/W...

Notice how WebGLAce_TMP_InputField simply subclasses the standard TextMeshPro TMP_InputField, and adds some more hidden state like the editorID and editorConfigScript of the corresponding ACE code editor running in the web browser.

All that is hidden from the code using it, so it doesn't need to come up with another place to store that editorID and editorConfigScript, or even know if it's getting an Ace editor under WebGL or falling back to TextMeshPro on other builds. That's what I mean by leveraging OOP to subclass existing components and hide internal state, which you can't do in immediate mode.

(My plan for non-WebGL builds that aren't already running inside a web browser, is to create an embedded web browser just to run the Ace code editor, and the C# WebGLAce_TMP_InputField API will remain the same, and it will just work transparently on different platforms. I want to support live coding Unity apps in JavaScript, but there just isn't anything for Unity that approaches ACE for editing code, so it's worth going through all the trouble to make an adaptor.)

How would you write a functional extension for Unity3D's old immediate mode GUI that let you embed an ACE code editor in a Unity WebGL app? What would the API and state management even look like? How could you make it platform independent?

And even if you solved all of those problems with an immediate mode API, by its very nature it still wouldn't enable you to build GUIs in the interface editor or store them in prefabs, and you'd still have to recompile you app (which can take half an hour with Unity) every time you wanted to tweak the user interface (which is why I like programming Unity apps in JavaScript as much as possible).

UnityJS Unity3D / JavaScript bridge architecture:
https://github.com/SimHacker/UnityJS/blob/master/doc/Anatomy...

UnityJS pie menu component for Unity3D, written in JavaScript, drawn with canvas, using TextMesh Pro labels:
https://github.com/SimHacker/UnityJS/blob/master/Libraries/U...

Uses a Unity3D pie menu tracker to translate low level input to high level events, written in C#: https://github.com/SimHacker/UnityJS/blob/master/Libraries/U...

Of course you can take it too far, trying to please everyone by combining the worst of all possible systems and then giving it a ridiculous sounding name (see "MoOLIT"), but we're discussing whether it's possible and practical, not whether it's desirable. And even if it's not desirable, it ends up being necessary.

https://en.wikipedia.org/wiki/MoOLIT

http://nova.polymtl.ca/~coyote/open-look/01-general/faq-doc-...

Embedding object oriented "retained mode" widgets with different APIs inside of each other is old hat and common for backwards compatibility. Whenever you write a new GUI toolkit, embedding widgets from the last toolkit is one of the first things you do (including recursively embedding widgets from the toolkit-before-last).

Concrete example: Microsoft lets you embed old fashioned OLE controls in Windows Forms / Presentation Foundation applications, which might be implemented in MFC themselves. And MFC is all about embedding old Win32 widgets implemented in C, and newer OLE components implemented in Visual Basic or whatever, in venerable C++ MFC user interfaces. Say what you want about how much Win32/MFC/OLE/WF/WPF sucks, and I'll wholeheartedly agree, but if you're running Windows, you probably have widgets on your screen using several different retained mode APIs embedded more than two levels deep right now.

https://en.wikipedia.org/wiki/Windows_Forms#Architecture