Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declarative UI: Swift/Dart vs Qt/QML approach #2065

Closed
medvednikov opened this issue Sep 22, 2019 · 59 comments
Closed

Declarative UI: Swift/Dart vs Qt/QML approach #2065

medvednikov opened this issue Sep 22, 2019 · 59 comments

Comments

@medvednikov
Copy link
Member

medvednikov commented Sep 22, 2019

Hi,

Update

V UI has been released, V itself is used for declarations.

I'm working on declarative UI right now.

Which approach do you think is the best: Swift/Dart (using the same language for declarations) or Qt/QML (using a smaller cleaner different language)?

It's nice to have only one language, but the "VML" approach looks cleaner to me.

Also, I'd need to modify V a lot, for example to allow things like [TextBox{}, Button{}].

@nedpals
Copy link
Member

nedpals commented Sep 22, 2019

I like Dart's approach. It's easy to debug and understand the properties of the component.

@Delta456
Copy link
Member

I like QML's approach because it's quite small and is more easy to understand IMHO .

@dumblob
Copy link
Contributor

dumblob commented Sep 22, 2019

Hi @medvednikov, a good UI is undoubtedly a valuable endeavor. Believe me though, it's kind of waste of your precious time. Read carefully the discussion vlang/ui#1 (comment) on this topic and dive thoroughly into the technical story (part 1, part 2) behind making modern UIs as referenced in the post.

To put it bluntly, don't even try to create yet another retained UI (as QML, Dart, WPF, Qt, GTK, ... you name it). It won't be used much and your work won't bring the fruits you'd expect and like to. There are literally hundreds of cross-platform UIs (sometimes embedded into applications, sometimes separated as a library). Your UI reminds me a lot of Lua tekUI and of QML. Don't recreate them, it's pointless 😢 (unless you want to avoid bindings to existing good UI libraries and an the same time make V a mainstream language, not a "better one" as I understood it until now 😉).

All this boils down to can be summarized as:

For UI all approaches are equally necessary - declarative compile-time retained, then declarative run-time retained, then compile-time immediate (i.e. non-declarative), and finally run-time immediate (i.e. non-declarative) mode.

Above-mentioned frameworks do offer though just the declarative compile-time retained approach and partially the run-time retained, but not at all compile-time immediate nor run-time immediate.


P.S. Full-featured UIs are about as complex as full-featured programming languages offering builtin parallelism and stdlib. UIs can eat up all your time for years...

@medvednikov
Copy link
Member Author

@dumblob there's no good cross platform native desktop UI library, this was one of V's main features. I've already written thousands of lines of UI code, I don't see a reason not to release my work :)

@ylluminate
Copy link
Contributor

ylluminate commented Sep 22, 2019

@medvednikov I must lean towards purist methodologies such as keeping it declared in the language itself vs having to remember something else or breaking out into a different methodology. When you get into generative aspects and such it seems superior to keep the language completely universal...

If i'm going to go for friendlier syntax, i'd just stick to Ruby. V is a far cry from the elegance of Ruby in terms of syntax and robust expression, but that's not why I value V and so i tend to think sticking with the "one way" mantra is the right way here.

Sidenote BTW (😀): I'm always for reducing boiler plate and simplifying syntax. If I could have V in Ruby syntax buddy you can believe I'd be first in line (!), but I realize there are tradeoffs. Hopefully at some point someone will take the initiative to write Ruby in V (similar to this Ruby with Rust project). :)

@gslicer
Copy link

gslicer commented Sep 22, 2019

I plead for declarative UI in V syntax

@dumblob
Copy link
Contributor

dumblob commented Sep 22, 2019

I've already written thousands of lines of UI code, I don't see a reason not to release my work :)

If it's only about releasing, then sure, go ahead 😉.

there's no good cross platform native desktop UI library, this was one of V's main features.

Well, this is a very bold statement and I'd argue it's exaggerating a lot. I know several very good cross platform libraries which are very hard to beat in their functionality and overall quality. Some of them are (very) minimalist, some of them leverage programming language(s) of their choice (pretty much like your declarative UI library uses V and will be hard(er) to use efficiently and as easily in other languages), some of them are more modern (allowing tighter integration with constrained platforms like web), etc.

So, generally there is no need for a cross platform UI library as they already exist and work well (might be less known, but that's another story). The only issue UI libs have is, that they are cumbersome to use. Still in each of them you can in the end achieve anything you need (beginning with animations, going through canvas-like painting up until fully dynamic behavior of widgets & any visual objects including their size/shape/content/position and their creation and/or destroying on demand in reaction to e.g. user input).

Don't take me wrong, but I'd rather say, don't try to push yourself to create a good UI library, as it's provably impossible with a declarative UI in the first place (in short: many of the above-mentioned requirements "animations ... on demand" are impossible with declarative UIs unless they're to be significantly more complicated then all the web CSS stuff nowadays).

@medvednikov
Copy link
Member Author

medvednikov commented Sep 22, 2019

Well, this is a very bold statement and I'd argue it's exaggerating a lot. I know several very good cross platform libraries which are very hard to beat in their functionality and overall quality.

I'm very interested in what these are. They key is native and cross-platform.

So Qt, GTK, Nuklear are not an option.

I can think of only wxWidgets and libui, and the latter is still at a very early stage and not under active development.

@dumblob
Copy link
Contributor

dumblob commented Sep 22, 2019

They key is native and cross-platform.

Assuming native means

looking exactly as native, behaving as native, using native widgets/constructs everywhere where there is feature-set equivalent available

and cross-platform means

Windows, X11 (i.e. Linux/BSD, ...), macOS, maybe Android

then off the top of my head (in random order): .NET WinForms, libui, Python tkinter, wxWidgets, [Red/VID](https://doc.red-lang.org/en/vid.html , VCLua, Qt (it mimicks it very well), QML (same as Qt), GTK (yes, it uses native DLLs for look&feel), IUP, Solvespace GUI abstraction, ...

Regarding the risk of (not) being developed, it's the same risk of any project disregarding whether proprietary or open source. Btw. V and it's ecosystem has this risk way higher than libui because "nobody" uses V, but hundreds of active users use libui.


(Not speaking about the fact, that libui is actually being actively developed - not sure where does the misinformation about abandoned development come from. Also libui is way ahead of V and it'll stay so for months, maybe years even if the V's development pace won't decrease.)

P.S. Btw. libui is also a perfect showcase why retained UIs are the wrongest decision for UI development - look at what's on the libui TODO list to get a grasp of what's needed for retained UIs, but is absolutely unnecessary e.g. for immediate mode UIs.

@ylluminate
Copy link
Contributor

Ultimately we need a native facility for UI implementation in V that provides native "widgetry" for each platform. For Windows and macOS that means to provide access to these systems' own UI toolkits with V interfaces. For Linux that obviously means something a little different and that, as you've noted, has been done via mechanisms you already have in place. Furthermore WASM and JS are also going a native and customizable UI interface that is immediately provided as well in this same vein (so it's essentially lumped in with Linux). From what I can tell you're on the right track @medvednikov.

I hear what @dumblob is saying, but I fear it may not hold true in this situation. Could libui fill this void and facilitate a UI for each platform with the necessary cross-compilation requirements that V needs to cleanly provide this? I don't know, I guess only you @medvednikov really can answer this. If V-UI is does this and does it cleanly and efficiently in native V then perhaps it's better and more maintainable than going with an existing C library.

If libui is even an option, for example, would it be time to create what we previously discussed with this back-and-forth tooling that will facilitate translation in both directions and diffing in order to keep projects in sync? Would that be a better investment of time? Again, I don't have the answer to this.

The one thing that I know is that we very much need a V-UI facility and it's something that cannot wait. It's also something that needs to be - LIKE V - cross compilable in every direction.

C proper has failed at this goal over the decades. It's a shame because C was supposed to be what V is. Everyone who has ever set out with C has effectively lost their way and got caught up in proprietary thought that has now yielded all of these platforms. It was a terrible mistake. Microsoft & Apple started the mess to a large degree (I know there were licensing issues at that time, but there were ways around it). Steve Jobs tried to bring some sanity back (and did) with NeXT, but here we are with Linux and this nightmare fragmentation. Too many of us hate GTK. Qt just simply didn't win thanks to the crap that went on with that circus. Etc. Etc. Etc.

So I guess at the end of the day I go back to my original thoughts: Alex, you've put a lot of work into this. You've done an amazing thing in a short period of time just bringing forth what you have. You have your own GUI needs with apps you've been working on. We need a true cross platform UI lib. Can V-UI do better than all of the other options and work in V's Live development mode? If all of this is the case, then let's do it your way and see what happens. And if all of this is the case, let's keep it in pure V.

Sometimes naivety and fresh perspective, as problematic as it can be, is the solution in this twisted metal wreck of computer science and software that presently exists.

@medvednikov
Copy link
Member Author

then off the top of my head (in random order): .NET WinForms, libui, Python tkinter, wxWidgets, [Red/VID](https://doc.red-lang.org/en/vid.html , VCLua, Qt (it mimicks it very well), QML (same as Qt), GTK (yes, it uses native DLLs for look&feel), IUP, Solvespace GUI abstraction, ...

.NET WinForms (Mono) is not native, the link you referenced mentions that:

Why Not Use Native Widgets?

It's also C#, which makes it very hard to usefrom C.

Qt is anything but native. It renders everything, and Qt apps, just like Java GUI apps are notorious for their "un-native" look. I use a Qt password app every day (KeePassX) and it's very visible. Besides, Qt is a multi gigabyte C++ monstrosity with a custom C++ dialect, so it's not easy to integrate it into a small language like V.

GTK is just... No comments :)

libui is a one person project mostly that's still in alpha after more than 3 years of development. andlabs/libui#274

libui is also a perfect showcase why retained UIs

If we want to have a native toolkit, then we have no choice but to use retained UIs, because that's what Win32 and Cocoa are.

I know that it's not 2007 anymore, and people don't care about the native feel that much. And the desktop app market is stagnating and being replaced by mobile. I also realize that what I'm doing may look like

But I'm 100% confident that's the right choice.

From the reviews I received, people are tired of 200 MB tray apps written in Electron/JavaScript just because there's no good and easy to use cross-platform UI toolkit.

And like @ylluminate mentioned, this is all going to be in pure V, with hot reload and cross-compilation, which is something none of the existing desktop toolkits offer.

@ylluminate
Copy link
Contributor

@medvednikov is spot on here. The comic is apropos, but (strangely) sometimes this is okay. I've been a project manager for an engineering firm and software engineer for a long time. I understand this ecosystem and frankly the ecosystem is so horrifically painful.

This issue about memory could be likened to a massive infection upon the software industry. It's like the visible head on a massive pustulant cyst on someone's face or head that they're trying desperately to hide, but it keeps growing and growing. Google is a nightmare with their Chrome practices and the web devs who have adopted technologies such as Chromium/Electron are compounding the situation. This kind of insanity must stop.

I agree that this SEEMS like we're going to end up with a mess, but I believe Alex is right. I may not be excited about some things like like spending time on making a Discord replacement due my desire to see that time dedicated to V-UI and other pet features, but ultimately the UI (today) is as integral and inextricably connected to success as the language's innate stability and robustness itself... :s

@gslicer
Copy link

gslicer commented Sep 22, 2019

@dumblob perhaps we should give @medvednikov a chance to show what he has built until now and if this could be an option to go or better to offer V bindings to existing UI frameworks

btw: I consider GTK+ as one of the "native" GUIs under GNU/Linux (because it supports very well Wayland) - another one supporting this protocol is Enlightenment (might be worth to take a look into it)

@dumblob
Copy link
Contributor

dumblob commented Sep 22, 2019

I do fully understand what @medvednikov, @ylluminate and others expressed here. I have to admit, it's my dream for almost two decades now. The one and only one obstacle which makes me rather pessimistic about the (current) plan for V UI is what @medvednikov wrote about V UI:

If we want to have a native toolkit, then we have no choice but to use retained UIs, because that's what Win32 and Cocoa are.

Which in stark contrast with what @ylluminate wrote:

Sometimes naivety and fresh perspective, as problematic as it can be, is the solution in this twisted metal wreck of computer science and software that presently exists.

and thus makes its way directly towards the 15. competing standard from the perfectly fitting xkcd comic.

It's fine to have V UI being the lowest common denominator across platforms. It's small, easy to maintain, fully native, fast. This'll then become a slightly less capable IUP but for V and not Lua. Originally I misunderstood and thought that V UI shall be more capable - therefore all my "warning" comments which you can ignore now 😉.


.NET WinForms (Mono) is not native, the link you referenced mentions that...

Yeah, just the behavior is native (rendering isn't). Still, WinForms theming is better than in Qt and GTK and an average user wouldn't often probably notice.

libui is a one person project mostly that's still in alpha after more than 3 years of development. andlabs/libui#274

It's one person project, but as I linked above it got forked many times with many active contributors and active merging => it's far from being dead. Also the linked thread andlabs/libui#274 clearly states it's not dead at all plus defines a roadmap etc. Last thing is the "alpha" state. Well, in practice libui is well usable (even the number of GitHub issues underpins it - yeah, 139 for such a big project means "all is perfect") with hundreds/thousands of users. The libui author is underestimating a lot - compared to other about as complex projects it would already be 1.x. On the other hand, libui is IMHO not a good fit for V for other reasons.

with hot reload and cross-compilation, which is something none of the existing desktop toolkits offer.

The following is not meant to disappoint anyone, but this is simply by far not true - e.g. Red GUI is unbelievably capable and offers hot reload (even better than V as one can edit the underlying application pretty much like in smalltalk environments), full cross-compilation (done right) for Windows, macOS, Linux (GTK), Android (!), etc. and is super fast.

Let's stop comparing thuff and rather rationally discover what everything can be done with the lowest common denominator of retained UIs. If not capable enough for V's basic needs in stdlib, then rather skip this completely and don't make it into V's stdlib at all and take some existing promising lib like Quarks, accommodate it to V (in case of Quarks even a rewrite in V would be a sane solution), maybe even use some native widgets as backend for uses matching the lowest common denominator and finally add it to VPM.

@gslicer
Copy link

gslicer commented Sep 23, 2019

@dumblob one toolkit you referred to, catched my attantion: Nuklear - looks very minimal but flexible at the same time to me.

Aalthough not using native widgets, perhaps "native" is overrated and sometimes even boring and restrictive?

There are even Go bindings for it: Go-Lang UI and they show the architecture for such bindings can be realized.

In case you find Nulear too simplistic, there is one other interesting "non-native" toolkit called dear imgui having an impressive variety in its gallery

@M4SSD35TRUCT10N
Copy link
Contributor

@medvednikov Stick to pure v. IMHO It's easier to learn. And with a third or first party visual tool the UI will be done in no time (one thing I liked on MacOS back then were their developer tools).

Easy language, clear way to implement something, then build tools on top of that to ease development process. I would like to see what you've achieved so far.

Keep up the good work!

@priezz
Copy link

priezz commented Sep 23, 2019

+1 for SwiftUI/Flutter approach. It could be used, however, for both, native and non-native widgets.
For non-native I would like to see the binding to Nuklear (as the smallest dependency-free cross-platform library I know), with the same sugar as for native counterpart. In many cases non-native UI is preferable. I mean games and other staff, which requires deeply customized look.

@medvednikov
Copy link
Member Author

@priezz the graphics module (gg) is going to have a non-native UI toolkit for games, webassembly UI, and Linux UI (GTK is not going to be used on Linux).

@priezz
Copy link

priezz commented Sep 23, 2019

@medvednikov , thank you, good to know! Is it gg, which is to be used for custom UI elements (like charts)? If so, the bindings to non-V libraries are really not necessary. Do you think of the unification of the use of native and non-native elements?

@medvednikov
Copy link
Member Author

Yes, things like charts will be unified.

But ui.Button is a native Windows/Cocoa widget, and gg.ui.Button is a custom widget rendered via OpenGL/DirectX/Metal/Xlib

@priezz
Copy link

priezz commented Sep 23, 2019

Actually, the question is, if it would be possible to use custom staff like gg.ui.Button together with the native elements, i.e. inside ui.Panel, or it will be necessary to replace the whole thing with the gg version?

@ylluminate
Copy link
Contributor

I think one thing we'll want to do is to wrap this such that when we build an interface the system will be smart enough to choose ui.Button or gg.ui.Button based on whether or not the target has native components (ie on Mac and Windows it will use the native; while on WASM or Linux it will use non-native with the accompanying desire UI graphic definition, however that will be defined).

@medvednikov
Copy link
Member Author

medvednikov commented Sep 23, 2019

Yes, there will be a way to draw anything next to native controls, including gg.ui controls.

@medvednikov
Copy link
Member Author

@ylluminate of course, if you use ui.Button on Linux, it uses gg.ui.Button behind the scenes. Same with WA.

@tomByrer
Copy link

I prefer the notation on the right side (V); it is closer to JSON which I'm used to.

IF you were to go with left side (VML), then please get rid of the brackets & just use a YAML format.

@arnaudchenyensu
Copy link

I really like the syntax and approach taken by elm-ui.

Might help you a bit for the syntax :)

@ylluminate
Copy link
Contributor

ylluminate commented Sep 24, 2019

@arnaudchenyensu your remark about elm-ui is interesting and this talk about that is also fun and really interesting: https://www.youtube.com/watch?v=Ie-gqwSHQr0

I don't know if it needs to be exactly like this since we're talking more about app UI design, BUT I could see this working for a web system... and maybe I'm just not able to completely associate this with app design since the video itself is more in the context of how crappy CSS is... LOL

I suppose that this could eventually (I don't necessarily know if @medvednikov has this as a priority right now) be used in a v-ui-web library to somehow take v-ui to the web also as an abstraction somehow... Or perhaps this could even be brought to UI design generally.

Mainly just thinking out loud after poking about...

@arnaudchenyensu
Copy link

@ylluminate

I believe that elm-ui is a good abstraction for UI design in general and not only web. It really shows how to handle layouts with simple and understandable words.

The adding benefit for V will be to have only one UI library that can be cross compatible.

@dhonx
Copy link
Member

dhonx commented Sep 27, 2019

@dumblob there's no good cross platform native desktop UI library, this was one of V's main features. I've already written thousands of lines of UI code, I don't see a reason not to release my work :)

Go on ... !!! That is an impressive work ... !!! 👍 💪

@Richiban
Copy link

Richiban commented Sep 27, 2019

I'd also look to Kotlin's builders for inspiration: https://kotlinlang.org/docs/reference/type-safe-builders.html

Here's a snippet:

fun result() =
    html {
        head {
            title {+"XML encoding with Kotlin"}
        }
        body {
            h1 {+"XML encoding with Kotlin"}
            p  {+"this format can be used as an alternative markup to XML"}

            // an element with attributes and text content
            a(href = "http://kotlinlang.org") {+"Kotlin"}

            // mixed content
            p {
                +"This is some"
                b {+"mixed"}
                +"text. For more see the"
                a(href = "http://kotlinlang.org") {+"Kotlin"}
                +"project"
            }
            p {+"some text"}

            // content generated by
            p {
                for (arg in args)
                    +arg
            }
        }
    }

It works in Kotlin because the syntax html { ... } is actually a call to a higher order function, equivalent to something like: html(() => { ... }).

However, the lambda is a special kind of lambda with a receiver of the HTML type, meaning that inside the lambda body all the members of the HTML type are in scope. So,

html {
    head {
        title {
            ...
        }
    }
}

is the equivalent of:

html({ h -> 
    h.head({ hh ->
        hh.title({ t->
            ...
        })
    })
})

I think it's a wonderful and powerful syntax feature.

@gslicer
Copy link

gslicer commented Sep 27, 2019

V already supports higher order functions (see example below from the Docs)

fn sqr(n int) int {
        return n * n
}

fn run(value int, op fn(int) int) int {
        return op(value)
}

fn main()  {
        println(run(5, sqr)) // "25"
}

@dumblob
Copy link
Contributor

dumblob commented Sep 27, 2019

@Xananax

I like when interfaces can be augmented by visitors; it's a very useful pattern for exposing components that work as they are, but can acquire additional functionality without being completely replaced.

Not exactly sure what you mean by "augmented by visitors", but pure "runtime dynamics" (as outlined above: "beginning with animations, going through canvas-like painting up until fully dynamic behavior of widgets & any visual objects including their size/shape/content/position and their creation and/or destroying on demand in reaction to e.g. user input") is only achievable with immediate mode UI libraries, but impossible with native cross platform (thus retained) UI libraries.

@gslicer
Copy link

gslicer commented Sep 27, 2019

interfaces augmented by visitors

Sounds to me as "inheritance" in OOP - you basically take a struct and add some additional attributes and maybe also additional "member functions"/"methods" (in V receiver functions) which extend the interface

@Xananax
Copy link

Xananax commented Sep 27, 2019

It's different enough from OOP to be unrelated.

Let's say I have this structure (pseudo-code, language agnostic):

{ element: 'post', children:[
  { element: 'input', name: 'title', type: 'text' },
  { element: 'input', name: 'body', type: 'text' }
] }

I could pass it to a visitor that produces:

{ element: 'post', children:[
-  { element: 'input', name: 'title', type: 'text' },
+  { element: 'input', name: 'title', type: 'hidden', value:'today()' },
-  { element: 'textarea', name: 'body', type: 'richtext' }
+  { element: 'input', name: 'body', type: 'text' }
] }

That's a modification.

I could do:

{ element: 'post', children:[
+ { element:'label', content:'title', children: [
    { element: 'input', name: 'title', type: 'text' }
+ ]},
+ { element:'label', content:'body', children: [
  { element: 'input', name: 'body', type: 'text' }
+ ]}
] }

That's an augmentation

I could do:

{ element: 'post', children:[
-  { element: 'input', name: 'title', type: 'text' },
  { element: 'input', name: 'body', type: 'text' }
] }

That's a removal.

It's important to note that the visitor:

  1. can have run-time custom logic; augments certain things, deletes others
  2. stays declarative: records are modifiable at anytime by any function, without hidden state
  3. are stackable: the same structure can go through a chain of modifiers, depending on final output
  4. are not linear: you can apply transforms in any order, or a custom order, or fork to different transforms according to complex logic

The usage is to display the same base record in different views with minimal logic.

post |> addLabels |> addHelp |> addRequired |> addAction |> toForm 

post |>  bodyToRichText |> hideLabel |> autoDate |> isAdmin 
	? |> toForm
	: |> inputsToDivs |> addComments |> toStaticView

@dumblob
Copy link
Contributor

dumblob commented Sep 27, 2019

@Xananax in your examples are all possible paths the visitor can take known in compile time. So that has actually nothing to do with runtime and is easy to implement disregarding language, syntax, logic, structures, data, abstractions, whatever - that's called "retained state" in UI terminology.

But if there are paths (for the visitor) which are not known in compile time (or it would be futile to find them in compile time - e.g. due to billions of them), then you really need something in runtime which is usually abstracted as "immediate mode" in UI terminology (imagine main loop of 3D games where one iteration of this main loop produces one image for your display).

@Xananax
Copy link

Xananax commented Sep 27, 2019

Of course my examples are trivial, they are examples, and as such, I've kept them minimal, in knowledge that people could infer more complex situations. The point being, if the API is declarative and can be augmented, then you (or the compiler) can choose which parts can be pre-compiled, and which need to be generated at run-time.

Also, I know we're currently discussing desktop UIs, but I disagree that we should adopt a graphical API terminology nonetheless. Widgets are widgets, and a declarative, manipulatable API allows widgets to be reused by different renderers. If a common API is agreed upon and entirely made of plain records with no hidden state or methods, then people are free to implement renderers for Curses, HTML, or whatever else they please.

@dumblob
Copy link
Contributor

dumblob commented Sep 28, 2019

@Xananax it seems we're talking at cross purposes. The current situation:

  1. @medvednikov has a goal to use native GUI capabilities (incl. libraries, widgets, behaviors, styles, whatever) for each supported platform (at least Windows, macOS, Linux/BSD, Android)

  2. you @Xananax want and I quote If a common API is agreed upon and entirely made of plain records with no hidden state or methods, then people are free to implement renderers for Curses, HTML, or whatever else they please.

But because all native GUIs on all the above mentioned platforms use retained state (let's stick to the common terminology and not try to reinvent a wheel), there is no way to agree an API without hidden state or methods. All native UIs known to me implement nowadays just retained state UIs (they retain much/full state, have their own hidden state and hidden behavior/methods, etc.).

So the points (1) and (2) mutually exclude each other.

@Xananax
Copy link

Xananax commented Sep 28, 2019

My impression is that this thread is about the syntax, which has a much more global reach than what you're discussing, specially for languages that want "one way to do the right thing", in which one syntax used today for native UIs will certainly need to be also used of other type of interfaces later.

The opening statement in the issue asks:

Swift/Dart (using the same language for declarations) or Qt/QML (using a smaller cleaner different language)?

My answer to this is:

By staying entirely declarative & using plain objects, we open many more possibilities in terms of outputs. By not using a specific DSL, we can easily create transformers for this structure using the same paradigms and constructs we're using daily. By using language constructs, we can naturally evolve the shape of structures for new functionality, rather than patching a DSL until it loses all elegance.

Since this issue is actually not about the implementation, but the long term viability of one syntax over another, I believe there is no cross purpose here. Native UIs may be one immediate goal, but they are not the purpose of this very issue.
Scrolling back in history, it seems to me you veered the discussion several times implementation. It's a worthy discussion, no doubt, but I think it warrants its own issue, as it doesn't answer the question that's asked at the top of this page.

@dumblob
Copy link
Contributor

dumblob commented Sep 28, 2019

@Xananax thanks for clarification and the nudge.

This will be a way longer post than I originally intended, but I felt that it'll significantly contribute to the disambiguation between "wish" and "reality".

TL;DR: Swift/Dart/Qt/QML/WPF/... all is trash; declarative yields retained state (i.e. verbose syntax, nearly no dynamics, difficult imperativeness); imperative yields immediate mode (i.e. terse readable syntax, maximum possible dynamics, easy declarativeness on demand)

Since this issue is actually not about the implementation, but the long term viability of one syntax over another, I believe there is no cross purpose here. Native UIs may be one immediate goal, but they are not the purpose of this very issue.
Scrolling back in history, it seems to me you veered the discussion several times implementation. It's a worthy discussion, no doubt, but I think it warrants its own issue, as it doesn't answer the question that's asked at the top of this page.

My whole point is, that syntax doesn't matter if semantics (you're referring to semantics discussion as "veering discussion with implementation") has a totally contradicting definition (i.e. make immediate mode UI by using retained mode). That's exactly what I showed in my comment #2065 (comment) above. And that's why I first want to land at the desired and non-contradicting semantics before we'll discuss syntax.

Let me shed some light on the whole problem of this GitHub Issue and why it's actually a misleading question.

Imagine you have a purely declarative programming language like Prolog. Prolog can guaranteed solve any problem in the world as it's turing complete. You actually used such declarative approach so much that basically every single existing UI library is built around the declarative approach (because for simple UIs where there is nearly no dynamics and rather minor content changes in run-time it's easier to create such UI library and easier to grasp though verbose in syntax).

It just happens, that many cases (actually vast majority when it comes to the number of their kinds) are not feasible to describe in Prolog (see Fifth Generation Computer) which lead you to create the icing on the declarative cake of futile (infeasible) endeavor to make declarative UIs more capable - the web CSS.

Imagine also, there is a purely imperative programming language like C. C can guaranteed solve any problem in the world as it's turing complete. You didn't use C's imperativeness for UIs (except in 3D games) because it wasn't foreseeable UIs will evolve into highly dynamic stuff and you believed in the declarative mantra thus proceeding with mimicking UI declarativeness (btw. notice, that it's more or less easy to mimick declarativeness in an imperative language, but it's difficult to mimick imperativeness in a declarative language).

It just happens, that majority of cases are feasible to describe in C (see e.g. evolution of the TIOBE index).

Now, Swift/Dart, Qt/QML, WPF, etc. are all built around a declarative approach. Asking which of them to choose implies declarative UI. But wait, commenters here in the discussion do not only want declarative UI, but they also want fully dynamic behavior (not known in compile time). We just learned though, that it's futile (infeasible) to build dynamic UIs around declarative approaches. Oh no, we lost this battle (unless we all have schizophrenia).

Well, not exactly. We also learned, that it's more or less easy to mimick declarativeness using imperative style. Could we then maybe describe UIs imperatively (rather then declaratively) and just for the few cases where declarativeness makes actually sense use the opportunity to mimick it? Voila, we now discovered immediate mode UIs (defined imperatively like in 3D games) but extended with the ability to save & restore state (i.e. mimick declarative UIs, aka retained state UIs).

To sum up, combining Prolog and C syntax is a nonsense. Asking about declarative syntax for UI specification is nonsense and won't lead anywhere if the audience will bring in stuff which can't be supported by declarativeness (i.e. dynamics as described by pretty much all commenters here).

Historically it also proved to be a nonsense to enhance/extend/enrich retained state UIs (i.e. syntax originally built around declarative approaches) by imperative stuff. But it works vice versa (i.e. enhance/extend/enrich immediate mode UIs by retained state stuff) as e.g. Quarks shows. Btw. Quarks doesn't use any special syntax - it's all plain C99 with automated generation of C structs for retained UI (easy to read & write by UI design tools), so leaving aside the fact, that Swift/Dart are declarative (retained state), it's similar on the logical level.

@ylluminate
Copy link
Contributor

ylluminate commented Sep 28, 2019

This is an exceptionally interesting dialogue. Appreciate the discussion and clarifications @dumblob . There's an awful lot of detail here - so let's distill this down into a concise plan of action if you don't mind.

Obviously and initially you were very opposed to making a new UI toolkit.

@medvednikov clearly already has a lot of time and thought committed to V UI and so this will move forward.

Please correct me if I'm wrong @dumblob: But it seems that you're recommending essentially taking Quarks and converting it to V and integrating it into the gg library since gg handles the generic graphics functionality for Linux, games and so forth that will underpin v ui itself that will handle native graphics and then use gg as necessary for non-native UI components...

@Xananax
Copy link

Xananax commented Sep 29, 2019

I understand where you're coming from and I think it's valid from that point of view to discuss syntax and implementation together, however I don't understand what is your criticism of declarative UIs?

You mention Prolog and a link wikipedia article, but those simply show that the specific approach Prolog took was not successful for specific reasons. As a matter of fact, the very article you link says that the paradigm may have been "ahead of its time".

You then go on to use CSS to further your point, as if CSS was an evidence of declarative UIs being bad. However, it is not an evidence. I, as well as many colleagues of different expertise (not necessarily web) I've conversed with throughout the years, happen to think that HTML+CSS, while being quite bad, is still, by very far, the best UI language we've ever created.
In other words, I don't understand what arguments you base yourself on to say that declarative UIs are "nonsense". Gargantuan cross-platform apps running on millions of computers, that even newbies can write, but that also are able to satisfy the most demanding business UI needs, certainly, cannot be considered "nonsense" from any pragmatic point of view? "Not ideal", at best, but what ever is?

I also do not understand the link between declarative/dynamic. There's no fundamental difference between expressing logic in a declarative manner or an imperative one. As a matter of fact, a relatively simple parser could turn one into the other back and forth at will. They're both expressions of intent, and what matters for the discussion is how they're understood and manipulated by humans, not how they end up being compiled and used.

A declarative UI can be extended with behavior; this can happen at compile time, or at run-time. Visitors can consume the plain objects and spew out whatever is needed.

A declarative UI language does not preclude custom behaviour created in userland, unless it's a DSL, which is what I'm arguing against. If the language is a DSL, then it gets parsed by the compiler, and logic gets applied by the compiler, and extensions become hard to create. But if the language is just a data structure, then even the most beginner of users can apply some function to them.

From there, I do not actually think it matters overmuch if there are methods in there or whatever imperative syntax; purely declarative UIs are easier to extend (because function bodies are not modifiable), but it's not that huge of a difference.

As far as I'm concerned, this is a false dichotomy. You can have any mix of imperative and declarative as you want, leaning more into one or other of those extremes. The complexity is the same, it's just represented differently. It all depends where you prefer to slice your cake.

I think we are saying the same thing, but you say augmenting declarative UIs has been historically shown to not work, but don't provide any example of why. The languages you do mention as examples are all wildly successful, so I'm pretty confused by that.

I also want to clarify I just landed in this issue by pure happenstance and have no stake whatsoever, so I'm purely discussing this out of curiosity.

@nodrygo
Copy link

nodrygo commented Sep 30, 2019

Hi @medvednikov
V is very interesting thing congratulation

on the Gui side, a RedGui UI like should be really great ;-)
otherwise I find WxWigets a good candidate

@medvednikov
Copy link
Member Author

@dumblob I decided to use imgui as the backend for V's ui for Linux.

It should be easy to optimize it and render things only when they need to be updated, like I did with my own renderer in Vid for example.

@iampato
Copy link

iampato commented Oct 22, 2019

Declarative UI is the way to go but this is my special request deal with state management in "this" framework because dart failed on that

@dumblob
Copy link
Contributor

dumblob commented Oct 28, 2019

@medvednikov thanks for letting me know - I'm totally out of time and thus can't dedicate any time to V since the end of September and probably during the next few weeks/months. I think imgui is a decent choice for V, so I'm glad you did it 😉.

If you want to contact me, just ping me explicitly using @dumblob syntax so that I'll know it's high-priority and I'll try to answer as soon as possible (yeah, I'm primarily thinking about parallelism in V).

@da7a90
Copy link

da7a90 commented Oct 28, 2019

the Dart/Flutter approach is better but it can be improved by maybe adding more computability

@akrymski
Copy link

akrymski commented Nov 11, 2019

I'd like to point out another option - building an alternative to Electron. If you're willing to sacrifice the idea of a platform-native look and feel (which frankly is an outdated concept these days) then I would suggest looking at using HTML & CSS to implement a GUI lib.

Implementing an HTML rendering engine in V has a number of advantages:

  • lots of developers are familiar with HTML / CSS / React way of doing things
  • many are looking for an alternative to Electron that isn't bloated
  • much easier to implement components in HTML & CSS that will work exactly the same across all platforms
  • plays well with WASM target for web app development. This is the direction Rust is going.

It may not be as difficult as it seems, there are a few other Russians working on this:
https://github.com/lexborisov/Modest
https://github.com/litehtml/litehtml

Remember the goal wouldn't be to support all possible websites, but rather the latest HTML & CSS standards (eg flexbox alone is probably enough for layout).

This is somewhat similar conceptually to what React Native is doing. A web browser implements only the most basic components natively, and frankly besides the TextBox everything else can be easily implemented in HTML/CSS. As long as V has access to the DOM then web designers will be able to build great looking interfaces with ease.

@shaxxx
Copy link

shaxxx commented Dec 3, 2019

Stand on the shoulders of Giants. I believe Flutter/Dart kind of aproach is the way to go. Would be nice to actually utilize Flutter engine to render controls. If you really want to have more cobtrol you can always use Skia engine directly.

@manhnt9
Copy link

manhnt9 commented Dec 12, 2019

Was about to comment on Flutter and I saw @shaxxx did. I would write my next cross-platform desktop GUI app with Flutter. Please target V's UI library to web more, it's hard to compete with other desktop GUIs and we're still lack of fast and easy to use, responsive WebUI. I'd love to have a faster ReactJS-like framework for Web.

@lygstate
Copy link

@akrymski How small it would be

@nedpals nedpals mentioned this issue Jan 2, 2020
@nedpals
Copy link
Member

nedpals commented Jan 21, 2020

@cristian-ilies-vasile Can you state the relation of Kai Krause and this issue?

@medvednikov
Copy link
Member Author

V UI has been released, V itself is used for declarations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests