Flutter: Consider JSX-like as React Native

Created on 25 Mar 2018  ·  203Comments  ·  Source: flutter/flutter

For code that builds a UI has to be readable. I understand that Dart is kind of like a simple version of Java, but it is not really a programming language for building a UI. For example, it doesn't have a closing tag. As a result, It is very hard to build a picture in mind with this unreadable code.

Moreover, Flutter was inspired by React. How can Flutter doesn't have JSX but has this kind of unreadable code? I am very scared that Flutter is going to die very soon as the early days of AnglurJs.

I understand people who work in Google are smart, but we also have some people who are not really smart choose React instead of Dart, and this is one of the reasons why Dart was dead in the past.

Most helpful comment

Some people like jsx, Some people dont. Why dont support the two ways to implement UI. You can write jsx-like syntax,and it will finally be comeplied to flutter native syntax,why not support?

All 203 comments

This has been asked for a long time:
https://github.com/flutter/flutter/issues/11609
Functional prototype developed:
https://spark-heroku-dsx.herokuapp.com/index.html
That shows the alternative and some benefits...


The current issue with DSX is about proper integration with Flutter tools as to provide a great developer experience with debugger, auto-complete, etc. working on .dsx files.

Telling users that they can use DSX but can't use debugger or enjoy auto-complete is a non starter for me. If anybody wants to help, what I need is to figure out a way to add full preprocessing support (with source map) to Dart Tools and VS Code Dart plug in. Once the tools support that DSX or any other transpiling language (any language that is a superset of Dart but compiles everything down to Dart) would just work.

If you can and would like to help, let me know.

I cannot agree. Especially using a IDE like Dart Code you get virtual closing tags which makes readin way easier. With Dart2 where you can omit new it will even get better.

Also I find it discourages you to build too big Widget trees without deconstruct it into smaller easier to maintain widget classes.

I use Android Studio. I don't even see a virtual closing tag. Even though we have a virtual closing tag, it is more complicated than HTML that everyone hates. Dart is just a programming language. People in Google don't understand the importance of simplification.

close

I don't think I would like a JSX-like syntax either but yeah, I use IntelliJ and something needs to be done with the tooling so that the UI code is easier to understand.

Also I find it discourages you to build too big Widget trees without deconstruct it into smaller easier to maintain widget classes.

I don't see how this is any different than with JSX... as the tree gets larger you can break into smaller sub-trees with both.

I don't think I would like a JSX-like syntax either but yeah, I use IntelliJ and something needs to be done with the tooling so that the UI code is easier to understand.

and it should be easy to read on all platforms and not only Intellij; I mean it should be easy to read on Bitbucket when reviewing code; and it should also be valid when using any editor; I mean with these 'comment annotations' what happens if someone using 'vi' types a different comment in there?

This is a dup of the locked down #11609
@sethladd ?

Apologies, you should be seeing the "virtual closing tags" in IntelliJ and Android Studio.

cc @devoncarew to verify which version turned that on, or if the user needs to opt-in ?

We thank you for your comments re: JSX-like syntax. We believe there is opportunity across the language, our tools, and plugins to make editing UI code easier.

This does dupe #11609 but I'd like for @devoncarew or @mit-mit to add a note about how to turn on "virtual closing tags", if possible.

Thanks!

@JonathanSum, the closing labels aren't available in Android Studio 3.0 unfortunately. You'll need at least IntelliJ 2017.3 or Android Studio 3.1. Android Studio 3.1 is currently in the release candidate stage, and we plan to release a flutter plugin with support for it tomorrow.

Irrespective of the conversation around a JSX like syntax, we do want to work towards making it easier to write UI code in Dart, in both IntelliJ / Android Studio and in VS Code. That's initially the closing label work, but also the recent Flutter Outline view. That shows the structure of your build() method in an outline view, and allows you to navigate the widgets and more easily see their parent / child relationships. That's currently available in IntelliJ - we do expect to be able to bring it to VS Code as well.

@zoechi - This might be a dup; but the other thread got heated, and locked. So their is no way to contribute to that conversation. I don't think you should close this thread as a dup just because you don't like people asking for a feature. This should probably be the new thread for responses for new people coming and requesting JSX support (or similar functionality).


@sethladd - Please do not lock this thread; I do think having community discuss pro's and con's on alternative layout methods is useful. I would have participated in #11609 had it not been locked.


I come from a NativeScript background. I have to say this is one area where I do feel NativeScript is considerably easier to use than Flutter. I can get a fairly complex screens working in less than 5 minutes and easily iterate the design quickly. Then add the code that runs the screen.

In NativeScript we actually have the following files:

  • screen.js / screen.ts (.ts is transpiled into .js if you prefer typescript). This is the main logic for the screen that you are displaying.
  • screen.css (or screen.android.css and/or screen.ios.css) which is a much more limited version of CSS but supports things like height, width, color, background, etc. Most the time a single css file is only needed, but occasionally if you are doing something weird you might separate your css for android and ios. It has full support for Classes, Elements, and id's So I can do TextArea.Login #Password and it actually will limit itself to just that specfic element chain.
  • screen.xml (Again or screen.android.xml and/or screen.ios.xml) - This is the screen layout. You CAN code the layout in JS if you want (basically like flutter); but the XML is so so much easier. Example:
<Page onLoad="loadme">
    <ActionBar title="Blah"><NavigationButton click="back" title="Back"/></ActionBar>
    <StackLayout>
      <Label text="Hi" id="Hi" style="color: red"/>
     <Label text="{{name}}" class="name"></Label>
     <Button text="Click Me" tap="clicker"/>
    </StackLayout></Page>

The interesting thing is that ActionBar is a specific page only component (i.e. it is specific to only Page); so basically what happens is the XML parser See's page; creates a new Page Element; then creates a ActionBar component which it then runs a builderChild function on the Page component; the page component overrides the default builderChild and looks to see if the child is a ActionBar; if it is; then it internally assigns it to the proper variable; otherwise the rest is passed through parent/super which then assigns it to the "child" or "children" components automatically. The build system is incredibly versatile in that each component can use either the parent's builderchild function or override it to do extra items like support <Label>Hi</Label> and assign that to the Text value automatically. This makes layout incredibly easy to get up and running without any code.

Because most editors have good XML editing capability it is automatically colorized and with the proper xsd definition intellij (& vscode) does automatic checking and limited context support.

Now technically everything is actually a JavaScript component; so you can do all this manually (like what Flutter does); but I find the easy of laying out a screen is trivial in NativeScript. And you don't need the JS or CSS when you first start; then you can add the CSS (typically you don't hard code in the layout the css based properties; but you can if you want).

The nice thing about this; is it allows Web developers to jump right in with very little (if any) retraining. In fact; because of its flexible renderer and being JS based -- NativeScript actually support Angular and Vue -- so that you can actually share close to 95% of the code base between web, and your mobile app if you use Angular or Vue. Since it uses Native OS components like react native (not a webview like cordova); it really is a decent cross-platform system (that is imho better than React Native) . However, I can see where there are some strengths that Flutter has that makes it a good complimentary tool for some mobile development as their are some apps that NativeScript is worse at and some it is still the much better for and based on the responses to my issues from Ian; will stay the considerably better tool for in those areas.

Better to open that locked thread and copy these comments there so we have a history of full discussions.

@JonathanSum it's not about whether anyone wants or doesn't wants the feature,
it's whether this is the place to have a heated discussion about it. I guess reddit or similar are better places.

@cbazza - I don't disagree; but you have to be very careful in the future to not insinuate things about people. That just inflames the discussion, no matter how idiotic you believe they are being.

@zoechi - Actually I believe any discussion about a new feature should be here. History should be maintained so that when John Doe comes a month from now and searches about XYZ feature he can :+1: an existing feature and/or contribute to it.

I don't think that thread is really locked for this long because of my comments. If what I said was so bad how come I can comment on everything else, like for example this thread?

The thread is locked because the Flutter team has no interest in doing this and just want people to stop talking about it.

Let's please keep the discussion in this issue focused on use cases and examples for a JSX-like feature.

Actually if NativeScript is that good, why bother with Flutter at all instead of trying to make Flutter NativeScript like.
I'm coming from an XML based Platform (Xamarin Forms) and thought in the beginning it might be more difficult to design in code but that's not the case.
In the contrary it makes is very easy to break down your design in separate classes which are easy to maintain.

JSX is designing in code !!!

@sethladd

Let's please keep the discussion in this issue focused on use cases and examples for a JSX-like feature.

OK, Let's talk about my DSX design which can be viewed here:
https://spark-heroku-dsx.herokuapp.com/index.html

It provides a direct mapping to the current way widgets are built and yet provides a JSX like flavour that is very lightweight and familiar to React developers. Is there anything missing in this design? Can this design generate all possible widgets in the wild?

Rule of thumb, if you feel one exclamation mark isnt enough you should probably step away from the keyboard and take a break.

I'm a newcomer to Flutter, having only some experience with Android and Java, and I must say I find what Flutter offers far better than what is being proposed here. I tend to find that XML is ugly and unwieldy. It's so much more beautiful to have a singular closing character, rather than a sea of that makes my code 5x longer, a hatred of mine when editing Android XML, and just virtual closing tags which the vast majority of IDEs which people use support. This is incredibly useful when designing longer structures. The neat nesting XML provides just doesn't outweigh the rest of the disadvantages, in my opinion, especially when 'child:/children:' do almost as good of a job. Dart is incredibly clean, and it is a reason I like it so much. I would be incredibly disappointed if this was to be ruined.

I know that React does it like this, but last time I checked, this place says Flutter. Just because React does it doesn't mean we have to - you're not the only ones jumping ship to here! I very much agree with all the points @escamoteur made. I'm not seeing the point in adding yet another language that people need to handle when using Flutter. We're already using Dart to program most of it, we don't need a load of other things to master! Consistency and simplicity must be valued.

Some remarks from your DSX vs generated Dart snippets:

  1. Subjective: I don't see any great readability gains. Verbosity is similar - if not a tad longer. Dart IDE plugin provides auto closing tags, which mirrors declarative markup closing tags. If JSX is design in code, then I don't see how widgets in Dart is not.

  2. Multiple properties in <vars>

@<vars>
var textStyle = {
    "textDirection": "TextDirection.ltr",
    "textAlign": "TextAlign.center",
    "overflow": "TextOverflow.ellipsis",
    "style": "new TextStyle(fontWeight: FontWeight.bold)"
};
</vars>@

Being able to define global styles mixing several properties is a nice idea.
However when I'm looking back at my modest flutter experience, I don't see where I would use these.

For Text it seems most of what I need to reuse is defined in TextStyle, rather than a mix of several properties. Maybe you can find another example than Text where that's not the case.

Looking at TextStyle, I find the current immutable + copy() to be great for reusing and composing in Dart:

class Style {
  static const TextStyle avenirNextMedium =
      const TextStyle(
         fontFamily: 'Avenir Next', 
         fontWeight: FontWeight.w500,
      );

  static TextStyle title =
      avenirNextMedium.copyWith(
        color: ColorKit.blue, 
        fontSize: 45.0,
      );
}

new Text(
  'Hello',
  style: Style.title,
),

new Text(
  'Hello2',
  style: Style.title.copyWith(
    color: ColorKit.red,
  ),
),

For reusable Container sharing a same style, I think that creating a custom stateless widget works better than an external defined <vars>. Most of the time, I want also a padding, an ink, a gesture listener or a shadow.

For any of those cases, I would need to compose Container with another widget: Material, Padding, Center etc. So if I have to create a custom reusable "container" widget anyway, I don't see much gain to have an external <vars> style that would just define the properties of a single widget in my reusable widgets hierarchy.

I don't see Flutter's "everything is a widget" work well with "multiple properties" styles.

  1. Not highlighted in your current DSX examples: How would you code an interface with dynamic widgets? Meaning: how to show or not show some widgets depending on a condition.

When doing design in Dart it's easy and convenient to add or not a particular widget into children.
It's also very convenient to dynamically wrap a widget with another. It makes the build() function fluent and easy to understand.

    var children = <Widget>[];
    if(a) {
      children.add(wa);
    }

    var wb = Text();
    if(b) {
      wb = Padding(child: wb);
    }

    children.add(wb);

@SirComputer1 the DSX proposal is an addition, the current way doesn't change so if you don't like it, don't use it, continue as you are today.

The <var> thing was only done for the demo because I didn't want to parse full Dart. The final solution would not include <var> but would use any dart variable. Also the '@' was only done for the demo to make parsing easy. Final solution would not include it.

Don't forget that anything else on the file is your normal Dart code, so you can use that for everything else.

    var children = <Widget>[];
    if(a) {
      children.add(wa);
    }

    // You can mix and match both
    var wb = <Text/>;
    if(b) {
      wb = Padding(child: wb);
    }

    // or
    var wb = Text();
    if(b) {
      wb = <Padding> {wb} </Padding>;
    }

    children.add(wb);

    children.add(
      <Center>
          {sayHello == true ?
             <Text ['Hello, world!']/>
          :
             <Text ['Good bye']/>
          }
      </Center>
    );

Let's stop comparing DSX with the current way, one is not competing with the other. Some people will prefer JSX and this thread is for them. What I want to know is how can I improve DSX to handle things that it won't work for.

@escamoteur - I don't tend to use a hammer as a screw driver. I evaluate the different technologies and use the proper one for the proper use case. That doesn't mean their isn't things can could be changed for the better in each of the platforms. :grinning:

For example; third party plugins integration. NativeScript is truly king over every single other cross platform. Nothing else even remotely comes close to NativeScript; and third party integration. I have a client asking about using https://github.com/vipulasri/Timeline-View . Flutter virtually impossible; NativeScript give me a couple hours and it will work just like any other NS control probably even with fully working data binding. On the flip side flutter has some serious strengths where NS flags...

Use the proper tool for the job. :grinning:


I do tend to like the XML based screen layout; but I do understand why people don't. Adding the ability for XML based building does NOT mean eliminating the existing method; it is just complementary; choice. For those of you who didn't bother reading, I can do the same chain of calls in NS that we do in flutter; but using xml is a lot less typings and easier to me to read. Everybody has their preferences...

I have actually thought about adding a XML based renderer to Flutter as a POC; but I haven't had the spare time. I just wanted to contribute to the conversation and say I would like to see this move forward; but I actually do not expect the core team to work on it. I think NS XML format could be done as community projects where those of us who care (i.e. probably me :grinning:) would be willing to do the work on them. However, my biggest concern @sethladd -- is if I spend a lot of time on a patch; will it be rejected because someone on the core team absolutely opposes this ability. That is what I would like to nail down first before I spend any time on this...

@NathanaelA Fantastic perspective !!!!!!! and look I used lots of exclaimation marks ;-) You literally nailed it on the head.

Yes, I can do DSX but I need a way to integrate it in the current Flutter build system so I need commitment from the current Flutter team before I move forward. IDE integration is virtually trivial on VS Code but not so much with Intellij (unless Google has access to Intellij JSX support).

@zoech, No! I think this is an issue. I remember developing an android app with native Java and XML. We still use XML for UI language part. I think using Dart for logic and UI is kind of odd, and this problem is kind of obvious. furthermore, I just hope Google is going to add the UI idea of React into the flutter. The UI part of React is very powerful and concise.

@JonathanSum I have seen many comments about this.
For me it still looks like something people want because they are reluctant to change their habits, not because it's a benefit for the platform.

Some people like jsx, Some people dont. Why dont support the two ways to implement UI. You can write jsx-like syntax,and it will finally be comeplied to flutter native syntax,why not support?

@zoechi

For me it still looks like something people want because they are reluctant to change their habits

This is a fair observation but wouldn't it be better for Flutter to be an enabler and remove as much friction as possible for people (outside Google) to adopt Flutter? This gate-keeping behavior is not winning hearts and minds of developers.

@yuu2lee4

Some people like jsx, Some people dont. Why dont support the two ways to implement UI. You can write jsx-like syntax,and it will finally be comeplied to flutter native syntax,why not support?

Excellent question. Given that I am doing all work on DSX, which is just like JSX, and @Hixie personally sent me email excited about the progress, I don't see why not support it, I don't see why not extend a hand and say 'What can I do to help you? What is blocking you to do this?'

honestly, am beginning to think this heading in a similar direction as the previous one... which would not help...

@cbazza

@Hixie personally sent me email excited about the progress..

So why don't you continue and the others who can help should also get on board and help? If we don't want this to turn up like the other thread...I think we should be discussing what are the blocks, how do we go about it and how do we get it working and put it out there... and I also think the flutter and dart team have in some way begun some work on reducing the verbose nature of writing UI...
Maybe the team might not be able to join in now but I believe if its worthy cause which I believe it is though for me am okay whichever approach...they will catch up at some point...so @cbazza lets continue with what you are doing and get it out...like what this guy did http://mutisya.com/ in the early days even though I dont know of its state...I also know @NathanaelA can help because he has contributed some really amazing stuff and tools for Nativescript...Lets get it out to give more devs more options...

@MichaelSowah
The reason not to invest more time on this is like @NathanaelA said:

However, my biggest concern @sethladd -- is if I spend a lot of time on a patch; will it be rejected because someone on the core team absolutely opposes this ability. That is what I would like to nail down first before I spend any time on this...

OK, here is what I have:
(a) A pre-processor that takes *.dsx files in and outputs *.dart files out.

Here is what I need:
(1) Someone to take care of 'VS Code' integration. From my investigation it looks simple.
(2) Someone to figure out how to add pre-processor capability into the Flutter build system so that debugging would work properly. I mean code stepping would be on the *.dsx files via something like sourcemap, etc.

Once the above 2 items are done we have an initial end-to-end system to get the ball rolling. Any takers?

So as you can see above, (1) & (2) require changes in the Flutter code that the Flutter team can reject so without support/commitment this feature is stuck.

@cbazza great so let's get one of the flutter team members here to let us know whether they are will to take in one and two...so who can we get here to help us progress...?

For (2) I think the best bet is to contact the Dart team, probably via [email protected] or their issue tracker? I believe one of the goals of Dart 2 was to create an infrastructure for more experimentation with the language and let the community create experiments like DSX. Maybe @anders-sandholm @mit-mit or @mraleph can point you in the right direction.

@sethladd Thanks for the quick response and could you also copy the resource persons and possibly
dart team unto this thread as well
@cbazza could you jump in to get this discourse going with the resource person listed.
with regards to the 'VS Code' integration I am sure onces we get 2 out of the way maybe @DanTup might be interested in helping out

Just some thoughts

OK, here is what I have:
(a) A pre-processor that takes *.dsx files in and outputs *.dart files out.

This is probably all you need to start, that and a file watcher to rebuild on changes - see FileSystemEntity. The challenge is this .dx grammar is a superset of dartlang, so you would have to parse all of Dart too. This will be tricky because unlike JavaScript, < and > are used in more places. I think the Dart parser is already written in Dart, and somewhere inside the sdk repo, but I don't know where

  1. For vscode and Intellij integration, it's not the flutter build system, it's the dart analyzer that you want. I think you can create a plugin for this which would consume the dx, transpile it to dart, then map the results back to the original file. This is how the angular analyzer plugin works to provide things like autocomplete to html files.

  2. You want build runner, this is a much more sophisticated package for doing a.

@MichaelSowah
Excellent so I guess you are taking on (1) & (2) so I can focus on the transpiler?

@jonahwilliams
I know, full dart parsing will be complicated and not really necessary right now because I can always use my markers for first release (https://spark-heroku-dsx.herokuapp.com/index.html)

But one thing is for sure, we need the IDE and debugger working properly or else people will not use DSX because the trade off is too much. I mean 'use DSX and forget about symbolic debugging', not a very compelling offer. That's also the reason I want at least one IDE supported and VS Code would be as simple as pie (since it already supports JSX in their Typescript & Javascript syntaxes definition json files)

re: IDE and debugger, presumably by implementing this feature inside the Dart 2 infrastructure and "common front end", you should be able to enable the higher levels of the stack to be aware of DSX. I recommend working with the Dart team and learning how to explore the various parts of the Common Front End and its APIs.

@MichaelSowah I did CC the folks from Dart in https://github.com/flutter/flutter/issues/15922#issuecomment-376960770

@NathanaelA would you be interested in joining in on the (1) & (2) since now we clearly have support from the team

Not sure; at this moment -- I'm swamped with several client projects. But I'd be willing to look into how to hook into the compile pipeline and potentially creating source maps. (i.e. 2) But it might be a couple weeks before I can do so.

@NathanaelA There is no rush or anything so you're good :-)

If DSX is simply Dart + Virtual closing tag then there is no real benefit. One benefit with dart is that we can use functions and variables to create part of the widget and increase readability.

Also with DSX and pre-processor, we will lose the sub-second hot reload ability, right @cbazza ?

Nope, DSX is like JSX and completely different than 'Dart + Virtual closing tag' which is what you can do today with your Dart only widget tree and IDE.

DSX is described here:
https://spark-heroku-dsx.herokuapp.com/index.html

DSX is Dart so all benefits of Dart as you describe are there. People familiar with JSX will get it right away and love it.

No you won't loose anything, nothing changes for normal *.dart file you create, you still have sub-second hot reloading.
Now if you have a *.dsx file, it will be first transpiled to *.dart and that process is faster than I can blink !!! So it will be unnoticeable to DSX users.

Before this one is closed again, let me finish what I want to say first.
The current UI of flutter part is an issue, and I am not trying to sell the idea of React.
Because the UI structure of flutter is very hard to realize in the mind with those parentheses, we really need something to improve. I highly suggest to use react native or the whole thing like React. React not only make people easy to read, it also separates a huge UI code in different groups. As a result, I can manage a huge complex UI code quicker and read them easily. On the other hand, with a lot of trees with parentheses only in the flutter, I don't know how to read them.

@JonathanSum did you try the last version of Android Studio (3.1) with closing labels ?

@14n Yes, I see those virtual closing tags and comments.

A big XML-like widget tree can be as hard to read as any other big thing, be it Dart, JSON, YAML or JSX. It doesn't seems like JSX itself solves problem of readabilty.

I haven't had any problems reading sane-sized widget trees with current syntax. Plus Flutter promotes composition so once certain widget gets too big it is trivial to split it in multiple smaller widgets.

Subjective opinion on proposed DSX format:

  1. Visually no real benefit and again - reading large XML-tree can be as painful, so doesn't seem like it solves the problem. Promoting Clean Code practices, for instance, would actually address readability concerns, but these practices can be applied to (almost) any syntax.
  2. Requires learning another DSL/syntax. I really-really-really like that I only need to know one syntax - Dart - to do everything - layout, styles, animations, logic. It is so much more friendly for both newcomers and experienced developers comparing to what happened to Web with html/js/jsx/ts/coffee/css/sass/scss. In fact, I even consider this a major benefit of Flutter over other platforms.

That said, I believe there is room for improvement for Dart to be more expressive when used for describing UIs, though I'd prefer it to be more of an extension to existing Dart syntax instead completely new DSL.

Please stop trying to make Flutter be like the "hot new thing". It's the hot new thing on its own, let it explore new paradigms.

@naiveaiguy I think it's hot. It makes me very productive and allows me to share code with browser and server apps.
I don't need some hype for one summer. I need something that allows me to get my job done.
That's exactly what Flutter and Dart do.

My thoughts on this mirror what @pulyaevskiy said in https://github.com/flutter/flutter/issues/15922#issuecomment-377666972. All the examples I've seen that aren't that readable can usually be tidied up in the existing code and I think there may be more minor changes that could be made to Dart (similar to removing new/const) that could improve it further. Maintaining a whole other set of files with a whole other syntax and a whole new set of tooling code seems like a high cost for what I believe relatively small gain (FWIW, I also prefer React without JSX).

I don't know if it's totally applicable here since the proposed dsx allows normal Dart code too, but every time I hear someone talk about a new syntax I'm reminded of this great post by Gilad A DOMain of Shadows. These things are always more complicated than people think. It's not as simple as just transpiling the code because people would expect real-time errors, code completion, refactors, tooltips, etc. - it's a big undertaking.

Rather than a working transpiler, I'd be more interested to see a three-way comparison between some code considered to be difficult to read, how it would look in this proposed syntax, and how it would look if you could make any changes to the existing Dart syntax without replacing all the brackets. For ex., something I like in React is that children as passed as varargs as the last parameter - I think child and children add a lot of noise in Flutter - maybe there's room for improvement there. There are also some discussions about whether changing the formatting or highlighting Widget class names might help. Looks like an Extract Widget refactor is on the way to easily break down large build methods. And of course, IntelliJ has the Flutter Outline view which let's you see the code in a tree and the selection keeps in sync with the cursor position in the editor (and I'm really hoping to get something similar into VS Code, though it's blocked by some VS Code features like this one so feel free to 👍 it!).

@pulyaevskiy
I understand what you are saying but experimentation is good, it's the path to evolution. Even if my experimentation with DSX fails, I hope others experiment with many other things and bring together the best ideas out there to create amazing technology.

@sethladd
Thank you for the leads.
Would love to hear back from @anders-sandholm @mit-mit or @mraleph on
how to work with the Dart 2 infrastructure and 'common front end'.
I will look into that with @NathanaelA.

@DanTup

These things are always more complicated than people think. It's not as simple as just transpiling the code because people would expect real-time errors, code completion, refactors, tooltips, etc. - it's a big undertaking.

Yes, you are correct. My 'trivial, simple as pie to implement' comment only applied to getting the editor to recognize the .dsx syntax. I looked into Intellij and they require a complete language parser for that (so that's complex), whereas VS Code was much easier with the syntaxes files and I also noticed that the Typescript/Javascript syntaxes files already had support for JSX (and DSX only has minor changes from JSX).

We will certainly be bugging you for help/direction to get our experimentation going.

In summary, I have:
(a) A pre-processor that takes *.dsx files in and outputs *.dart files out.
https://spark-heroku-dsx.herokuapp.com/index.html

I need help with:
(1) Someone to take care of 'VS Code' integration.
(2) Someone to figure out how to add pre-processor capability into the Flutter build system so that debugging would work properly. I mean code stepping would be on the *.dsx files via something like sourcemap, etc.

@NathanaelA will help with (2).

So I am still looking for people to help with (1)
Any takers? @birkir @yuriy-manifold @tehfailsafe @alexkrolick @sanketsahusoft

@DanTup - I'm not a pro on JSX, but I can speak toward NativeScript XML format. I can do:

Any property that the class StackLayout supports can be added to the XML. So it is a one-to-one relationship; which eliminating a ton of extra cruft: So lets look at the Flutter demo:
https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/gallery/home.dart#L39-L63

<AnimationBuilder animation="{{animation}}">
   <Stack>
      <BackgroundLayer top="{{-layer.parallaxTween.evaluate(animation)}}" left=0.0 right=0.0 bottom=0.0>
          <Image src="{{layer.assetName}}" package="{{layer.assetPackage}} fit="cover" height="{{maxHeight}"}/>
      </BackgroundLayer>
   </Stack>
</AnimationBuilder>

I find this easier to read and understand if I converted it correctly. :grinning:

@NathanaelA What happens if you need to do something more dynamic, like calling map? Here's some code from that same file:

  Widget build(BuildContext context) {
    return new AnimatedBuilder(
      animation: animation,
      builder: (BuildContext context, Widget child) {
        return new Stack(
          children: _kBackgroundLayers.map((_BackgroundLayer layer) {
            return new Positioned(
              top: -layer.parallaxTween.evaluate(animation),
              left: 0.0,
              right: 0.0,
              bottom: 0.0,
              child: new Image.asset(
                layer.assetName,
                package: layer.assetPackage,
                fit: BoxFit.cover,
                height: _kFlexibleSpaceMaxHeight
              )
            );
          }).toList()
        );
      }
    );
  }

What would children: _kBackgroundLayers.map(...) look like in this syntax?

JSX/DSX specifies only the tag transform as:

In:
<A property="a"/>
Out:
new A(property: a)

In:

<A property="a">
  <B/>
  <C/>
</A>

Out:

new A(property: a, 
children: <Widget>[
   new B(), 
   new C()
])

and you can use {} to put any valid Dart code, like variable evaluation and anonymous functions, etc. The {} can be placed in 3 places. The example below shows {} used in 2 places (tag attributes and as children), with the 3rd one being with the spread operator.

  Widget build(BuildContext context) {
    return <AnimatedBuilder
      animation={animation}
      builder={(BuildContext context, Widget child) {
        return <Stack> {
          _kBackgroundLayers.map((_BackgroundLayer layer) {
            return <Positioned
              top={-layer.parallaxTween.evaluate(animation)}
              left={0.0}
              right={0.0}
              bottom={0.0}>
              <Image.asset [layer.assetName]
                package={layer.assetPackage}
                fit={BoxFit.cover}
                height={_kFlexibleSpaceMaxHeight}
              />
            </Positioned>;
          }).toList()
        } </Stack>;
      }}
    />;
  }

Put the above code in a Javascript file and view it with VS Code/Intellij. Notice the +/- (left side of line) that you can use to open and collapse XML nodes to make tree smaller/bigger.

Why can't we just admit the issue and adopt the React Native way? Are we going to do so or not?

@JonathanSum sorry when being directed here, but who do you think you are? There is no general issue just something you don't like.
Have you even wrote a single App with Flutter?
The examples above mixing Dart with XML look far worse than just Dart. Nothing to gain here.
I came from Xamarin Forms which uses xaml and I really liked it. But instead of complaining why Flutter doesn't support Xaml I dove right into it and started to adapt and learn.
Face it if you want work like in React then use Reactive instead of annoying everyone here.

Here is the same code block as above, but in pure Dart and refactored to avoid deep nesting.
Curious which parts of the below snippet are hard to read and/or understand?

Widget build(BuildContext context) =>
    AnimatedBuilder(animation: animation, builder: _buildChild);

_buildChild(BuildContext context, Widget child) {
  return Stack(
    children: _kBackgroundLayers.map((_BackgroundLayer layer) {
      final image = Image.asset(layer.assetName,
          package: layer.assetPackage,
          fit: BoxFit.cover,
          height: _kFlexibleSpaceMaxHeight);
      return Positioned(
          top: -layer.parallaxTween.evaluate(animation),
          left: 0.0,
          right: 0.0,
          bottom: 0.0,
          child: image);
    }).toList(),
  );
}

In fact, personally I'd make it look closer to something like this:

Widget build(BuildContext context) => AnimatedBuilder(
      animation: animation,
      builder: _buildChild,
    );

_buildChild(BuildContext context, Widget child) {
  return Stack(
    children: _kBackgroundLayers.map(_imageForLayer).toList(),
  );
}

_imageForLayer(_BackgroundLayer layer) {
  final top = -layer.parallaxTween.evaluate(animation);
  final image = Image.asset(
    layer.assetName,
    package: layer.assetPackage,
    fit: BoxFit.cover,
    height: _kFlexibleSpaceMaxHeight,
  );
  return PositionedImage(top: top, image: image);
}

class PositionedImage extends StatelessWidget {
  PositionedImage({this.top, this.image});
  final double top;
  final Image image;

  @override
  Widget build(BuildContext context) =>
      Positioned(top: top, left: 0.0, right: 0.0, bottom: 0.0, child: image);
}

Again, it seems we are mixing two different problems here:

  1. Dislike of Dart syntax and need for XML/JSX-like syntax
  2. Readability of Flutter code.

Are there people here who believe implementing JSX will solve readability? It would still be possible to create deeply nested trees in code and developers would still need to go through the same steps I just performed with Dart version to make things readable.

But what it would definitely add is an extra build/transpile step with source maps & co, and a lot of work to support this infrastructure in IDEs and Dart SDK (analyzer, debugger, etc).

@JonathanSum @escamoteur We don't speak aggressively on this project. Please remain collaboratively collegial. Thanks. The recent discussion has been friendly and productive, so thanks to everyone taking part in that discussion!

Overall, it seems to me that adding DSX would fragment the Flutter ecosystem at its earliest stages, with much work being done to try and keep both syntaxes feature-complete, not actually significantly help readability in most cases, and attract the kind of developers who are attracted to projects purely for having a similar syntax and/or paradigm to a hot new thing.

@Hixie sorry that I lost my temper but I think Flutter is on a good way as it is and the Flutter devs have enough to do without demands like this

@escmoteur - I think that is why I specifically said "community" effort. I don't think this needs to involve the flutter core team beyond them being willing to accept patches... Which Seth appears to have said we are able to proceed. If you aren't interested in this feature; then don't use it... :grinning:

@escamoteur, I am sorry for the way of what I said.
I have built some flutter apps from tutorials. All I feel about flutter is everything is an object rather than a widget. It is just like a huge piece of complicated object-oriented programming codes stuck together disorderly.

I think the most important thing is making a framework that is easy for reading and managing, and it should not be complicated as hell. Most importantly, I think the way that React-Native builds follows what humans build stuff naturally. On the other hand, the flutter needs to connect stateful widget into the stateless and... Moreover, most of the UI frameworks which we use in these years focus on this React way as a standard, and I think flutter should focus on this more rather than the hot reload(when I try to add new some new classes, the console tells me to restart everything instead of doing hot reload). I really think this is an issue, not a comment or demand.
naiveaiguy said:

Please stop trying to make Flutter be like the "hot new thing". It's the hot new thing on its own, let it explore new paradigms.

You can go check them out.
https://facebook.github.io/react-native/
Thinking in React:
https://reactjs.org/docs/design-principles.html
Flutter:
https://flutter.io/tutorials/animation/

Look at the React-Native, it even puts the state management above and UI parts below. It is an art and natural behavior of human being. This is why the learning curve and the time of management are low. Thus, please do not compare XML or even Xamarin to the React Native. Moreover, the futter is just like just an chaos and disorder. The stateless connect to stateful, and the create-state connects everything in the stateless. With React-Native, you are drawing a beautiful picture with a pencil. With a flutter, it is just like dropping a water on a paper and separating the water into different parts. But I think we are still in the early days of flutter. React-Native has its own philosophy and goals, and flutter is just a serious project, or everyone disagrees with me.

@JonathanSum

I have built some flutter apps from tutorials. All I feel about flutter is everything is an object rather than a widget. It is just like a huge piece of complicated object-oriented programming codes stuck together disorderly.

You've failed to provide a reason why your subjective feeling in this matter would justify the enormous amounts of fragmentation it would inevitably cause. When between these two approaches, no one is clearly better objectively than the other, I don't think it's worth it, and definitely not in the stage that Flutter is in right now as an ecosystem.

I think the most important thing is making a framework that is easy for reading and managing, and it should not be complicated as hell.

This is a tautology. Obviously everyone wants this, but people have different ways of approaching the problem. Flutter's paradigm is one of them.

Most importantly, I think the way that React-Native builds follows what humans build stuff naturally.

I don't think something as minor as the syntax for building the UI influences how easy-to-use a framework is overall.

On the other hand, the flutter needs to connect stateful widget into the stateless and...

It seems like you fundamentally disagree with how Flutter approaches apps. Why are you using it? Moreover, this isn't really a valid point. You're not expressing something that you feel is wrong, you're just saying "I think that connections between stateless and stateful widgets is wrong and complicated in some vague way that I will not proceed to explain."

Moreover, most of the UI frameworks which we use in these years focus on this React way as a standard,

Argumentum ad populum.

and I think flutter should focus on this more rather than the hot reload(when I try to add new some new classes, the console tells me to restart everything instead of doing hot reload)

Yes, because hot reload is not a very easy feature to achieve in the way Flutter has done it. I would argue that the development cycle that Flutter has managed to achieve, even in 30-40% of code changes, is really impressive, and would only be slowed down by layers of transpiling.

However, the futter is just like just chaos and disorder.

Here you've made it clear that you simply don't like Flutter's approach. Don't use it then. And if you think that somehow, magically, changing the UI syntax will make Flutter not "chaos and disorder", then you'll need to provide clear evidence of that working in the same kinds of settings and constraints that Flutter is working with.

That is why the learning curve and the time of managing it is low. Please do not compare XML or even Xamarin to the React Native.

Fair enough - use React Native then. The developers there are doing a great job with their paradigm.

The stateless connect to stateful and create-state in the stateless

What? No. This is just plain wrong - what is your point here?

With React-Native, you are drawing a picture with a pencil. With a flutter, it is just like a water dropping on a paper and separating the water into different parts.

Frankly, this analogy makes very little sense to me. I could easily just state the reverse opinion and we would be right back where we started here.

You are acting like this is self-evidently obvious ("let's face it") and we're just being pretentious and/or insufferable here for saying that the Flutter team shouldn't have to deal with this. This is not a good attitude to adopt if you're wanting other people to take you seriously.

Additional point: Please don't pretend that this is something third-party developers can do without any involvement or work on the Flutter core team's part. The Flutter team will have to do a lot of additional work with IDEs and editor plugins, and evangelism, and dealing with GitHub issues, if such a feature is to be implemented satisfactorily as a harmonious part of Flutter.

@naiveaiguy
All right, I think you are right. I am just a random person comparing everyone here and a person who likes React. Flutter has its own way, and React has too. I am sorry for my attitude, and I was not nice.

@JonathanSum I think you just need more time to really understand how Flutter apps are built. To be fair there isn't much docs out there on architecture, how to use Inherited Widgets correctly and how to connect your viewmodel to the widgets.

What I'd like to know is why are you interested in Flutter at all? For me React is a no go because of JS

So much to comment, so little time, perhaps I should focus...

@escamoteur what exactly do you mean by:

For me React is a no go because of JS

ES6/7 or Typescript are so close to Dart/Kotlin/Swift that I'll happily dance with any of these ladies :)

The thing that attracts me to Flutter is the graphics & animation support. Direct Skia Vector graphics built on top of OpenGL for super fast UX at 60fps to easily implement things like what you see on:
https://uimovement.com/
I am into custom UX and Flutter enables that. I've implemented UX stuff for decades and I really like being able to build that using declarative/reactive techniques, and Flutter supports that.

@pulyaevskiy

Again, it seems we are mixing two different problems here:

  • Dislike of Dart syntax and need for XML/JSX-like syntax
  • Readability of Flutter code.

Correct, this ticket here (and the previous one) just want JSX like capabilities. There are other tickets for improvements of Dart language to diminish verbosity of current UI building code.

Are there people here who believe implementing JSX will solve readability?

It might for them, to each their own.

Yes, the example you provided makes the tree smaller but by breaking it into pieces and moving pieces somewhere else, it also makes it even harder to see the whole structure in code. I would rather keep the complete structure in one place and take out of the tree some related properties (named parameters) and use the spread operator of DSX to bring them in. Just my preference.

But what it would definitely add is an extra build/transpile step with source maps & co, and a lot of work to support this infrastructure in IDEs and Dart SDK (analyzer, debugger, etc).

We are handling this and @sethladd has stated that I believe one of the goals of Dart 2 was to create an infrastructure for more experimentation with the language and let the community create experiments like DSX.

@naiveaiguy

I would argue that the development cycle that Flutter has managed to achieve, even in 30-40% of code changes, is really impressive, and would only be slowed down by layers of transpiling.

Yes, I really enjoy hot loading even though it doesn't work all the time. I'll definitely take that but your comment with transpiling slowing that down is baseless. If you don't use DSX it won't add anything to your compile time. If you use DSX, the transpiler is so fast you won't even notice it.

Additional point: Please don't pretend that this is something third-party developers can do without any involvement or work on the Flutter core team's part. The Flutter team will have to do a lot of additional work with IDEs and editor plugins, and evangelism, and dealing with GitHub issues, if such a feature is to be implemented satisfactorily as a harmonious part of Flutter.

Not really. We are doing this and asking only not to be blocked. We are asking for guidance to point us in the right direction. I will not do all of this by myself, so now there are 2 of us (thank you @NathanaelA) and we are looking for more people (at least 1 more) if they want to help.

Greetings everyone! First of all, I would like to point out that it does not make much sense to continue the back and forth discussion on this issue - it will go large and hard to follow due to the linear structure. Your arguments will be lost and rehashed over and over again. Lets reduce this to pure numbers:

  • If you are FOR this feature - thumbs up the very first comment on this issue.
  • If you are AGAINST this feature - thumbs down the very first comment on this issue.

Next, I would like to clarify @sethladd's statement, it should read _"one of the goals of Dart 2 was to create an infrastructure for more experimentation with the language for the Dart team"_.

Even in Dart 2 we don't provide any APIs that allow you to easily change the syntax of the Dart language, without rebuilding Dart SDK (or Flutter engine artifacts). What Dart 2 provides is a _common front-end_ (CFE) infrastructure (located in pkg/front_end in Dart SDK sources) - which is a parser for Dart language written in Dart. For purely syntactic sugar language changes like DSX you should be able to just edit CFE code, build Dart SDK (or Flutter engine) and have all tools (except for syntax highlighting code built into respective IDE plugins) pick up your new syntax extension. Note that currently only VM and dart2js actually use CFE, analyzer is scheduled to transition next. As you can see there is certain barrier for entry here.

An important thing to highlight here is that because there is no API to extend Dart syntax you would have to work with Dart language team to have the language extended. Currently there is no formalized process for this, however for a feature like DSX there would need to be a lot of evidence and motivation for it to be included into Dart. (/fyi @leafpetersen @lrhn - please correct me if I am wrong)

Here are my recommendations to proponents of DSX like solution:

  • First of all you actually need to put your proposal in writing and move discussion to a place that facilitates non-linear discussion. When you propose language changes you need to have an _elaborate_ description of what you are trying to solve and how it is solved using your proposed syntax extensions. Otherwise it is impossible to evaluate costs and benefits of the proposed change. Then you need a way to have non-linear discussions about different parts of the proposal, e.g.

    • if you put your proposal into Google Doc, then people can use builtin comments to discuss various components of your proposal;
    • alternatively you can create a GitHub repo with markdown description of your proposal, and use GitHub issue and PRs to refine and discuss your proposal.

    Note, I am not saying that you need to come up with _formal specification_ for your change that would be comparable to Dart language specification in the level of refinement. Instead you need to have extensive examples of how the proposed change functions and what benefits it provides.


  • Next if you can you should try to have an implementation. The barrier is high here even with CFE infrastructure - but much lower than it was before.

@mraleph I think the arguments about integration into Dart was more about hooks to invoke code generation or similar, not to change the language.
I have no idea anything like that is necessary.
I think this could mostly be implemented like Angular with its Analyzer plugin, just DSX instead of HTML

@mraleph

Thank you very much for the clarification.
We don't really want to modify the Dart language, what we need is pre-processing capability in order to transform our experimental DSX into Dart.
By the way you can try it online at:
https://spark-heroku-dsx.herokuapp.com/index.html

Thing is when Dart first came out it was able to transpile to Javascript and by using source maps it was able to just plug into the Javascript ecosystem (several other languages did the same: Coffeescript, Typescript, etc). What we are looking for is something similar to this for Dart/Flutter. We are looking for generic pre-processing capability that would enable any other transpiling language to be built on top of Dart/Flutter.

With respect to voting, the previous ticket has some numbers:
https://github.com/flutter/flutter/issues/11609

@cbazza

We don't really want to modify the Dart language, what we need is pre-processing capability in order to transform our experimental DSX into Dart.

I was talking from the perspective that *.dsx files are actually Dart files in which you can use some additional syntax. And as I said there are currently no APIs or extension points that facilitate creation of such syntax extensions in a way that allows these syntax extensions to interoperate transparently with all tools in Dart ecosystem. Furthermore, I don't think there are any immediate plans to design and provide such APIs or extension points - so your best bet as of today is to fork Dart SDK and built DSX support into CFE.

I also recommend thinking about corner cases - rather than thinking about simple cases. For example imagine you are editing your DSX file. In this case you most likely want to see real-time completion on half-finished code, e.g. constructor names and attribute names. How would that work with source-mapping? Things like that constitute developer experience.

@mraleph Thank you once again.

We are certainly aiming to provide a great user experience for DSX users that's for sure.

Some people like XML-like syntax,some people hate it.Maybe adding jsx-like syntax is too overkill.My main concern about Flutter is readability.IMHO,there is still room to improve current syntax of Dart and Flutter(For me it is mainly about deep nesting parentheses,child ,children,semicolon noises,etc.)
Reposting some exmple code[1]here,

// Comparing Flutter to what it might look like in Kotlin
class TutorialHome : StatelessWidget {
    override
    fun build(context: BuildContext) = scaffold {
        appBar = appBar {
            leading = iconButton {
                iconImage = Icon(Icons.menu)
                tooltip = "Navigation menu"
                onPressed = null
            } 
            titleText = "Example title"
            actions = [ // based on https://twitter.com/abreslav/status/867714627060322305
              iconButton { 
                iconImage = Icon(Icons.search)
                tooltip = "Search"
                onPressed = null  
              }
            ]
        }
        body = center {
            // Remember: This is a fully functional programming environment. You can execute any 
           //  code you can think of.
            child = Text("Hello ${MyApp.users.me.fullName.split(" ").first}!")
        }
        floatingActionButton = fab {
            tooltip = "Add"
            childImage = Icon(Icons.add)
            onPressed = null
        }
    }
}

Dart 2 version with new and semicolon optional(code from @sethladd)[2],

class TutorialHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Scaffold(// implicit new!, also matching your Kotlin here
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.menu)
          tooltip: 'Navigation menu'
          onPressed: null
        )
        title: Text('Example title')
        actions: [ // Dart + strong mode will infer the contents of the list
          IconButton(
            icon: Icon(Icons.search)
            tooltip: 'Search'
            onPressed: null
          )
        ]
      )
      // body is the majority of the screen.
      body: Center(
        child: Text('Hello, world!')
      )
      floatingActionButton: FloatingActionButton(
        tooltip: 'Add' // used by assistive technologies
        child: Icon(Icons.add)
        onPressed: null
      )
   )
}

IMO, the kotlin version is clean and looks better.Dart 2 version is very close and still has room for improvement(if Dart support extension methods?). So i think improving Dart syntax to reduce verbosity is the right direction.

[1]https://gist.github.com/asarazan/b3c23bef49cf9a61f5a1a19de746f1b0
[2]https://gist.github.com/sethladd/7397a067deb43b6052032195fcb26d94

Another angle, I like the compose ability of JSX.

Working with the components (widgets) is very easy and accessible, moving them up and down the tree in a editor is just a matter of a keyboard shortcut (Alt+UP / Alt+DOWN). This is especially true for when moving stuff in and out of container, row, column etc.

But this isn't something that DSX would solve on it's own. The widgets them self would need to be
more restricted with property naming for this to work. In React, this is a property called children and is a main principal in JSX. Flutter allows flexibility in children naming (childs, children, body, etc.).

Here is a great discussion of pro's and con's: https://github.com/jsforum/jsforum/issues/1

Dart DSX

Source: https://github.com/flutter/flutter/blob/master/examples/platform_view/lib/main.dart

I have to admit the DSX sample looks appealing. But I fear as soon as you mix it with Dart Code e.g. When using any builder widget it will look really ugly.

@birkir DSX should be able to support something like the render props pattern for multiple/non-children child slots. If it can take functions or class references as props (which it probably would automatically) it would work out of the box.

As far as the tooling implementation goes, Javascript tooling has supported non-standard syntax and language extension for a long time (Flowtype/Typescript/Babel) so a lot of the tools for JSX leveraged existing transpilers. Afaik Dart hasn't experienced that level of fragmentation so the tooling doesn't exist yet. But now's a good time to start building it 😄

IMHO, json-like syntax is much better than ~xml-like~ syntax!

container {
  padding: EdgeInsets.symmetric { vertical: 16.0  }
}

@jaychang0917
I do not think JSX can be compared to XML. I think JSX and XML are two different things as supersonic aircraft verse propeller aircraft.

With JSX, you can do things like following:

<supersonicAircarft 
          aircarft={{"F-22"}} 
          speed={{"mach2"}} 
          style={{"you can style it whatever you want as simple as css"}}
/>

or

<Image
          source={{uri: 'https://i.chzbgr.com/full/7345954048/h7E2C65F9/'}}
          style={{width: 320, height:180}}
        />

With JSX, we can even break everything piece by piece as above, or you can group a large part of UI into one <> tag to put this large part of UI anywhere you want.

This is why React replaces HTML and XML and adopt JSX for building either an iPhone app or web app, or people say JSX is just a cooler version of HTML.

  • I do not like both XML and HTML and love JSX.
  • I think the most important thing is not about performance as iPhone vs desktop.

  • The most important thing is easy to use as iPhone vs desktop. JSX is a good example of easy to use unlike XML or HTML.

For example:

import React, { Component } from 'react';
import { Image, ScrollView, Text } from 'react-native';

class AwkwardScrollingImageWithText extends Component {
  render() {
    return (
      <ScrollView>
        <Image
          source={{uri: 'https://i.chzbgr.com/full/7345954048/h7E2C65F9/'}}
          style={{width: 320, height:180}}
        />
        <Text>
                        JSX is the philosophy, everything is a component. Simple is Complicate because you can 
                        form everything to your own perfect shape. 
        </Text>
      </ScrollView>
    );
  }
}

or write

< AwkwardScrollingImage/>

to write-once-runs-everywhere

import { AwkwardScrollingImage } from './your-native-code';
class SomethingFast extends Component {
  render() {
    return (
      <View>
          <AwkwardScrollingImage/>
        <Text>
            JSX is the philosophy, everything is a component. Simple is Complicate because you can form everything to your own perfect shape. Everything is a widget or component.
        </Text>
      </View>
    );
  }
}

~Flutter is using a programming language to build a UI.~

Reference:

Flutter:
https://flutter.io/tutorials/layout/
React Native that build android, Iphone, and even desktop:
https://facebook.github.io/react-native/

@birkir
Ohh that looks so goooood !!! just meat and no bones :)
Imagine using https://builderx.io/ with it (take a look at second animated image - 2 way UI building like Flex use to do :)

@escamoteur
with inline builders it would look as messy as with the current way; samples were provided above:
https://github.com/flutter/flutter/issues/15922#issuecomment-377780062

anyway, i think the current way is clear and consistent. Mixing some dart code and < tag in a dart file makes me feel that the code is awkward and unclear. From an android developer's point of view, it looks like writing java/kotlin code in a layout xml file:)

JUST MY TWO CENT

@JonathanSum um...

So which advantages of using JSX that current flutter way can't do? I don't see any arguments you said are strong.

JSX is not XML like. JSX is simpler and powerful than that XML.

Btw, JSX is xml-like, if facebook team doesn't lie to me:)

@jaychang0917
JSX is not XML because JSX is simpler and more powerful than that XML.(I say JSX is not XML like)

If you say there are no strong arguments, let me ask you a question. Did I show an example that JSX can inherit a large part of the code as the Object in Java and run this inheritance again anywhere you want ?
Let me just end my talking here. If people want JSX or DSX whatever, there will be one similar in the future.

  • Reference:
    https://facebook.github.io/jsx/
    This specification does not attempt to comply with any XML or HTML specification. JSX is designed as an ECMAScript feature and the similarity to XML is only for familiarity.

I do miss the real closing tags from XML though :)
Idea: Auto generated closing tags

Kotlin would have solved this too. Just look how awesome Kotlin-react and Anko are

Kotlin-react is not that awesome, KSX would had been better :)

import React from 'react';

export function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
package hello

import react.*
import react.dom.*

fun RBuilder.hello(name: String) {
    h1 {
        +"Hello, $name"
    }
}
package hello

import react.*
import react.dom.*

fun RBuilder.hello(name: String) {
   <h1>Hello, {name}</h1>
}

Tags just don|t belong there :)

Being on the JSX/DSX/KSX camp, I certainly believe tags belong inside code :)

@saied89
Do you want to use a tag to nest an element inside another element just like HTML? Or do you want to type out a word "children", "child", or [ ]? In addition, JSX does provide things like reusing hundreds of UI code by only typing down one tag.

Perhaps one other aspect is the default formatting that dart format does. IMHO it is hard to read especially with the leading child: /children.

I would really prefer some formatting that emphasizes the tree structure something like that:

 Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("WeatherDemo")),
      resizeToAvoidBottomPadding: false,
      body: 
        new Column(children: <Widget>
        [
          new Padding(
            padding: const EdgeInsets.all(16.0),
            child: 
            new TextField(
                    key: AppKeys.textField,
                    autocorrect: false,
                    controller: _controller,
                    decoration: new InputDecoration(hintText: "Filter cities",),
                    style:  TextStyle(fontSize: 20.0,),
                    onChanged: ModelProvider.of(context).textChangedCommand,
                    ),
          ),
          new Expanded(
                child: 
                new RxLoader<List<WeatherEntry>>(
                        key: AppKeys.loadingSpinner,
                        radius: 25.0,
                        commandResults: ModelProvider.of(context).updateWeatherCommand,
                        dataBuilder: (context, data) => new WeatherListView(data ,key: AppKeys.weatherList),
                        ),
          ),
          new Padding(
            padding: const EdgeInsets.all(8.0),
            child: 
            new Row(children: <Widget>
            [
                new Expanded(
                    child: 
                    // This might be solved with a Streambuilder to but it should show `WidgetSelector`
                    new WidgetSelector(
                            buildEvents: ModelProvider.of(context).updateWeatherCommand.canExecute,   //We access our ViewModel through the inherited Widget
                            onTrue:  new RaisedButton(    
                                            key: AppKeys.updateButtonEnabled,                           
                                            child: new Text("Update"), 
                                            onPressed: ModelProvider.of(context).updateWeatherCommand,
                                            ),
                            onFalse:  new RaisedButton(                               
                                            key: AppKeys.updateButtonDisabled,                           
                                            child: new Text("Please Wait"), 
                                            onPressed: null,
                                            ),

                        ),
                ),
                new StateFullSwitch(
                        state: true,
                        onChanged: ModelProvider.of(context).switchChangedCommand,
                   )
              ],
            ),
          ),
        ],
      ),
    );
  }

This may not be the ideal solution but it should show the direction.
@sethladd any chance to do something in that direction?

First of all, i'm glad this is not getting as heated as its sister issue was :smile:.

If i were asked to pick any of the 2 syntaxes, I'd lean towards the Dart side. This is based in several facts:

  • I prefer switching between as few contexts as i possibly can. Like it or not, jumping between syntaxes is a way of doing that. This can be helped with tooling support but this leads into the point below.
  • I prefer that the development team dedicates time to other issues that prevent us from coding certain features and/or stop people from jumping into Flutter. I think that not having JSX-like syntax should not be the reason a company/developer/whatever dismisses Flutter.
  • We would benefit from every Dart update. This specially true for Dart since Flutter is one of its main customers and it's a UI framework. See the new/const changes for example.
  • I highly value type-safety. Not saying that a JSX-like syntax can't be type safe, i don't believe the effort in accomplishing it is worth its revenue.

That aside, I actually favor a Kotlin-like syntax. Specially if said syntax brings along some Kotlin features over to Dart :innocent:.

@emalamela,

Here is the thing, there is no context switch as you call it, just ask any seasoned React developer. Also this syntax separation is actually a great feature because when you look at the code you can easily see what is declarative and what is imperative.

I think that not having JSX-like syntax should not be the reason a company/developer/whatever dismisses Flutter.

But unfortunately it will be for a lot of React developers.

We would benefit from every Dart update.

I don't see how DSX doesn't also benefit from Dart updates since it is a superset of Dart.

I highly value type-safety. Not saying that a JSX-like syntax can't be type safe, i don't believe the effort in accomplishing it is worth its revenue.

The effort to accomplish type safeness in DSX is zero because DSX is just a tiny syntatic sugar layer on top of Dart, so it uses Dart type system just like it uses Dart control statements, etc.
https://github.com/flutter/flutter/issues/15922#issuecomment-377780062

Thanks for your input @cbazza !

Here is the thing, there is no context switch as you call it, just ask any seasoned React developer.

I'm no seasoned React developer so for me it is a context switch. Just like in Android you have to jump from Java/Kotlin to XML, albeit the jump is larger there. One languages, same tooling, less overhead.

Also this syntax separation is actually a great feature because when you look at the code you can easily see what is declarative and what is imperative.

The way it is now is quite declarative in my opinion.

I don't see how DSX doesn't also benefit from Dart updates since it is a superset of Dart.
The effort to accomplish type safeness in DSX is zero because DSX is just a tiny syntatic sugar layer on top of Dart, so it uses Dart type system just like it uses Dart control statements, etc.

Fair points. But DSX is still something to be maintained and improved, that still implies effort that i would like to see being focused in other more critical/lacking aspects of the ecosystem.

Another aspect about the discussion that i don't agree with is the constant comparison with React. I understand its relevance but i don't want Flutter to be a copy of React without the JS bridge and changing the name of Components to Widgets. If it's the same, then why change? That doesn't mean that Flutter should try to be as far as possible from React. Flutter should have its own identity. I prefer that the Flutter culture of providing solutions is proactive, not reactive. We should use React only as a contrasting point, not as a guideline.

As far as i'm concerned, if any developer chose not to develop in Flutter because of DSX/JSX not being supported, well that person didn't want to join Flutter at all.

Another aspect about the discussion that i don't agree with is the constant comparison with React. I understand its relevance but i don't want Flutter to be a copy of React without the JS bridge and changing the name of Components to Widgets. If it's the same, then why change?

Because React has gaps that Flutter could fill and then you create something that is better than React because it fixes React's cons with Dart performance and GPU accelerated graphics, while keeping the best parts of React as well as it's familiarity.

As far as i'm concerned, if any developer chose not to develop in Flutter because of DSX/JSX not being supported, well that person didn't want to join Flutter at all.

It doesn't matter, the end result is that if mobile developers that are using cross platform tools don't join Flutter, Flutter will fail in the marketplace. So Flutter needs to attract React Native developers for its survival.

Talking about evolution, it's not 'survival of the fittest', it's 'survival of the most adaptable'. Adapt or you perish.

@cbazza

It doesn't matter, the end result is that if mobile developers that are using cross platform tools don't join Flutter, Flutter will fail in the marketplace.

What? Why would it need to? Flutter can form its own niche while it's in beta (as it has done very successfully), and then grow organically without needing to attract moths with superficially similar features. Also what do you mean "fail"? Flutter doesn't need to be popular to be a success.

@naiveaiguy
Look, I know you have downvoted cbazza's replies.
But could you spend 15 seconds to look at this before you downvote my reply?

Before you think about DSX.
Just take a look in below, it is just a JSX.

After you have built a nav bar and a body, you can just import the nav bar code from your nav bar code.

import XXXXX, { Component } from 'XXXXX';
import { Text, View } from 'XXXXX-native';
import navbar from "your code1"
import body from "your code2"

class SomethingFast extends Component {
  render() {
    return (
      <View>
        <navbar
            style={{width: 360, height:90}}
         />
        <Image
          source={{uri: 'https://google.com/dsx.jpg/'}}
          style={{width: 320, height:180}}
        />
        <body/>
        <Text>
          Look at @escamoteur s code from above.
           Can you export part of UI code to another place,
           separate it into different modules, and read everything in few seconds or less?
        </Text>
      </View>
    );
  }
}
       I think cbazza is right.
       If flutter uses DSX or whatever that is JSX,
       it is a perfect UI framework.

       So, could we have something
       similar or better in the future?
       Or do you really think that the
       current is fine?

Maybe someone hates JSX because it is from Facebook, but in fact, it is from a small Japanese game company.

Having done apps with React Native and Flutter, I feel that at the current state JSX is easier to read and adjusted than pure nested Dart classes.
However, like mentioned before, Facebook had a reason to use JSX due to how JavaScript is written (e.g. no named constructor parameters) which is not the case with Dart. Also the added Dart type-safety is nice indeed!
So in case Flutter sticks to pure Dart syntax in the end, I would hope to see improvements with the syntax highlighter and auto formatter. The new closing tag comments are a big improvement already but not enough to reach JSX productivity.

@JonathanSum You are explaining the idea of reusable components. You don't need JSX to do reusable components. I think would could have something better by refing Dart's syntax, but DSX is not a good way of going about it at all.

@hartmannj We're always on the lookout for improvements to the Dart syntax, highlighter, and formatter that will help with productivity. For any specific ideas or proposals for such improvements that you or others may have thought of, I'd be very curious to learn more.

IMHO removing the need to use new/const already helped a lot. I have real difficulties in the way dart format formats the trees. it does not emphasis enough the tree structure IMHO compared to:

    return Scaffold(
      appBar: AppBar(title: Text("WeatherDemo")),
      resizeToAvoidBottomPadding: false,
      body: 
        Column(children: <Widget>
        [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: 
            TextField(
                    key: AppKeys.textField,
                    autocorrect: false,
                    controller: _controller,
                    decoration: InputDecoration(hintText: "Filter cities",),
                    style:  TextStyle(fontSize: 20.0,),
                    onChanged: ModelProvider.of(context).textChangedCommand,
                    ),
          ),

https://reactjs.org/docs/introducing-jsx.html

React doesn’t require using JSX, but most people find it helpful as a visual aid when working with UI inside the JavaScript code. It also allows React to show more useful error and warning messages.

When so many developers eager to use JSX-like to build UI,it means the way is needed and they should not be ignored.

@woodstream The kind of people who are eager to use JSX are already React fanboys fans. They're already using React Native. Flutter is catering to a very different type of developer.

EDIT: I admit my usage of fanboy was wrong here.

@naiveaiguy, @Hixie

The kind of people who are eager to use JSX are already React fanboys. They're already using React Native. Flutter is catering to a very different type of developer.

You are wrong and your name calling divisive comments ('React fanboys' & 'different type of developer') are unwelcome. JSX/DSX has technical merit and others prefer it. This thread is to discuss that, if you don't like it, unsubscribe from it. Also stop down-voting every single one of my comments, it just doesn't bode well for you.

I just suggest offering two ways for developers to choose which they like, and someone like to give thumbs down in front of different opinions? Technology should be open and inclusive rather than playing in a closed community.

@anders-sandholm I agree with @escamoteur about the need to enhance the visibility of the widget tree. I would have done his example like following:

return
      Scaffold(
          appBar: AppBar(title: Text("WeatherDemo")),
          resizeToAvoidBottomPadding: false,
          body:
        Column(children: <Widget> [
          Padding(
              padding: const EdgeInsets.all(16.0),
              child:
            TextField(
                key: AppKeys.textField,
                autocorrect: false,
                controller: _controller,
                decoration: InputDecoration(hintText: "Filter cities",),
                style:  TextStyle(fontSize: 20.0,),
                onChanged: ModelProvider.of(context).textChangedCommand,
            ),
          ),
        ])
      );

Furthermore I could imagine highlighting the Widget class names with a different color, font style or weight so it would be even more recognizable right away.

@cbazza

Name calling? I didn't imply that these people were negative, only that they were different. I do like this thread but accusing me of arguing in bad faith is a bit ironic.

The word "fanboy" is generally considered a derogative, and was taken so in this context as well. I recommend avoiding words like that in discussions here.

Please everybody, be civil and constructive. We are discussing style here, something very subjective, so no matter how much everyone likes their own preference, it is unlikely to be inherently superior to everybody else's. Do list the advantages and disadvantages that you see with existing and proposed syntaxes, but remember that not everybody sees it the same way, and that's perfectly fine.

@hartmannj

Just some minor clarifications...

However, like mentioned before, Facebook had a reason to use JSX due to how JavaScript is written (e.g. no named constructor parameters) which is not the case with Dart.

Actually since ES2015/ES6, JS has had named parameters; you can just use 'de-structuring' for it :)
Here is an example:

// function declaration
function findUsersByRole ({
  role,
  withContactInfo, 
  includeInactive
}) {
  if (role === 'admin' && withContactInfo) {
  ...
  }
...
}


// usage
findUsersByRole({
  role: 'admin', 
  withContactInfo: true, 
  includeInactive: true
})

https://medium.freecodecamp.org/elegant-patterns-in-modern-javascript-roro-be01e7669cbd

Also the added Dart type-safety is nice indeed!

You get the same type-safety with DSX, which is indeed nice.

Since this is a duplicate of the earlier-reported https://github.com/flutter/flutter/issues/11609, I'm going to close this one in favour of that one.

i really dont understand how people can vote against this- something which is so second nature to the way declarative code is written in the internet era..

<like><this /></like>

please be flexible enough to give flutter the chance to fly!

sadly this looks hopeless, every technology used markup to create UI in the past and even now and all of that developer experience is now being wasted by flutter.

we dont need to do it like react native or html, just use simple xml

and maybeeee... xml embedded in dart! ;P

On Tue, 28 Aug 2018 at 21:29, Touseef notifications@github.com wrote:

we dont need to do it like react native or html, just use simple xml


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/flutter/flutter/issues/15922#issuecomment-416550338,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AC8aNdVb_NV8c8JH4t36OS1OOvX6kY58ks5uVSmjgaJpZM4S6HPa
.

--
Tony Polinelli

To me JSX-like functionality is the future and it will become a standard construct for declarative frameworks like React, Vue & Flutter.

we dont need to embed xml in dart if we can just have 2 separate files for UI and logic then we can easily follow mvvm, mvc or any other desired pattren.

I've said it in the other thread but:

If you really want JSX, a good starter is using code generation. Go with a .html or .xml file and generate widgets from these.

Obviously, this is not a full-fledged JSX, but it's a start. Enough to see how the community will react to it.
If that syntax gain traction, maybe Flutter team will reconsider the topic.

Otherwise, I think it's just a loss of time. We can clearly see from here that it is a heavily debated topic.

If flutter introduces and xml / jsx / call it what you want way of creating the UI I would start using it for production level apps in a heart beat!

I agree @leossmith tht is the only thing being a hurdle for production level apps.

I personally would prefer to _not_ add JSX or an external markup language. I prefer to keep everything in a single type-checked language. I feel a better approach is to continue improving the Dart language for the purpose of coding deeply nested declarative UI trees. They have already added some nice features in this area:

  • Making the new and const keywords optional helps.
  • Virtual closing tags in the IDE
  • dartfmt helps also

I prefer to keep everything in a single type-checked language

That's exactly what DSX/JSX does, the language is Dart for DSX, Javascript for JSX !!!

I feel a better approach is to continue improving the Dart language for the purpose of coding deeply nested declarative UI trees.

DSX is an improvement to the Dart language to better support deeply nested declarative trees. Just like JSX is for Javascript.

https://facebook.github.io/jsx/

The purpose of this specification is to define a concise and familiar syntax for defining tree structures with attributes.

@cbazza You raise a good point. JSX is just and improvement to JavaScript.

So first let's clearly separate two things:

  1. External DSL for defining UI. I am 100% against this. I have always believed this creates more problems than it solves. I wrote a blog post arguing this point. It got 58K views and surprisingly, almost no dissenting opinions: 80% of my coding is doing this (or why templates are dead)
  2. Language improvements. To make it easier to construct and visualize deeply nested UI tree structures. On this we both agree there is room for improvement.

But we differ slightly on the approach. There are two reasons JSX makes more sense for React:

  1. Data structure: On the web, JSX matches exactly the thing being generated (HTML DOM nodes). In flutter, we are generating Widget instances.
  2. Familiarity: People are used to looking at html code. But the DSX proposal deviates from JSX/XML just enough to invalidate this point.

Below are the two things (I believe) that make XML good (and readable) for constructing UI trees. The question is, can these be achieved without introducing XML into the language:

  1. XML has End tags. This is possible with or without an xml-ish syntax. Visual basic had it in the 90s (think End If). And other languages have it. The IDE does provide "virtual end tags" but this is kind of sketchy. I would prefer language support.
  2. XML has special treatment of children. Attributes are distinct from children. But I would argue that this is a double edged sword. There are some cases where Dart is actually more clear and expressive than XML in this respect. For example, container widgets with differing child content models:
MyWidgetA(children: [ w1, w2 ])
MyWidgetB(child: w1)
MyWidgetC(top: w1, bottom: w2)

Dave Proposal for end tag problem

ButtonsView(
        onDeal: onDeal,
        onHit: onHit,
        onStay: onStay,
)ButtonsView

This would be easy to read by humans. And a parser would just replace the )ButtonsView with ). Also, the IDE could provide better checking and assistance with this scheme. I would make it required any time the open and close parens are not on the same line.

Dave Proposal for the nested children problem

Some languages (like kotlin) allow special treatment for args of type lambda. They allow you to put the lambda argument outside the parens. See Passing a lambda to the last parameter.

I propose something similar for Dart, but as arg of type List, not for lambdas. I propose special syntax for passing a arg of type list that is named "children":

```
//instead of this:
Foo(a: 1, b:10,c:44, children:[...])

//we do this:
Foo(a: 1, b:10,c:44)[

]

For a Constructors/functions that take a single child or 2 children (like top and bottom) leave it as it, no change.

I prefer to keep everything in a single type-checked language

That's exactly what DSX/JSX does, the language is Dart for DSX, Javascript for JSX !!!

I feel a better approach is to continue improving the Dart language for the purpose of coding deeply nested declarative UI trees.

DSX is an improvement to the Dart language to better support deeply nested declarative trees. Just like JSX is for Javascript.

https://facebook.github.io/jsx/

The purpose of this specification is to define a concise and familiar syntax for defining tree structures with attributes.

@StokeMasterJack - your proposal for the end tag problem sounds the same as my proposal some time ago.
Idea: Auto generated closing tags

I think flutter needs something like this. I struggle with inserting new widgets inside a deep nest most days. I would use a JSX-like syntax just to get the end tag notation.

I don't want to have to write closing tags. It's a pain in JSX/html/xml. Especially when I want to refactor.
I think the virtual closing tags is pretty neat. It seems like a good compromise between both worlds.

If we really need some improvements here I think we can continue exploring on the IDE side. For example, vscode provides the following panel:

screen shot 2018-10-11 at 01 31 33

(Pretty sure Android Studio has the same)

Instead of stopping at the focused method, we could add constructors nesting too.
So that when hovering a specific class we'd get the following UI:

lib > main.dart > Foo > build > Container > Center > Text 

If it's about separating visually widgets from other kind of content, the IDE can do it too again.

We can have a different syntax hightlighting for widgets. Instead of the usual color used for classes, we can have a specific color for widget subclass


If it's about editability, then Flutter already provides all the tooling you need.

There are quite a few refactoring options, including:

  • Wrap into new widget
  • Remove widget
  • Swap widget with child
  • Swap widget with parent

With these in mind, you don't have to deal with parenthesis anymore.


In all honesty, I spent hours on a daily basis playing around Flutter for months. And I haven't felt any lack in readability or any disconfort in writing nested widgets.
While in comparison, I've used React for just as much and there _are_ some stuff that frustrate me.

@rrousselGit - those refactoring options you have sound useful. I don't see them on Android Studio 3.2.
I thought Android Studio would provide the best features for Flutter development.

@Rockvole

Here is a screenshot from Android Studio:

image

Activated as a quick-fix Option+Enter (macOS).
I use these all the time, super helpful.

On the topic: it seems that Flutter team is exploring options for "UI as code" and we might get more improvements on this front sooner or later. Though ideas of @StokeMasterJack sound interesting.

@Rockvole Great minds think alike!

@StokeMasterJack

Nice reply !!!

There are two reasons JSX makes more sense for React:

  1. Data structure: On the web, JSX matches exactly the thing being generated (HTML DOM nodes). In flutter, we are generating Widget instances.

The power of JSX is not on generating HTML/DOM nodes, it is in managing component hierarchies; React Native doesn't have HTML/DOM nodes right?

  1. Familiarity: People are used to looking at html code. But the DSX proposal deviates from JSX/XML just enough to invalidate this point.

Just like above, it is not about HTML code, it is about a syntax that becomes clearly separate from the imperative constructs of the host language and screams declarative markup for building tree hierarchies.

I am not a fan of your proposal or Kotlin's because it looks like a hack done to avoid doing a proper design. Instead of designing a DSL that looks distinct, now I have to look at the code and try to figure out what it does; The syntax looks ambiguous. There are benefits for separating imperative and declarative constructs; 3rd party tools can easily locate XML markup inside code for example.

@Rockvole

I would use a JSX-like syntax just to get the end tag notation

Good to know ;)

@rrousselGit

I don't want to have to write closing tags.

You don't have to; WebStorm for example auto generates the closing tag and it even renames the open or closing tags as you edit the other. Really great editor functionality that others should follow (looking at you 'VS Code').

In all honesty, I spent hours on a daily basis playing around Flutter for months. And I haven't felt any lack in readability or any disconfort in writing nested widgets

I hope you can appreciate that your experience does not reflect everybody else's experience. With the tooling, writing is not as painful as reading the code. Go to github to read other people's code and you will notice that reading is a pain, the code is too verbose and long with nested structures. It looks like when promise-chains were used before async/await showed a better way. Also it feels like declarative techniques are less important than imperative ones; I mean why isn't there declarative vector graphics constructs? instead I have to use imperative calls to Skia for vector graphics drawing for example.

You don't have to; WebStorm for example auto generates

Vscode does that too. But that it still not perfect. Especially in the refactoring step when moving things around.
I think virtual tags provides a much smoother experience here.

I hope you can appreciate that your experience does not reflect everybody else's experience

For sure ! I just wanted to point out it may be more of an inexperience with the tooling then an actual lack 😄

Go to github to read other people's code and you will notice that reading is a pain, [...]

I don't quite see how your arguments here are related to the topic.
The problem you listed comes from bad practices, not bad syntax. It's not Flutter's fault if peoples want to make a 500 long widget tree.

@pulyaevskiy - thanks for the useful tip, on Linux the quick fix is Alt-Enter. Not a very easy feature to discover, I scoured the top menu options but it seems to be nowhere except by magical keypress :)

I think virtual tags provides a much smoother experience here.

Do these virtual tags show up on source file in github for example?

I don't quite see how your arguments here are related to the topic.

Basically the language could provide constructs to make things less verbose as I mentioned in the promises vs. async/await example. In Flutter Widget constructors are enormous and a lot of times they take a lot of parameters; with DSX you can use the spread operator for example to compress a 10 line constructor into a 1 line constructor and hence you can still have the complete tree hierarchy visible with less noise around it. This makes reading the code easier and allows clean separation of style from tree structure for example. I am not saying this can't be done by re-structuring your Dart code but it can be done without much effort or re-structuring things around. You don't need to fit to the limitations of the language, the language fits to you.

The problem you listed comes from bad practices, not bad syntax.

Before async/await, best practices were to use promises instead of crazy event callbacks everywhere. Using promises causes readability problems that were addressed by async/await. It is basically the same thing just syntactic sugar but async/await is clearer when reading someone else's code.

This is a terrible example @woodstream

Update: Just to make my point and not just bashing out words without any arguments. The DSX equivalent is just as long... This is nothing to do with line count, or HTML.

class MusicImage extends StatelessWidget {

  TextStyle titleTextStyle = TextStyle(
    fontWeight: FontWeight.w800,
    letterSpacing: 0.5,
    fontSize: 20.0
  );

  Container titleText = (
    <Container height={116.0} padding={EdgeInsets.all(10.0)}>
      <Text style={titleTextStyle}>title</Text>
    </Container>
  );

  TextStyle authorTextStyle = TextStyle(
    fontWeight: FontWeight.w800,
    letterSpacing: 0.5,
    fontSize: 10.0,
  );

  Container music = (
    <Container
      height={40.0}
      decoration={BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(8.0))
      )}
      padding={EdgeInsets.fromLTRB(0.0, 5.0, 5.0, 0.0)}
      margin={EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0)}
    >
      <Stack>
        <Row>
          <Container
            height={30.0}
            width={30.0}
            decoration={BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(8.0))
            )}
            margin={EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0)}
          >
            {Image.asset('images/bg2.jpg')}
          </Container>
          <Column>
            <Text>music</Text>
            <Text style={authorTextStyle}>author</Text>
          </Column>
        </Row> 
        <Align alignment={FractionalOffset.centerRight}>
          <Icon icon={Icons.play_arrow} />
        </Align>
      </Stack>
    </Container>
  )

  @override
  Widget build(BuildContext context) {
    return (
      <Container
        height={168.0}
        margin={EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0)}
        decoration={BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(8.0)),
          image: DecorationImage(
            image: new AssetImage('images/bg.jpg'),
            fit: BoxFit.cover,
          ),
        )}
      >
        {titleText}
        {music}
      </Container>
    );
  }
}

As a React developer, I think what this community needs to do is to provide this feature themselves and when the developers start to adapt it and actually use it; the main contributors will be forced then to adapt it natively as well. I'm a React developer and I have a lot of issues dealing with how UI is written in flutter, I would love to move to flutter but the syntax isn't helping, I would even research of how to implement the JSX-like syntax myself, as said before "It's nice to have the option".

I think the one of the main reasons people are pushing against this is they can't imagine them using it. Truth is, you really don't have to, just like people use (comparing to react) React.createElement(Component, {}, null) as opposed to <Component /> If this is implemented, this will draw people to use Flutter in the first place, and thats what we really want. A large community dedicated to Flutter with support from each other. If it's not the kind of syntax you would use, oh well. But tons would prefer a JSX like notation as opposed to the current method.

Personally I think SGML and its derivatives are just plain ugly. If we're doing a DSL, why not one with QML-like syntax?

I also think some of the pro-DSX points are conflating features of Javascript as a language (that Dart as a language does not have) and features of JSX as a DSL. For instance,

Basically the language could provide constructs to make things less verbose as I mentioned in the promises vs. async/await example. In Flutter Widget constructors are enormous and a lot of times they take a lot of parameters; with DSX you can use the spread operator for example to compress a 10 line constructor into a 1 line constructor and hence you can still have the complete tree hierarchy visible with less noise around it.

That's not a feature DSX would magically grant, that's a feature JSX has because Javascript has it. Dart as a language could gain the spread operator (rather unlikely IMO), in which case you'd be able to use it with constructors and other function calls without needing a special DSL on top of things. It's also a feature that works largely because Javascript's objects, hashmaps and arrays are all essentially the same thing, which is most definitely not the case with Dart and is almost definitely never going to change.

And that I think is the problem that a lot of the people against the proposal have even if it's not vocalized - it's essentially a request to have Dart behave (or pretend to behave) like Javascript, and while there are some pros the fact is that they simply are different languages that have been diverging more and more since the early days of Dart 1.

Edit: Which is not to say that a markup/modeling DSL for UI is entirely a bad idea. It's honestly not, but I think that the inspiration for it should come from languages/frameworks that are a bit more similar to Dart/Flutter (in typing paradigm as well as other semantic details - I'm not talking about plain syntax) than Javascript is.

Dart as a language could gain the spread operator (rather unlikely IMO)

In fact spread for collections is already specified and ready for implementation, see Spread Collections and the whole "Language funnel" for more info about upcoming Dart language features.

@mraleph I was talking about the spread operator specifically in use in function/constructor calls and with objects, not just with Lists or Maps - that's what I think is unlikely. Sorry if that wasn't clear!

(I'm vaguely aware of that proposal, but the last I checked it you can't just spread a Dart Size(10, 10) the way you can spread/destruct a Javascript Size { width: 10, height: 10 }, or spread a list/map of arguments into a normal function call (not using Function.apply, which would sacrifice type safety))

@filleduchaos

Personally I think SGML and its derivatives are just plain ugly. If we're doing a DSL, why not one with QML-like syntax?

Because a lot of people, unlike you, don't think it is ugly and rather prefer it. You don't have to have much vision to see all of the enthusiastic React developers out there.

JSX/DSX brings markup into the host language Javascript/Dart in a way that enhances the host language and enables all programmatic language contructs on the markup. Very simple and powerful stuff.

That's not a feature DSX would magically grant, that's a feature JSX has because Javascript has it.

Not true at all; DSX can implement spread by itself, it doesn't need Dart to support it. It would be nice if it did but not a requirement. That's the beauty of transpiling from a higher language into Dart, the higher language doesn't need to be constrained by Dart.

My prototype online DSX transpiler processes spread operator just fine, check it out:
https://spark-heroku-dsx.herokuapp.com/index.html

And that I think is the problem that a lot of the people against the proposal have even if it's not vocalized - it's essentially a request to have Dart behave (or pretend to behave) like Javascript, and while there are some pros the fact is that they simply are different languages that have been diverging more and more since the early days of Dart 1.

Stop thinking about what current Dart is and focus on what it could be by taking the best ideas from all of the other languages out there.

I think that the inspiration for it should come from languages/frameworks that are a bit more similar to Dart/Flutter (in typing paradigm as well as other semantic details - I'm not talking about plain syntax) than Javascript is.

Typescript is typed and supports JSX. The closest UI framework to Flutter is React, and guess what React took off because of JSX. Please do come up with something better than JSX/DSX and if you do, people will stop asking for JSX/DSX but I haven't seen anything out there that I consider better so right now JSX is the state-of-the-art.

It is nice to see though that the Dart language people are taking the best ideas from other languages like Python (list & dictionary comprehension).

@cbazza

Because a lot of people, unlike you, don't think it is ugly and rather prefer it.

And vice versa. Why this one syntax and not any other, especially when it doesn't really have a strong relationship with the language? (With the Android SDK, Java and XML had had a relationship for years. Ditto with Javascript and HTML, which JSX strongly resembles. DSX as proposed would be bringing SGML syntax based on it making sense for other languages but not necessarily for _Dart_).

JSX/DSX brings markup into the host language Javascript/Dart in a way that enhances the host language and enables all programmatic language contructs on the markup. Very simple and powerful stuff.

Not true at all; DSX can implement spread by itself, it doesn't need Dart to support it. It would be nice if it did but not a requirement. That's the beauty of transpiling from a higher language into Dart, the higher language doesn't need to be constrained by Dart.

It's rather interesting to look at these two statements in juxtaposition, because they just go to prove my point. JSX is great (for Javascript) specifically because of its simplicity - it's simply sugar over what are already JS language constructs, it doesn't really implement any special semantics itself. You rightly praise that simplicity, then go on to say that DSX should implement semantics by itself independent of the target language apparently without recognizing 1) how much more work that is to ask for, and 2) how it entirely defeats the point of being a simple but powerful DSL.

My prototype online DSX transpiler processes spread operator just fine, check it out:
https://spark-heroku-dsx.herokuapp.com/index.html

I have seen your transpiler before, and while it is impressive work it in no way comes close to processing the spread operator in the way that Javascript as a language (and thus JSX) does by default. As has been mentioned, spreading (and eventually destructuring) collections is not very much at odds with Dart, and in fact is in the pipeline to be implemented. Spreading and destructuring any object (which, unlike in JS, are very much are not the same thing as Maps) is, and your transpiler doesn't appear to handle that either (and in fact requires putting arguments inside Maps, which is rather unidiomatic and unusable Dart (cannot be interacted with in a decently type-safe manner, for instance)).

Stop thinking about what current Dart is and focus on what it could be by taking the best ideas from all of the other languages out there.

Sure. But of the languages out there for Dart to lift from, personally JS isn't very high on the list - I honestly think trying to be too much like JS (for the sake of interoperability) crippled Dart in its early days.

I would love a UI DSL, sure. But that DSL should be idiomatic for _Dart_, not lifted wholesale from a semantically different language because of popularity alone.

And I would also like for people to stop conflating what Javascript does with what JSX the DSL does, because some of the benefits mentioned are actually language-level feature requests in disguise. To continue with the spread operator, if Dart as a language actually did support the full range of the operator as it is in JS then I don't see how return <SomeWidget {...someArgs, arg: newValue } />; is preferable to read than return SomeWidget(...someArgs, arg: newValue); or QML-like return SomeWidget { ...someArgs, arg: newValue }; unless one has some attachment to SGML.

@filleduchaos

Why this one syntax and not any other, especially when it doesn't really have a strong relationship with the language? (With the Android SDK, Java and XML had had a relationship for years. Ditto with Javascript and HTML, which JSX strongly resembles. DSX as proposed would be bringing SGML syntax based on it making sense for other languages but not necessarily for Dart).

Stop pairing up things you think go together (and have a relationship) and focus on picking best ideas regardless of where they come from. You are kind of artificially segregating things when there is no need for it.

I am picking JSX syntax because it is well regarded in React and that's what React people expect and want. This ticket is about that, if that is not for you, don't use it.

It's rather interesting to look at these two statements in juxtaposition, because they just go to prove my point. JSX is great (for Javascript) specifically because of its simplicity - it's simply sugar over what are already JS language constructs, it doesn't really implement any special semantics itself. You rightly praise that simplicity, then go on to say that DSX should implement semantics by itself independent of the target language apparently without recognizing 1) how much more work that is to ask for, and 2) how it entirely defeats the point of being a simple but powerful DSL.

Whether it implements new semantics or not, it is irrelevant. Simplicity comes from its usage. If it is easy for users/developers to use, they will use it. Users/Developers don't care about how complex internally something is (or how much work it was to do), they just care how simple it makes their life and improves their code.

I have seen your transpiler before, and while it is impressive work it in no way comes close to processing the spread operator in the way that Javascript as a language (and thus JSX) does by default.

My intention with spread on DSX was just to spread attributes and not a complete JS implementation of spread. It works just fine for what it is and it has no type-safe issues at all. Type checking/correctness occurs when Dart compiles what DSX generates.

crippled Dart in its early days.

What cripped Dart in the early days was not providing simple JS interoperability so current JS libraries could be used easily with Dart code (and vice-versa). Also this is the exact same reason why Typescript succeeded where Dart failed.

I would love a UI DSL, sure. But that DSL should be idiomatic for Dart, not lifted wholesale from a semantically different language because of popularity alone.

Popularity dictates everything. Best ideas are best ideas because they become popular because lots of people appreciate its benefits.

And I would also like for people to stop conflating what Javascript does with what JSX the DSL does, because some of the benefits mentioned are actually language-level feature requests in disguise.

Again this is not relevant.

What we really need from Google (Dart/Flutter) people is generic transpiling support via source maps so that any higher level language can be developed that targets Dart/Flutter and it would work just fine with the current tools (IDE, debugger, etc). Level the playing field and you guarantee the best ideas will come to the platform from others.

@cbazza

I am picking JSX syntax because it is well regarded in React and that's what React people expect and want. This ticket is about that, if that is not for you, don't use it.

That seems rather divisive and quite a bit entitled to me. Why should Flutter have first-class support for specifically React syntax? Why not Vue component files, or Xamarin.Forms syntax? Why must the (presumably official) UI DSL for Flutter be based on what one particular set of people using a different framework in a different language expect and want? If you want a community tool specifically for React/JS developers, that would be one thing. But asking for the framework itself to include it solely to cater to you all is a bit much IMO.

Whether it implements new semantics or not, it is irrelevant. Simplicity comes from its usage. If it is easy for users/developers to use, they will use it. Users/Developers don't care about how complex internally something is (or how much work it was to do), they just care how simple it makes their life and improves their code.

This is such a weird form of entitlement in my opinion. And no, developers will care about how complex an implementation is when it starts causing issues and feature drift as complexity in abstractions tends to do. Developers who want to do more than just use the DSL - extend it, for instance - will most definitely care about how complex the implementation is. The developers who would have to build and maintain it are also people that deserve consideration in this.

My intention with spread on DSX was just to spread attributes and not a complete JS implementation of spread. It works just fine for what it is and it has no type-safe issues at all. Type checking/correctness occurs when Dart compiles what DSX generates.

It only "has no type-safe issues" if you don't think about it at all. What I said was that Maps of arguments are not _usable_ in a completely safe manner with the rest of a Dart codebase, where presumably you would want to interact with those arguments the way you can with props and such in JavaScript - pass them down from another Widget, import them from another module, etc - and not just declare them in one place, in which case what's the point over a normal constructor call?

To illustrate what I mean, you can do this in JS:

class MyCustomSize {
  constructor(length, width, height) {
    this.length = length;
    this.width = width;
    this.height = height;
    this.calculateVolume.bind(this);
  }

  calculateVolume() {
    return this.length * this.width * this.height;
  }
}

const Cuboid = ({ length, width, height }) => { // blah blah }

const literalSize = { 'length': 30, 'width': 20, 'height': 10 };
const size = new MyCustomSize(30, 20, 10);

size.length = 100; // Can interact with the object as normal, no compromises
console.log(size.getVolume()); // and even call methods
size.foo = 50 // If you're using TypeScript, you get a nice error
literalSize.height = 15 // can interact with the hashmap as though it were an object

const SomeComponent = () => (
  <div>
    <Cuboid {...literalSize} />{/* valid */}
    <Cuboid {...size} />{/* also valid even though size is an object */}
  </div>
)

But with Dart and your transpiler that requires hashmaps of arguments:

class MyCustomSize {
  int length, width, height;

  MyCustomSize(this.length, this.width, this.height);

  calculateVolume() {
    return length * width * height;
  }
}

class Cuboid extends StatelessWidget {
  final int length, width, height;

  Cuboid(this.length, this.width, this.height);

  @override
  Widget build(BuildContext context) { // blah }
}

Map literalSize = { 'length': 30, 'width': 20, 'height': 10 };
Map invalidSize = { 'length': 300, 'width': 200, 'height': 100 };
final size = MyCustomSize(30, 20, 10);

literalSize.height = 15; // Invalid, you must use square bracket notation which is honestly ugly to do a lot of the time
invalidSize['foo'] = 50; // No indication of anything wrong here

class SomeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return (
      <Column>
        <Cuboid {...literalSize} />{/* Yes, works */}
        <Cuboid {...invalidSize} />{/* Sure the transpiled code errors as there is no parameter named foo. But this is now a completely opaque error. What if the `foo:50` key-value pair was added in some other section of your codebase? In a third party library even? How do you debug that*/}
        <Cuboid {...size} />{/* How do you plan on handling this as a plain transpilation step? */}
      </Column>
    )
  }
}

What cripped Dart in the early days was not providing simple JS interoperability so current JS libraries could be used easily with Dart code (and vice-versa). Also this is the exact same reason why Typescript succeeded where Dart failed.

Dart's interop with JS has never been complex, unless (and this is a point I keep stressing) you simply want to still write Javascript and are averse to learning anything else. Typescript being a superset does not so much have operability with JS as it simply is JS, to the point of deliberately having an unsound type system just to cater to JS (as well as no runtime to actually enforce its expressive type system, which is a damn shame this many years on). But back to my point, I personally feel Dart made quite a few poor design decisions for JS' sake and Dart 2 really should have been the first iteration of the language.

Popularity dictates everything. Best ideas are best ideas because they become popular because lots of people appreciate its benefits.

"Best", or rather good ideas are good ideas because they have merit. Sometimes they become popular, sometimes they don't. Sometimes bad ideas become popular, sometimes they don't. To suggest that popularity is a direct indicator of merit is frankly absurd and is an attitude I personally would very much rather not spill over into the Dart community, small as it is.

What we really need from Google (Dart/Flutter) people is generic transpiling support via source maps so that any higher level language can be developed that targets Dart/Flutter and it would work just fine with the current tools (IDE, debugger, etc). Level the playing field and you guarantee the best ideas will come to the platform from others.

...I didn't think it was possible to come of as even more entitled than you were before, and yet here we are. Why is it this one UI SDK that must be targetable by every high-level language on the globe? Once again the proposal strongly, strongly comes off as "Make Dart/Flutter into my language/framework" - you might as well just come right out and say you want to build Flutter apps with Javascript. And yeah, more grease to your elbow and I'd be all for contributing to a community project like that, but it's frankly ridiculous to expect a positive answer if you request official support for that.

Again reiterating - I don't mind a UI DSL and would actually love one. But if we're asking the team to bake it in then it should be a DSL that's idiomatic for Dart. Because yes, there are whole dozens of us out here who actually like Dart as a language.

Yet another edit: It would be one thing to request a DSL, suggest JSX as a possible syntax/syntax inspiration, and be open to other suggestions. It's the insistence on DSX that rubs me (and I suspect many who have commented) wrong.

@filleduchaos

You are hilariously confused and I don't have much time to waste yet.

The only thing I am asking of the Dart/Flutter team is what I said before:

What we really need from Google (Dart/Flutter) people is generic transpiling support via source maps so that any higher level language can be developed that targets Dart/Flutter and it would work just fine with the current tools (IDE, debugger, etc). Level the playing field and you guarantee the best ideas will come to the platform from others.

That provides everything necessary to implement DSX, Vue component files, Xamarin.Forms, NativeScript, QML, etc. and therefore would enable the community to come up with anything they want and nobody has to 'take' my DSX. Don't like DSX, you can use plain Dart or create your own thing with ease.

I'd say you're looking for things like https://github.com/dart-lang/build and dartanalyzer.
You'll likely miss a piece or two (like the ability to make analyzer plugins as pub dependency), but I'm pretty sure the Dart Team is fine with helping with that.

In any case, I don't think being harsh to each other continuously will help the framework progress in any way.
The most we'll get out of this is another permanently closed issue because it got "too heated".

@filleduchaos

Regarding your 'foo' example, DSX spread is a compile time thing so map would need to be defined as const or I could come up with anything else I wanted to make that happens at compile time (for example create a new DSX keyword or annotation for it followed by the const map). It has to be at compile time, instead of at run time, because Dart doesn't support dynamic constructor parameter insertion at run time. Not a problem because it solve the problem I wanted to solve, i.e. spreading attributes on constructors.

@cbazza The point is that part of what makes the spread operator so handy in JS/JSX is that you don't have to impose restrictions like "you can only use a hashmap" or "all your arguments must be known at compile time" or "you can't interact with the arguments/props you want to pass to a Widget in the same way you can interact with everything else" (note that you haven't suggested anything to handle the case where the thing with the properties you need is actually an object, not a map literal) -0 it's all well and good when it's a simple example, but that sort of thing would get extremely frustrating _fast_ in any medium-sized project. I mean, at what point does one stop piling on workarounds and compromises and annotations, take a step back and wonder if the extension is actually a good fit for the language as it exists?

JSX has been such a success (compared to most templates) because it doesn't force you to program a certain way (or rather, doesn't force you to write code any differently than you would have in Javascript anyway). It's pretty much completely painless to use with _any_ JavaScript; this is what I mean by creating a DSL that actually fits the language. It's a similar thing with Redux. Redux in a JS codebase is a thing of beauty (when it's used properly); on the other hand all the Flutter examples I've seen using Redux extensively honestly just look painful compared to using Streams/the BLoC pattern. That's not to say that there aren't things that overlap with great success: React's Context and Flutter's InheritedWidget implement a common concept that caters incredibly well to the strengths of both. I'm just not convinced that JSX is currently one of those things - barring several language-level changes, it honestly looks like DSX would be a pain to develop _and_ a pain to use for anything more than trivial examples, whereas one could probably write a feature-complete JSX transformer from scratch in a lazy weekend because of how straightforward it is to map to JS.

Also I was a bit aggressive earlier and I apologize.

@filleduchaos

I am not trying to create a fully generic spread operator that works everywhere and for everything, not even the one planned for future Dart is as generic as JS's one. What I want spread to handle in the context of DSX it does just fine. DSX has no need for spreading objects for example.

Spread Collections
https://github.com/dart-lang/language/issues/47

I have developed super large projects with JSX and have really never needed to use spread on the tag attributes. JSX works great without it. The reason I added to DSX is because it solves a problem for Flutter widgets that there is no simple solution for it, specifically if a widget takes 20 parameters on the constructor how can you write that in less than 20 continuous lines that will make the widget tree a pyramid of doom. The only feature of DSX spread is to enable taking some of those lines out of the tree and place it somewhere else.

@cbazaa I'm evaluating whether to use React Native or Flutter. Leaning towards Flutter because everything is just Dart so that the compiler can check my UI typos. Also see: https://medium.com/flutter-io/out-of-depth-with-flutter-f683c29305a8

Does JSX spot my typos as well? I use TypeScript.

I hate HTML / separate markups. For example, in Angular, if I mistyped something / variables in HTML, I only find my errors after rendering the page.

@sivabudh

Does JSX spot my typos as well? I use TypeScript.

Yes, some JSX typos are caught at compile time (component name for example) but not prop names (which will be caught at run time) when using JS/ES6; but since you are using TypeScript the type system catches all JSX typos at compile time:
https://www.typescriptlang.org/docs/handbook/jsx.html

@cbazza is dsx open source?

@pushqrdx
Not yet, I have not released its source code.

As a consumer of React + TypeScript and Flutter I can offer myself as a tester. Cheers

Will we have dsx source? It will be very great!

I applaud cbazza's efforts but I won't be using DSX in Flutter. Happy to test it out, though.

The issue #27141 tracks the addition of code generation support to the build system. This will be done through https://github.com/dart-lang/build with Builder. In theory it should be fairly simple to wire up a dsx compiler/transpiler when this feature is ready.

After two issues, I met such a stubborn team for the first time.

This is not a discussion of JSX, but a discussion of nested hell

Even if you can't give a JSX solution, you should make the nesting less and the code more readable

I think the advantage of JSX is obvious, but flutter team are trying to ignore it.

JSX doesn't solve the nesting issue. React face the same problem

If you dislike that nesting, you may want to take a look at hooks, which is a port of React hooks, which themselves are an attempt to solve the nesting hell.

I think we should find out why JSX comes into being. That's because the h/createElement function is poorly written and the code is poorly readable. Unexpectedly, flutter is now written 10,000 times worse than the h/createElement function, which can be seen from the eyes

JSX comes into being because React is, at its core, a blending of Javascript and HTML. The XML syntax with Javascript interpolation/injection naturally creates JSX.

Flutter is totally separate from Javascript and HTML, so it does not translate well into JSX. I agree that Flutter projects are often very nested and it can be a real pain, especially when dartfmt smashes these heavily nested lines. Horrible.

I would also note that I felt Flutter was horribly structured when I was new to it, coming from React, but Flutter is objectively a lot easier to work with when you get past the initial learning curve. The learning curve is not unique to Flutter, it's common when learning new frameworks. Flutter is especially difficult because it has no reason to act like the HTML syntax many people are familiar with.

I think there are ways to improve the nesting issue, and JSX isn't the answer.

Some ideas:

  1. Develop an internal style guide that requires people to break out massive flutter trees into smaller components.

  2. Get dartfmt to formally recognize that Flutter has a unique set of formatting needs compared to Dart packages and work with Flutter/Dart team to come up with a solution that is reasonable. @munificent

  3. Use code generation like @rrousselGit 's @stateless package to make it easier for developers to do number 1

To be fair, the nesting issue arise mostly when not wanting to refractor our code.

Widgets are made to be broke into many smaller pieces.
Use and abuse of the extract widget refactoring tool.

This both makes the code a lot more readable, reduce redundancy, and potentially even fixes bugs/increase perfs.

While I agree for the most part, Flutter widgets are so high level that I have seen many people do entire views in a single widget because... it actually works really well and you don't have to pass props down thru 4-5 levels of widgets. What you lose in the process is you get this horrible nested code that dartfmt smashes into something unrecognizable. So I get why people do it, I get that there is a solution, but I also get why people don't use the solution.

JSX comes into being because React is, at its core, a blending of Javascript and HTML. The XML syntax with Javascript interpolation/injection naturally creates JSX.

How do you explain the fact that React Native uses JSX and it has nothing to do with HTML?

How do you explain the fact that React Native uses JSX and it has nothing to do with HTML?

Because it uses React. They probably didn't want to reinvent syntax

Because it uses React. They probably didn't want to reinvent syntax

So JSX is not really the blending of Javascript & HTML as @lukepighetti states but it is rather a XML-like syntax extension to ECMAScript without any defined semantics... who's purpose is to define a concise and familiar syntax for defining tree structures with attributes.
It is all spelled out in the spec: https://facebook.github.io/jsx/

As I understand it, React was first released as react + react-dom with a jsx compiler, so the HTML + JavaScript blend was natural. After that, react was used to drive other renderers like react-native, react-vr, react-pdf, etc etc. So I still stand by my original statement as being reasonable and sensitive to the history and pedigree of React. The 2019 spec is the spec as of 2019 and does not address the history of React.

I agree

But for me there's a bigger issue. Vue and React works similarly in that aspect.
React has a createElement and Vue has a h function.

We're never manually instantiating components in both React and Vue. It's the framework that takes care of it.


Flutter behaves differently. We are directly manipulating the instance of a Widget.

As such in the Flutter world, a <Foo /> just means new Foo()

But in that case, the JSX is totally unrelated to Widgets. We're just changing the syntax of how we instantiate classes in dart.

To me this sounds like we're loosing the meaning of what creating a widget is.

@lukepighetti
react-pdf is not another react renderer, you must be thinking of react-canvas.
So react != react-dom != react-native. The react package is responsible for managing component hierarchies with the help of JSX so react doesn't care if it is generating react-dom, react-native, react-canvas, so react is not really about HTML.

The 2019 spec is the spec as of 2019 and does not address the history of React.

There is no such thing as the 2019 spec of JSX. There is only one version of JSX and it is the original one published in 2014 from the link I provided (https://facebook.github.io/jsx/).

@rrousselGit

We're just changing the syntax of how we instantiate classes in dart.

For the case of DSX with Flutter that's exactly what the transpiler is doing.

To me this sounds like we're loosing the meaning of what creating a widget is.

How can you lose something if nothing is removed, you are just gaining another way of doing something (that has benefits & drawbacks) and now you have freedom of choice, pick the one that best suites you.

Hi, I believe you may have a misunderstanding of my message. react drives other react renderers such as react-dom, react-native, react-pdf, react-vr, etc. Afaik, react and react-dom were released simultaneously so the heritage of jsx is, in my opinion, quite clear. I hope you're not digging into my message because we have different opinions on the value of JSX in the context of Flutter. Would probably be best to keep it on topic and not split hairs.

Hi lukepighetti , have you used react native with JSX for one to two month? If so, you must understand why building an app with JSX AND react native (or react, I know they are different) framework style is simple and well structure.
However, if you have not used for a period of time, you can never understand why JSX is so helpful and important.

I still hope Google can understand the beauty of JSX, and as we had many people supporting this. Google team may one day think about DSX or JSX for a React inspired framework, flutter.

Hi lukepighetti , have you used react native with JSX for one to two month? If so, you must understand why building an app with JSX AND React native (or React, I know they are different) framework style is simple and well structure.

I can't speak for lukepighetti, but I've been working professionally with React for two years, now doing some Vue. So I'm quite well versed when it comes to JSX.

Similarly, I've been using Flutter for about 2 years too. At first, I also thought that Flutter needed some sort of JSX.
But Flutter improved quite a lot in that period, and I changed my mind.

  • JSX is horrible to write by hand. It requires a lot of tooling to make it bearable, including auto-closing tags, auto renaming tags & emmet. And even then it's nowhere near as simple as Flutter's syntax.

For instance, refactoring Foo() to Foo(child: Bar()) is easy.
But refactoring <Foo /> to <Foo><Bar /></Foo> is not.

  • Flutter offers a lot of refactoring options that makes manipulating parenthesis even easier

  • Virtual closing tags that Flutter offers makes up for the lack of ending tags.
    _But they don't show up in code-reviews!_
    They actually do! You can do your code-reviews from your IDE. See https://code.visualstudio.com/blogs/2018/09/10/introducing-github-pullrequests

    • JSX doesn't translate well for the Flutter model.

What if a widget take both a child and children? Do we get:

<Foo
  child={<Bar />}
>
  <Bar />
</Foo>

?

In that case, it means that for consistency purpose child should always be treated as a named argument instead of using the children slot.

The thing is, very few widgets takes a children. The vast majority is either a single child, or a combination of custom named parameters (like Scaffold).

Which means the vast majority of widgets using JSX will look like:

<Container
  child={<Bar />}
/>

Which is _worse_ then:

Container(
  child: Bar(),
)

All summed up, I think Flutter is fine. And even if JSX were available, I doubt it'd actually improve things.

Like I said upthread I think there is a lot of conflation between what are actually JS/ECMAScript/general web features (object spreading, destructuring, interchangeability of objects/hashmaps, all DOM* nodes having a highly similar interface, the flexibility of HTML in general, etc) with what are JSX features. The former IMO are what make JSX pleasant to write. Without them, you're just writing XML, and most people I know who actually have a choice don't like writing XML.

*Worth noting that this above everything is my major opposition to trying to retrofit Flutter to XML. I don't think there is any real point trying to deny that JSX/React has deep roots in the web, and DOM elements have a longstanding standard of every node having _attributes_ and _children_. On the other hand Flutter doesn't bind devs to name a custom widget's slot for other widgets children or even child and I see zero reason why it should start doing that.

I can see why the other JSX thread was locked. I shouldn't have to defend my skills/experience in GitHub comments for explaining why I think JSX doesn't benefit Flutter. I could easily say "You don't have enough experience with Flutter to have any opinion about Flutter." Doesn't feel good, does it. Y'all enjoy your keyboard warrior tribe.

What if a widget take both a child and children? Do we get:

Why a widget need to have both child and children? It's either this or that。
Another topic,Flutter‘s some widgets use children, and the others use child , nobody thinks it's complicated and easy to confuse?children contains child, so no matter how many child you have,one or more then one,just use children to get the job done.

@rrousselGit

JSX is horrible to write by hand. It requires a lot of tooling to make it bearable,

Not just the whole React world disagrees with you but also the whole HTML world and XML world.

Flutter offers a lot of refactoring options that makes manipulating parenthesis even easier

So you are saying Flutter 'requires a lot of tooling' too but since you are biased you feel the need to trash the other side. FYI: best thing to do is accept that there are more than one way of doing something and that some people will prefer the other way of doing it.

They actually do! You can do your code-reviews from your IDE.

That doesn't solve the problem for all other online code review tools used by teams. These tools manipulate the source code and if it is not in the source code, it doesn't exist.

JSX doesn't translate well for the Flutter model.

That's just your bad opinion, anyone can see that DSX adds enhancements to JSX that fits perfectly with Flutter.
https://spark-heroku-dsx.herokuapp.com/index.html

So you are saying Flutter 'requires a lot of tooling'

No, I said "even easier" not "bearable".

I happen to answer to StackOverflow/Slack often, and sometimes even from my phone.
And I clearly have a bad time when answering html related question – but Flutter is fine.

best thing to do is accept that there is more than one way of doing something and that some people will prefer the other way of doing it.

That works the other way around. You should see that clearly, the community isn't 100% fans of JSX. The number of downvotes on both this issue and the previous one proves it.

That's just your bad opinion, anyone can see that DSX adds enhancements to JSX that fits perfectly with Flutter.

I disagree. The syntax contains a lot of complex characters that on many keyboard layouts are hard to access.
It contains tons of repetition too.


In any case, I don't understand why you're permanently so aggressive. We're all trying to make Flutter better.
There's no point in being harsh and making this discussion closed again.

If JSX does not work well in flutter, I can accept not joining JSX, but we should consider nested hell.

Another side story is the semicolon of dart language. It's really annoying.

Another side story is the semicolon of dart language. It's really annoying.

There's a request for this on dart-lang/language: https://github.com/dart-lang/language/issues/69
Go give it a 👍

This long discussion is about being able to use this:

<A property="a">
  <B/>
  <C/>
</A>

Instead of this:

A(property: a, children: [
   B(), 
   C()
])

Even if one agrees with the former syntax to be superior, something I personally don't do, this comes with ongoing maintenance costs, higher complexity and new possible error sources, not only in the language / framework but also the surrounding tooling like IDEs, debugger, linter, etc. It also increases build times. And it requires developers to learn a new syntax and occupy themselves with the internals of the transpiler, to understand when and how instances are being created. All this pretty much with the only goal of React & co. developers feeling at home.

Before of starting with new languages, I'd rather focus on improving Dart, which is far from ideal, missing important features like pattern matching, data classes, ADTs, destructuring, proper optionals, etc. Some of these PRs are open already 5+ years. This, opposed to adding a cosmetic and unnecessary markup layer to create widgets, has a huge impact on architecture, safety and overall code quality.

Even if this is relegated to "community driven", it's still time the community could spend working on something meaningful. But of course everyone can do with their time what they want. Just stop putting this disproportional amount of pressure on the Flutter team, please.

Hey i-Schuetz.
there is a reply section.

image

This is what I have been saying in this long post. JSX fixed the "spaghetti problem of HTML and XML" (unreadable and complicated UI code). In my personal opinion after using flutter, it is more complicated than JSX or worst.

In these years, I have been seeing people said Flutter cannot capture some of the advantages from React, for example, the true idea of everything is components.

Not sure I follow. In the text you highlighted, the user is saying that he found JSX easier to learn because he was familiar with HTML and it has a similar syntax. I don't see how this justifies the existence of JSX and even less an imitation for Flutter in any way.

I didn't add the replies to the screenshots simply because the images would take too much space. They seemed rather supportive of what I posted, so also redundant. I posted links.

@JonathanSum is Flutter more complicated than JSX, or is Flutter different from _React_ and that's causing friction from you? It's more verbose in some cases, yes, and quite arguably less readable without virtual closing tags in an IDE, but I'm not quite sure how using constructors is more _complicated_ than writing an XML-like DSL and I'm still not quite sure why so many people seem to think said XML-like DSL would be a silver bullet that would make using Flutter easier to _understand_. Especially considering that Flutter has no prior history with the problems that React/JSX was created to solve - React makes DOM manipulation easier and cleaner, and that's nice, but what exactly does that have to do with Flutter again?

In these years, I have been seeing people said Flutter cannot capture some of the advantages from React, for example, the true idea of everything is components.

Without touching the notion that React has some "true" idea of everything being components that Flutter does not, there are also some advantages of Flutter/Dart's design that React/JS cannot capture. And you can say the same (and vice versa) for most decent UI SDKs/frameworks/libraries. Incredibly, different projects are in fact different; perhaps people coming to one project might be better served if they don't start out expecting it to be [insert project they've used in the past]. 🙂

There are some interesting ideas out there https://github.com/munificent/ui-as-code

It would most likely be quite the breaking change, but the parameter freedom proposal got me thinking how much more concise build methods could be if Dart had e.g. Crystal's method arguments spec.

Of course, Crystal's compiler would come last in a race against a slug and a tortoise, so there's that 😅

I now agree not to add JSX and not to put extra pressure on flutter.

But as far as dart is concerned, it's far less elegant than JS or TS. I feel helpless

For instance, the development route of Microsoft UI technology is WinForm to WPF,and now in Flutter,abandon WPF and use WinForm instead。In response to developer‘s complaints, the Flutter team worked hard to implement the WinForm‘s visual window and property editor。

As a newcomer in flutter i must say thet this should be in the roadmap. If not jsx, a more human readable way of laying down widgets.

I can see a react class render function and and image of the rendered class and associate at the moment.

I can see a dart file and the rendered content and i will take 5-6 minutes to figure out how it works ...

I can make a semi-complex react class in 5 minutes in an plain text editor , because it's intuitive

I can't do that in flutter. Without autocompletion i'm done as a developer. I don't like to be dependent in a extension for developing something -.-

However. It's gonna be interesting how dart developers deal with this "problem" . In dart 2 they made it more readable . I don't know how they are gonna improve the readability in dart 3 -4 -5 . but i think a refactoring of the components build function is gonna be needed sooner or later.

EDIT:
Nevermind, just tried React Native again , and i hated jsx , the props system , the fact that everything was dynamic was really scary concept again , i guess it's just a personal opinion then. Leave flutter as it is....

They requested DSX, not only because they love JSX. They want Flutter.

UI declaration should be visually separated in the code for better code readability and support. Especially in large teams with lots of juniors/middles. Coming from Adobe Flex I can say that reading Flutter's UI declarations reduce productivity badly.
If not DSX(which would be awesome IMO) but something should be done with current situation at least on IDE level.
All of the former UI development frameworks had this feature and we should have it too.

UI declaration should be visually separated in the code for better code readability and support.

and for better integration with other tools like 'gui builders' for example.

Coming from Adobe Flex I can say that reading Flutter's UI declarations reduce productivity badly.

Imagine a UI declaration like MXML with Flutters power! I can only dream!

Now that we have codegen support, the best way to get something like this into the product is to create a package that enables it and show that it is hugely popular.

@Hixie is there any pointer to doc for codegen?

Now that we have codegen support, the best way to get something like this into the product is to create a package that enables it and show that it is hugely popular.

It looks to me like codegen is just for .dart -> .dart, the input file must be valid .dart file. That is not very useful for .dsx files since it is a superset of dart. I still need support for cross-compiling into .dart with source maps like features for debugging, etc.

Please give SwiftUI, which was released yesterday, a look. This seems to be what Flutter should be aiming to, instead of React-like markup.

Swift's implicit member expressions alone would be so amazing

I'm mixed about SwiftUI syntax. It's lite for sure, but some aspects look magical.

But we can technically have something relatively similar already:

Column(mainAxisSize: MainAxisSize.min)([
  if (foo) Text('foo'),
  Text('bar'),
]);

That's valid dart code, where Column is _still_ a class.

Here's a stateless widget showcasing it:

class Foo extends StatelessWidget {
  const Foo({Key key}) : this._(key: key);
  const Foo._({Key key, this.children}) : super(key: key);

  final List<Widget> children;

  @override
  Widget build(BuildContext context) {
    return Column(children: children);
  }

  Foo call(List<Widget> children) {
    return Foo._(key: key, children: children);
  }
}

It's boilerplat-ish, but a code-generator can help – especially with the upcoming extension members.


The only issue about this approach is that we're both losing const constructors (since it uses a function to specify children) and instantiate the widget class _twice_.

If that syntax is desired, ideally instead of a call method, it should be implemented using constructor currying.

@rrousselGit I'm curious about what aspects of SwiftUI look magical to you - it seems like pretty straightforward extension of Swift syntax to me.

On their code example from here:

  • Content is mutable? Does that mean they have a built-in Mobx / Vue store?
  • What's that @State?
  • Why is body a variable? Is that a getter? If so, when is the getter called again?
  • is body part of an interface, or many similar variables inside Content?
  • What does that item in _exactly_ do? Why is the right operand of in not something iterable, but the "result" instead?
  • Why is the Image aligned left to the title/subtitle when there's no HStack?

I can't remember for certain, but I'm pretty sure I didn't have such questions when picking up Flutter.

@rrousselGit That might be because of your background, not because Flutter syntax or semantics is inherently obvious (I've met plenty of people who were quite stumped by it). And the points you've raised seem to be a weird junction of overanalysing a 14-line code snippet for faults while not actually knowing the language it's written in.

  • It's not really mutable (in the Dart or JS sense) though? It's a struct. Also MobX/Vue-style stores (i.e. papering over pretty limited language support) are not the only way to handle mutability

  • @State is an attribute, otherwise known as an annotation in some languages (e.g. Dart), otherwise known as a very common thing in Swift code. If you mean what it does, even without looking at the docs it most likely marks a property as state that will change over time.

  • body is a computed property, which is readily apparent to Swift developers. As for when it's recomputed, does Widget build(BuildContext context) also inherently tell you when it's called again?

  • Content (again quite clearly to Swift developers) extends/implements View, which is where you'd look for answers to your question (it actually has a very nice API reference page).

  • This is pretty much "why is the keyword in this language not the same thing as the keyword in the language I use", not anything particularly "magical". The in keyword here is not the same thing as a for...in construct - it indicates that the body of a closure is about to begin. { item in ... } is a function block passed to the List constructor; a ListView's itemBuilder, if you will.

  • Are you legitimately asking why a view has its own encapsulated layout rules?

On SwiftUI:

1-Nice to see state declared in the View and not as a side appendage.

2-Nice individual methods to set things instead of having to pass everything on the constructor (methods enable actions to take in effect instead of just data being passed in).

3-Very nice to see declarative vector graphics mixed in with everything else that is declarative (like I suggested in the past with declarative SVG like widgets) !!!
https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes

4-Very simple animation & transition constructs
https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions

5-Drag&Drop design tools in synch with code editor both ways.

There are warts as everything else but I rather focus on what they did very nicely.

These "questions" exists just to showcase potentially confusing points. These are not _actual questions_.

That might be because of your backgroung

Likely. I'm not saying that their approach is bad or anything. I'm saying it didn't feel natural to me as it did with Flutter.
Flutter widgets use almost no "fancy language feature" and could be implemented on nearly any languages (although the recent if/for for collections change that).
While their showcase of SwiftUI extensively uses Swift specific features.

As for when it's recomputed, does Widget build(BuildContext context) also inherently tell you when it's called again?

My point here is the lack of relationship between State and the act of recomputing body.
React and Flutter are very explicit on that matter: setState.
Vue/Mobx are "magical", using the same @State feature.

It's fine really, but that's a different pattern.

Are you legitimately asking why a view has its own encapsulated layout rules?

No, it's more of an "explicit" vs "implicit".
It seems that they really focused on "doing as much as possible in as little code as possible", even if it hides some of the logic (in that case, the ltr vs rtl logic)

Flutter would ask you to use a Row.

Flutter uses and relies on plenty of "fancy language features" (read: language features that whoever the speaker is isn't used to and/or does not agree with). Just off the top of my head, constant constructors (and Dart's style of naming constructors in general), operator overloading, classes being implicit interfaces, @covariant, and mixins are features that would draw reactions from confusion to outright labeling as a code smell depending on a developer's background. I could probably come up with a longer list given an hour's thought. And that's not an indictment of Flutter any more than it's an indictment of SwiftUI - I don't see why one would think it's a virtue to write software in a particular language so that it could be written the same way in any language - what's the point of different languages if we're supposed to pretend like differences between them don't exist?

Besides, I completely disagree that either of setState or @State is explicit about its relationship with the act of rebuilding a view. In both cases you're simply told that if you change something that's been marked as state the framework will sort out what to build. In both cases the dev still has no explicit control over what's going on or when exactly. You find a function call more familiar, people who work in some other languages find decorators more familiar. But calling a function doesn't make things not magic.

Flutter would ask you to use a Row

I take it you've never used ListTile, which has the same behaviour shown here but with named parameters? Should we also ask why a Scaffold "magically" puts a menu button in the left of your appbar when you didn't ask it to?

The difference is that in the current state of Dart is very similar to most mainstream languages.

That's important.
The question "Do I need to learn Dart, or can I just start learning Flutter?" comes up quite often.
At the moment, the answer is "just learn Flutter. You can write effective dart after a single day".
That's not guaranteed to stay this way forever, but I do think that this is one of the strength of Flutter.

The rest of the discussion is a bit off-topic. If you want we can continue that part by mail (my github mail works).

Why is this not locked? This is already devolving badly, and it's exactly the same as a locked issue earlier.

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

Was this page helpful?
0 / 5 - 0 ratings