Here's Andreas Kling briefly demoing both and talking a bit about it: https://www.youtube.com/watch?v=1QYBvTy9QKE&t=519s
The difference might sound trivial but in practice it is like trying to dismiss editing text with Emacs by experiencing editing text in Notepad.
[0] https://adkaster.github.io/images/build/VisualBuilder.png
- Code-based UIs tend to work better with existing tooling, like comments and source control. You can freely customise your development environment, rather than being at the mercy of a single GUI app.
- Most serious UIs need code-like features, such as "for-each" to render a list of objects, or "if" to reveal a form when a checkbox is ticked. The easiest way to access code-like features is to write your UIs in code.
- You'll need to write some backing code in any case. Defining the UI tree and its "code-behind" in the same file could be considered more DRY.
- Live preview (or alternatively, hot reloading) will give you very quick iteration when writing a UI in code. It's not quite as good as drag-to-resize, but it's close.
- Automatic layout (which is non-optional nowadays) isn't necessarily a great fit for WYSIWYG editing.
- As React has demonstrated, the ability to quickly throw together custom components is extremely useful. Visual editors tend to make it more complicated and bureaucratic to define custom components.
- WYSIWYG editors are bad about making small unintended changes that can easily slip by undetected (Interface Builder in Xcode for example often changes XIBs/storyboards just by viewing them)
- WYSIWYG editors bury bits of configuration in inspectors that are only visible in certain conditions, e.g. a control being selected, making them less evident and more difficult to find
There are circumstances where I think they still work alright — for instance I still enjoy building Mac apps with XIBs in Cocoa, but there’s a reason for that: traditional desktop UI has much less of a need for flexibility and generally speaking, has far fewer moving parts since it doesn’t have to hide things as a result of limited screen real estate. Additionally, these apps will only ever run on Macs which further reduces need for flexibility/adaptivity.
For mobile and multiplatform on the other hand, I strongly prefer code. It just works better.
This trivial example lacks it, and places it simple logic inside the UI code. But what if we want to protect against negative numbers? Or want to increase the number with larger increments if we hold the button pressed? Etc.
Your Delphi setup isolates business logic from UI. Which may seem "overly complex" in trivial demoes, but will help you the very moment you write the first test or add some business logic.
It's also why I see so many React apps spiral into an unmaintainable mess within days after their "git init".
This is true for any library/framework/architecture, and the same problem is very prominent in Svelte/Vue/React/Backbone/Angular and everything else.
No. It's true for any library or framework that lack isolation or decoupling concepts.
In react (and many of the ones you mention) there is nothing on place that guides you into decoupling. It has nothing, not even conventions, that help a junior to put stuff in the right place (or to prohibit or make it difficult to put stuff in the wrong place).
Part of that is due to how in TS/JS everything can grope around in everything else. But the bigger part is lacking conventions, primitives and structure in the libs and frameworks.
Sure, a library (which react is) doesn't provide structure (it's a distinguishing trait from frameworks). But the many frameworks on top of React don't do a good job either. They either become some Enterprise Ready amalgamation of saga's, redux, message-bus, setups, or they offer too little guidance. And in all situations, it's still possible to just fire a fetch() or put data transforms or business logic within the UI. Only discipline keeps people from taking this "much easier" route.
And when only discipline stands between us and "the easier way for now", that "easier way for now" will be chosen, and pain in future will be felt.
At least Redux provides a semblance of immediately grokable data flow, this all gets worse with mobx which gives you all the flour you need to make spaghetti for the whole village. Worked on a codebase where you might have to chase down references across all sorts of files you wouldn't expect because everything is 'observable' so people, working 2-week sprints, just stop thinking about any kind of coherent structure cause it works anyway.
I've seen too many react projects that employ all sorts of enterprise patterns (amongst which redux) yet also wrangling-spagetti of useEffect and useState, often intermixed. There's one thing worse than having to unknot a mess of useStates: thats having to unknot a mess of useStates that is sometimes synced to and sometimes from and sometimes both, a redux global state.
So basically, the same as Cocoa/obj-C?
And then how about version control? Sure there could be (and is) underlying machine code, and you could try hard to make it human readable. But... IDK seems like a lot of effort to me for some small benefits.
Disclaimer: I have only very little experience with UI programming.
I don't know about current Delphi, but in Lazarus (which is kind of an open source and crossplatform Delphi) you set those rules visually. For example you can "draw" the UI by drag-and-dropping controls in a window/containers/etc and then you can add rules like "this button's left side will be 5 pixels from that label's left side and will be placed vertically so that it is centered relatively to the label". You can also set things like "this control (or container or whatever) will always be at the top/left/right/bottom edge of its window/container". This is done in the visual editor with immediate feedback (you can even resize the window/container while you are editing its layout to see how it behaves).
This allows you to make UIs that work not only across dimensions, but also handle different fonts, texts (for localization), scaling (for DPI) and themes. Especially important for Lazarus since its GUI framework has various backends that often look very different from each other.
> And then how about version control?
Lazarus (and Delphi - with the exception of some earlier versions - and really most GUI designers) save UIs in a text based format with a tree-like structure of key/value pairs, e.g. (i edited it a bit for brevity):
object Main: TMain
Left = 625
Height = 505
Top = 393
Width = 903
Caption = 'World Editor'
Menu = MainMenu1
Position = poScreenCenter
object plRenderContainer: TPanel
Align = alClient
BorderStyle = bsSingle
object plRenderWindow: TPanel
Align = alClient
BevelOuter = bvNone
end
end
end
This can easily be stored in version control and diffed to see changes (in fact in my own projects before committing something to VCS i check both the code and the UI files to see what exactly i changed).Look into how various design tools handle flexible layouts. Usually a combination of flexbox/something similar to flexbox or slightly more old-school; constraints.
Here is an example with Figma: https://gdwn.medium.com/how-you-can-create-really-flexible-a...
The window itself can have a layout control that stretches to fill the window regardless of resizing. Layout changes would cascade down through the tree of UI controls and everything would resize/reposition accordingly.
Generally writing UI code in Xcode (and presumably before that on NeXT as well) is a breeze and a joy. Work with your delegates, connections, outlets etc.
Not really in the case of Cocoa's Interface Builder (nib/xib files). There the artifact is basically a marshalled object tree of the actual UI objects, not declarative markup.
… assembles an appartments worth of new Ikea furniture…
Oh!
If you answer “brilliantly” I am genuinely curious to give it a go!
See it in action e.g. here:
Anyway, I went pretty deep on SwiftUI from the announcement, and started programming with Delphi 7 / Visual Basic 6. While I enjoy SwiftUI, it has some rough edges still, and it's been 3 or 4 years. Hopefully Apple can put things together this year, especially for macOS apps.
I agree that Delphi is leaps and bounds better than the web technology in popular use today, and every reason I've heard for why (increased DPI, variable screen sizes, etc.) are just poor excuses.
The web is where the money was, development approaches forked, and now the worse approach happens to be more popular.
I can't decide whether it's sad or funny what Microsoft is trying to do with Blazor. They solved their Desktop UI problems by offloading them to you with a browser (now you have the problems).
But the question here is also if it makes sense to basically have the same UI or even UI paradigms for such different types of environments.