New issue

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

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

Already on GitHub? Sign in to your account

Consider JSX-like syntax inside dart code #11609

Closed
cbazza opened this Issue Aug 14, 2017 · 239 comments

Comments

Projects
None yet
@cbazza

cbazza commented Aug 14, 2017

It would be great if aside from the current way of building widgets you could add JSX like capabilities. I mean add tiny syntactic sugar to enable XML like constructs inside dart code. It just makes code so much easier to read/develop/debug/maintain and also easier for powerful GUI builders to integrate with editable code.

Looking for something like DSX:
https://spark-heroku-dsx.herokuapp.com/index.html

Carlos.


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.

@sethladd

This comment has been minimized.

Contributor

sethladd commented Aug 14, 2017

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 15, 2017

@cbazza Can you elaborate on why you want this? Maybe show an example of what it would look like compared to today?

@cbazza

This comment has been minimized.

cbazza commented Aug 15, 2017

Ok, so the "Basic widgets" example on 'https://flutter.io/widgets-intro/#basic-widgets' would look like the following:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  // Fields in a Widget subclass are always marked "final".

  final Widget title;

  @override
  Widget build(BuildContext context) {
    let style = {
        height: 56.0, // in logical pixels
        padding: const EdgeInsets.symmetric(horizontal: 8.0),
        decoration: <BoxDecoration color={Colors.blue[500]}/>,
    };
  
    return <Container style={style}>
      <Row>
        <IconButton
            icon={<Icon name={Icons.menu}/>}
            tooltip='Navigation menu'
            onPressed={null}
        />
        <Expanded>
           {title}
	</Expanded>  
        <IconButton
            icon={<Icon name={Icons.search}/>}
            tooltip='Search'
            onPressed={null}
        />
      </Row>
    </Container>;
  }
}

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Material is a conceptual piece of paper on which the UI appears.
    return <Material>
      <Column>
          <MyAppBar
             title={<Text 
               text='Example title'
               style={Theme.of(context).primaryTextTheme.title},
             />}
          />
          <Expanded>
            <Center>
              <Text text='Hello, world!'/>
            </Center>
          </Expanded>
      </Column>
    </Material>;
  }
}

void main() {
  runApp(<MaterialApp
    title='My app'
    home={<MyScaffold/>}
  />);
}
@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 15, 2017

How about this syntax?:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  // Fields in a Widget subclass are always marked "final".

  final Widget title;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 56.0, // in logical pixels
      padding: EdgeInsets.symmetric(horizontal: 8.0),
      decoration: BoxDecoration(color: Colors.blue[500]),
      child: Row(
        children: <Widget>[
          IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigation menu',
            onPressed: null,
          ),
          Expanded(
            child: title,
          ),
          IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: null,
          ),
        ],
      ),
    );
  }
}

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Material is a conceptual piece of paper on which the UI appears.
    return Material(
      child: Column(
        children: <Widget>[
          MyAppBar(
            title: Text(
              'Example title',
              style: Theme.of(context).primaryTextTheme.title,
            ),
          ),
          Expanded(
            child: Center(
              child: Text('Hello, world!'),
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    title: 'My app',
    home: MyScaffold(),
  ));
}
@cbazza

This comment has been minimized.

cbazza commented Aug 15, 2017

Huumm, a little improvement but not so good...
Here are the things that gets accomplished by using XML:
(1) No more 'child' & 'children' stuff
(2) easy for 3rd party tools to manipulate (parse, analyse and regenerate)
(3) notice that the switching between markup and programming is easily detected. I mean inside XML you have '{}' to delimit code and in code you have '<Capital' to delimit markup.
Also separate all the 'style' things from the main structure.
I know this is basically fully endorsing React's way but you are half way there anyways ;)

@sethladd

This comment has been minimized.

Contributor

sethladd commented Aug 15, 2017

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 15, 2017

(1) No more 'child' & 'children' stuff

I don't really understand why that's desireable. "child" and "children" aren't special. Consider ListTile for example. How would you do that one? Why are "icon" in IconButton, or "home" in MaterialApp, something you want to give a name for, but not "child" in Expanded? All three are just arbitrary arguments that happen to take Widget objects. There's nothing magical about "child" vs "home".

(2) easy for 3rd party tools to manipulate (parse, analyse and regenerate)

You can parse, analyze, and regenerate Dart code. But I agree we should make that easier. Hopefully in the coming years the Dart team will provide better APIs for this.

(3) notice that the switching between markup and programming is easily detected.

Why is that desireable? I mean, why would any of this count as "programming"? It's all just expressions.

I mean inside XML you have '{}' to delimit code and in code you have '<Capital' to delimit markup.

I don't really understand the distinction.

Also separate all the 'style' things from the main structure.

You can do this today in Flutter if you really want to, just put the style in a variable like you did in the XML case.

@cbazza

This comment has been minimized.

cbazza commented Aug 15, 2017

I don't really understand why that's desireable. "child" and "children" aren't special. Consider ListTile for example. How would you do that one? Why are "icon" in IconButton, or "home" in MaterialApp, something you want to give a name for, but not "child" in Expanded? All three are just arbitrary arguments that happen to take Widget objects. There's nothing magical about "child" vs "home".

Less boilerplate, you don't need to say it because it is inherited in the structure.

Why is that desireable? I mean, why would any of this count as "programming"? It's all just expressions.

It's related to (2) because it makes life of toolmakers, specially GUI builders, much easier since they don't need to fully parse Dart; but it also makes reading the code easier.

I don't really understand the distinction.

The format of XML is very simple so when you see '{}' you know it is calculating an expression in dart. Same for the opposite, when reading dart code and you see '<Capital' (a less-than followed by a word that is capitalized. example <Row>) you know that an object hierarchy is being created from XML markup.

@cbazza

This comment has been minimized.

cbazza commented Aug 15, 2017

Also in the final XML processor I would avoid passing objects to attributes of parents and instead create child tags as below:

this...
          <MyAppBar>
             <Title style={Theme.of(context).primaryTextTheme.title}>  
                 Example title
             </Title>
          </MyAppBar>

instead of this...
          <MyAppBar
             title={<Text 
               text='Example title'
               style={Theme.of(context).primaryTextTheme.title},
             />}
          />
@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 15, 2017

Less boilerplate, you don't need to say it because it is inherited in the structure.

But why only for some of the properties? And how do you handle cases where there's two child slots, like ListItem? XML-ish syntax just doesn't seem to handle this very well.

Also I'm not really sure it's less boilerplate.

Compare:

   <Container style={style}>
      <Row>
        <IconButton
            icon={<Icon name={Icons.menu}/>}
            tooltip='Navigation menu'
            onPressed={null}
        />
        <Expanded> {title} </Expanded>  
      </Row>
    </Container>
   Container(style: style,
      child: Row(
        children: [
          IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigation menu',
            onPressed: null,
          ),
          Expanded(child: title),
        ],
      ),
    )

It's not at all clear to me that the XML-ish syntax is cleaner or less boilerplatey. There's lots more punctuation, and some duplication of content (e.g. in the close tags). And you had to add some names, so sure, you lose "child", but you gain "name" on Icon.

Also with XML how do you make it clear that Row can take zero, one, or more than one child, while Center has to have exactly one child? What would happen if someone did this?:

   <Center> <Test/> <Test/> </Center>

It's related to (2) because it makes life of toolmakers, specially GUI builders, much easier since they don't need to fully parse Dart;

They wouldn't need to fully parse Dart if we had a Dart parsing API either, though, right? I mean, you'd parse what you want to parse and leave the rest. Also I'm not sure it's actually easier to parse, since it's not actually XML; see below.

but it also makes reading the code easier.

I'm not at all convinced that the XMLy version here is easier to read. Once you've read a few build functions, you quickly get used to the nested constructor syntax.

The format of XML is very simple so when you see '{}' you know it is calculating an expression in dart.

It's not actually XML, though, right? It's some variant of XML. Are there well-defined parsing rules for it? For example, is this valid?

  <Test name={describe("}")}>

How does it know that the first "}" isn't the end of the attribute expression, without parsing Dart?

Same for the opposite, when reading dart code and you see '<Capital' (a less-than followed by a word that is capitalized. example <Row>) you know that an object hierarchy is being created from XML markup.

You know this today when you see the new keyword too, right? Or indeed in the new-less markup proposal above when you see any capitalised word. Is this really a benefit of XML, or are you more familiar with XML than Dart?

Also in the final XML processor I would avoid passing objects to attributes of parents and instead create child tags as below:

I really don't understand what you're proposing here. It's not well-formed XML at all as far as I can tell. Can you elaborate on exactly what the syntax you are proposing is and how it works? For example, the "Text" constructor seems to have disappeared; how does the processor know that <Title> creates a Text widget?

Sorry if I sound defensive or aggressive. :-) This is a topic that's come up several times but I've never had someone willing to actually argue the case before so I'm finding this conversation very useful in teaching me what the reasoning behind the request is. Please don't take my argumentative tone as dismissive, I'm very interested in your input here.

@cbazza

This comment has been minimized.

cbazza commented Aug 16, 2017

Look, you are mixing everything I say and this conversation is going nowhere. In legal terms you are "Badgering the witness".

If you are really interested in learning why JSX is hot, just google for "react tutorial" and notice that for the past 2 years all articles on React use JSX. The original way of creating component hierarchies in React (which is equivalent to the current way in Flutter) is never mentioned again because JSX became the preferred method (best practice).

https://facebook.github.io/react/tutorial/tutorial.html
https://facebook.github.io/react-native/docs/flatlist.html

Another interesting thing is that Typescript has adopted JSX also:
https://www.typescriptlang.org/docs/handbook/jsx.html

You failed to grasp that XML parsing (with some extra code to skip '{}' properly) is orders of magnitude simpler than fully parsing a programming language like Dart. That is a fact. You are assuming that tool builders will use Dart on their development, not the case, Intellij most likely is using Kotlin and Java on their IDEs that supports Dart (they are a special case because they specialize in language parsing; everybody else will struggle to fully parse Dart from another language).

What I like about putting XML inside another language is that it provides a cognitive separation between the two because XML is very distinct from programming languages. Just scrolling through the source file you can easily see what is code and what is declarative markup. Can't accomplish that with dart code pretending to be markup.

Stop nit-picking things that are not fully specified. All your doubts have answered for it just learn more about how that was handled in JSX. I just don't have the time for this here.

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 16, 2017

My apologies if I sound defensive or aggressive. This is a topic that's come up several times but I'd never had someone willing to actually argue the case before so I was finding this conversation very useful in teaching me what the reasoning behind the request was. Please don't take my argumentative tone as dismissive, I'm very interested in your input here.

Please don't feel you have to reply. I'm commenting here so that there is transparency regarding the issues that we would have to resolve before we're able to make a decision or design one way or the other. This is basically just a Socratic dialogue. Your participation is welcome but certainly you should not feel that it is your responsibility to defend your proposal.


I've no doubt that JSX is "hot". In React, the non-JSX syntax is a lot worse than the alternative syntax proposed in this issue (the one that looks like our current code but without the "new" and "const" keywords). What I'm trying to understand is whether the same reasons that JSX is "hot" in React apply to Flutter.

Regarding TypeScript doing JSX, In 2012 I was involved in efforts to specify E4H, and even before that there was E4X. Both efforts died. So it's important to me that we understand what exactly it is people like about JSX vs other syntaxes.

Parsing XML isn't easy, parsing sort-of-XML-but-with-curly-braces-somehow is not easy either. Parsing sort-of-XML-but-with-curly-braces-somehow-that-is-embedded-in-another-language is even less easy. However, how easy that is to implement probably isn't a big deal because it's going to be implemented once or twice and then the library that does it will be reused. (I've been heavily involved in writing the specs for parsing HTML and been involved in similar work for XML, and I've implemented a parser for Dart, so I have a pretty good idea of how difficult parsing markup languages vs programming languages actually is.)

What I like about putting XML inside another language is that it provides a cognitive separation between the two because XML is very distinct from programming languages. Just scrolling through the source file you can easily see what is code and what is declarative markup. Can't accomplish that with dart code pretending to be markup.

But why is it beneficial to be able to do that?

It's pretty obvious when scrolling through Flutter apps where the build functions are (they're the giant nested expressions). What is it about "declarative markup" that is important to separate from "code"?

Stop nit-picking things that are not fully specified. All your doubts have answered for it just learn more about how that was handled in JSX. I just don't have the time for this here.

As far as I can tell, JSX doesn't handle the things I was asking about. For example, React doesn't have the concept of child slots. The closest thing I could find is something they do by switching back to JS then back to JSX inside that, so you'd need to be able to parse both the programming language and the markup language.

@cbazza

This comment has been minimized.

cbazza commented Aug 17, 2017

What I'm trying to understand is whether the same reasons that JSX is "hot" in React apply to Flutter.

Yes, the exact same thing applies here. The current way looks good to you because that's the only option you have. Give people a second option and the same will happen.

Whether E4X died or not is irrelevant because nothing lives forever. I have used ActionScript with E4X a lot and thought that Adobe did an excellent job there. In a way Flutter is just a newer version of Adobe Flash with Flex apps.

(I've been heavily involved in writing the specs for parsing HTML and been involved in similar work for XML, and I've implemented a parser for Dart, so I have a pretty good idea of how difficult parsing markup languages vs programming languages actually is.)

Great so you know that parsing a markup language is trivial compared to parsing an imperative programming language.

But why is it beneficial to be able to do that?

Code readability and simplicity which in turn drives a whole bunch of other benefits.

It's pretty obvious when scrolling through Flutter apps where the build functions are (they're the giant nested expressions). What is it about "declarative markup" that is important to separate from "code"?

On your giant nested expressions can you easily see structure? can this structure be easily manipulated by other tools like GUI builders interchangebly ? I mean like Adobe Flex Builder use to do, drag and drop widgets around, wire them on UI and then switch to code view and just edit anything you want and then switch back to gui mode and continue to manipulate the widgets. You can't do that easily when the programmer goes inside your "giant nested expressions" and writes any valid dart code that doesn't follow the structure that the GUI editor is expecting. With a fixed XML structure that is not a problem.

As far as I can tell, JSX doesn't handle the things I was asking about. For example, React doesn't have the concept of child slots

It handles it just fine, you just don't know how to do it. So going forward just put the example in question here and I will provide you with what I think the JSX version should be.

  new ListTile(
    title: new Text('CineArts at the Empire',
        style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
    subtitle: new Text('85 W Portal Ave'),
    leading: new Icon(
      Icons.theaters,
      color: Colors.blue[500],
    ),
  ),
  <ListTile>
    <title> 
      <Text style={{fontWeight: FontWeight.w500, fontSize: 20.0}}>
         CineArts at the Empire
      </Text>
    </title>
    <subtitle>
      <Text>85 W Portal Ave</Text>
    </subtitle>
    <leading>
      <Icon data={Icons.theaters} color={Colors.blue[500]}/>
    </leading>
  </ListTile>,

It looks longer than the dart version but I could had placed everything in the same number of lines. Thing is an IDE/Editor can provide '+' & '-' to expand and collapse these XML nodes anyways.

Make Flutter look familiar to React developers and you have a chance of attracting a bunch of new users to Flutter.

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 17, 2017

Whether E4X died or not is irrelevant because nothing lives forever.

Whether it died isn't the issue, it's why it died. Did it die because it didn't provide a solution that people wanted? Did it die because of implementation issues? Did it die because of patent issues? Was it too early? Too late? I think it's important to learn lessons from past experiences. Why did E4X and E4H fail where JSX has succeeded?

What I find interesting is that people who are new to Flutter often ask for two things: a markup language, and animated GIFs. Then three months in, they are still asking for animated GIFs, but not for a markup language. It could be that this is because the markup language isn't actually needed once you're used to writing build methods in Dart. It could be that they still want a markup language but have worked around the omission and so don't think to ask anymore. It's worth figuring out which because otherwise we risk spending effort on something that is the wrong choice (in either direction).

On your giant nested expressions can you easily see structure?

Yes, at least as easily as with XML. Personally, I find XML to be very verbose and it obfuscates the structure. But I think this is more about what you're used to.

(We're also experimenting with IDEs that put in virtual "closing tag" comments for you so you can see the structure without having to actually write it.)

Great so you know that parsing a markup language is trivial compared to parsing an imperative programming language.

My experience is that declarative vs imperative is not the distinction that matters when it comes to determining how easy a language is to parse. (For example, HTML is "declarative" but it may be among the most complicated languages to parse that I've ever dealt with.)

Code readability and simplicity which in turn drives a whole bunch of other benefits.

If this is the main benefit then this is something we can test. We could take a mixture of engineers who are used to writing HTML, React, iOS code, Android code, Flutter, command-line apps, and so on, and present them each with various syntaxes, and ask them to describe what they think the resulting UI would look like. We can then measure which syntax gets the best results. @InMatrix is this something we could look at after the animation work wraps up, maybe?

can this structure be easily manipulated by other tools like GUI builders interchangebly ?

Yes, in principle at least. It should be relatively straight-forward to mechanically convert Dart expressions to XML or JSON or whatever other structured language one might use. It's just a matter of converting the syntax, the actual information is the same. Personally I wouldn't convert it to a different syntax if I was making a GUI editor, I would just parse it into a data structure in memory straight from Dart.

You can't do that easily when the programmer goes inside your "giant nested expressions" and writes any valid dart code that doesn't follow the structure that the GUI editor is expecting. With a fixed XML structure that is not a problem.

The thing is, you can put exactly the same "any valid dart code" in the XML structure as in the Dart expression. They are literally mechanically interchangeable. So I don't really see how using XML helps with this particularly. For example how would you turn this into XML?:

new ListView.builder(
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0,
  itemBuilder: (BuildContext context, int index) {
    return new Text('entry $index');
  },
)

It handles it just fine, you just don't know how to do it.

I meant specifically JSX. I agree that your proposed syntax would be a perfectly valid way to approach the problem.

@HansMuller

This comment has been minimized.

Contributor

HansMuller commented Aug 17, 2017

I worked on Adobe's Flex SDK, which combined XML markup and ActionScript, for the last couple years that the product existed at Adobe. I understand the appeal of markup for defining UIs however I can also remember some drawbacks:

  • Flex application visuals could be defined in terms of markup and code. As I remember it, code tended to dominate in large real-world apps. Readability isn't necessarily a benefit for apps defined as a complex hybrids of markup and code.
  • The "Flex Builder" IDE had to support apps that were defined by markup and code. This made the IDE difficult to build and maintain. Developers tended to view it as an ActionScript tool.
  • Evolving and maintaining the XML "compiler" was a significant burden that kept a team of engineers busy full-time. Keeping the compiler and toolkit in lockstep slowed down the evolution of the overall sdk.

It's been years and I can no longer recall all the details. However my overall impression is that defining UIs with a combination of markup and code is a mixed bag at best.

@cbazza

This comment has been minimized.

cbazza commented Aug 17, 2017

Whether it died isn't the issue, it's why it died. Did it die because it didn't provide a solution that people wanted? Did it die because of implementation issues? Did it die because of patent issues? Was it too early? Too late? I think it's important to learn lessons from past experiences. Why did E4X and E4H fail where JSX has succeeded?

It died because E4X was only implemented in ActionScript which was only used inside Adobe Flash/Flex and Adobe killed the project. Instead Adobe changed direction towards open standards where there is no single source provider with possibility of lock-in and ecosystem implosion.

What I find interesting is that people who are new to Flutter often ask for two things: a markup language, and animated GIFs. Then three months in, they are still asking for animated GIFs, but not for a markup language. It could be that this is because the markup language isn't actually needed once you're used to writing build methods in Dart. It could be that they still want a markup language but have worked around the omission and so don't think to ask anymore. It's worth figuring out which because otherwise we risk spending effort on something that is the wrong choice (in either direction).

Well, if I asked you for 2 things and you didn't do either in 3 months and there is an alternative to the first thing, I would also only ask you for what is totally impossible to do given your responsiveness and previous delivery performance.

(We're also experimenting with IDEs that put in virtual "closing tag" comments for you so you can see the structure without having to actually write it.)

Kind of funny but it's like putting the XML closing tag that you mentioned before was too verbose.

If this is the main benefit then this is something we can test. We could take a mixture of engineers who are used to writing HTML, React, iOS code, Android code, Flutter, command-line apps, and so on, and present them each with various syntaxes, and ask them to describe what they think the resulting UI would look like. We can then measure which syntax gets the best results. @InMatrix is this something we could look at after the animation work wraps up, maybe?

Sure you can do that go ahead, I am sure you will find out that "Once you do React(with JSX) you simply don't go back". Survey experienced React developers and ask them if they think JSX is bad and it should never had been done. Show your way and ask them if they want to replace JSX with what you have. Before you do that, close the doors and lock up the place because these developers are just going to grab their stuff and sprint for the closest exit.

The thing is, you can put exactly the same "any valid dart code" in the XML structure as in the Dart expression.

Sure, but for the GUI builders that's just a block of bytes that doesn't need to be touched and can be easily skipped. Making it design/code interchangeability practically possible instead of in principle.

new ListView.builder(
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0,
  itemBuilder: (BuildContext context, int index) {
    return new Text('entry $index');
  },
)
let style = {
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0
};

<ListView.builder style={style}>
  {(context, index) => <Text> entry {index} </Text>}
</ListView.builder>
@cbazza

This comment has been minimized.

cbazza commented Aug 17, 2017

I used Adobe Flex Builder extensibly...

Developers tended to view it as an ActionScript tool.

Yes, but I often switched from design view to code view and vice-versa.
Starting a screen I would go to design view and use drag/drop to layout widgets and generate first static screen. Then I would add in code and some static data to fill in screen so I could show people something running that looked like production ready stuff. Productivity was incredible. As development progressed, I connected the front end to the back end and the amount of ActionScript code grew and yes it dominated the code overall but even at close to release time, I often used the design view to tweak the UI without having to dig into code.

However my overall impression is that defining UIs with a combination of markup and code is a mixed bag at best.

Not in today's world. Imperative languages have evolved in the philosophy of Python and are great for development. Declarative techniques with embedded markup (XML) became mainstream with the advent of React; and JSON became the preferred text based data format.

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 17, 2017

E4X was only implemented in ActionScript

E4X was an ECMA standard. Mozilla shipped it for a while, but then removed it (a very unusual move for a browser vendor). Other browser vendors never wanted to implement it. (They've implemented other new ECMA features, though.) With E4H, the browser vendors were never interested in implementing it (though again, they've implemented plenty of other things I've helped invent).

Well, if I asked you for 2 things and you didn't do either in 3 months and there is an alternative to the first thing, I would also only ask you for what is totally impossible to do given your responsiveness and previous delivery performance.

That's one possible theory. People tend to ask for many other things besides, though, and many of the things they ask for get implemented, and there are workarounds for animated GIFs too, so I'm not sure this fully explains the situation.

Kind of funny but it's like putting the XML closing tag that you mentioned before was too verbose.

Indeed. This is an optional IDE feature, and one that you don't have to write into the code, which makes a big difference to whether the verbosity is an issue, though.

...ListView...

How would a GUI editor handle this markup? I don't really understand how to visualise the UI for this.

@branflake2267

This comment has been minimized.

branflake2267 commented Aug 17, 2017

This may be a counter argument to this request, and/or maybe some insight's to keep in mind if you want markup. I have strong feelings that adding markup creating some challenges with GWT I'd hate to see another API go through.

I've seen a couple other frameworks go through this transition regarding with UI building. Markup like this works great for tooling, in so far it's heavenly for the IDE developers. It's easier to separate the responsibilities of who does what. Although I think it can be done better.

GWT started out this way, building UI's with Java. Then came along UiBinder, where you could build the UI in xml markup, with a specification. Then the tooling, Eclipse Plugin, was able to generate UI's in xml markup. Android is doing it too, no need to belabor the point. So what I saw happen, markup works great for UI IDE developers. But really, markup is a huge huge investment in time and added complexity tooling to transition it to real program. And the tooling is always last to come. So in the mean time, while all that manifests into reality, there are two worlds. Two interesting ways of doing everything. One in the default language and one in markup. So I support GWT today. When I write documentation, I have to write it twice, once for Java and once for UiBinder XML Markup. So the real question, if you want to go down the markup road, I think the question should be asked, is the added complexity worth the journey!

JSX I think aims to solve other issues where you want to blend together what your doing with HTML and javascript. It really doesn't feel like the added complexity of markup specification suits the needs of writing UI with markup. Especially when you don't really have a document markup language as the target. At least not for the everyday user.

On a positive note. I like to work on tooling. So I can see a markup language being quite useful. It's much easier to write and modify AST when your using markup.

But then again, if you have enough minds on the job, it doesn't really matter what you do. At the end of the day, if the developer can write his application faster with your api, your going to get traction. But at what cost to the engineering team.

I think the real question is, how can the UI be built faster. I think tooling could write the dart, skip any middle man markup. And my aim isn't really to say it's not worth it, but really count the cost's on all the fronts if the road is taken!

@cbazza

This comment has been minimized.

cbazza commented Aug 18, 2017

E4X was an ECMA standard. Mozilla shipped it for a while, but then removed it (a very unusual move for a browser vendor). Other browser vendors never wanted to implement it.

I would say only Adobe fully championed E4X and had a good following with developers. Browser vendors do add and remove stuff from their browsers all the time; didn't Google remove MathML support?

That's one possible theory. People tend to ask for many other things besides, though, and many of the things they ask for get implemented, and there are workarounds for animated GIFs too, so I'm not sure this fully explains the situation.

Here is the thing about React and JSX. Initially I completely dismissed it, I was in love with Angular and doing massive work with Ember. I tried desperately to convince the team to go with Angular but that didn't go anywhere as others had their eyes on Aurelia. Someone pointed me to React, I read the docs and evaluated and simply said that there was nothing in there that Angular or others couldn't do it. Then last year I worked on a new project and had the chance to try something new so I gave React a try and you really don't fully appreaciate what React brings to the table until you develop with it for awhile, then it becomes night and day against all other frameworks. It's a mixture of simplicity and expressiveness brought together by JSX.

How would a GUI editor handle this markup? I don't really understand how to visualise the UI for this.

let style = {
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0
};

<ListView.builder style={style}>
  {(context, index) => <Text> entry {index} </Text>}
</ListView.builder>

I would represent the <List.builder> as a rectangle and if its child/children where other widgets I would put rectangles for that inside it.
Since the child in this case is a function, you can simply put a rectangle saying 'uneditable/code' to tell users that this widget is created from code or in this case easily deduce that the function is a shallow wrapper to the widget and simply present that; I mean a rectangle that says that the function is a shallow function wrapper and inside it the List item widget rectangle (<Text> in this case).

@cbazza

This comment has been minimized.

cbazza commented Aug 18, 2017

But really, markup is a huge huge investment in time and added complexity tooling to transition it to real program.

All I am asking is to add these simple extensions on the Dart compiler so that if developers want to they can write using this XML structure. The old way would continue to work and the amount of work involved to do this is not huge at all. You can actually see how many lines of code it takes the babel.js compiler to do JSX and I am talking hundreds and not thousands of lines (I just checked it).

And the tooling is always last to come. So in the mean time, while all that manifests into reality, there's two worlds. Two interesting ways of doing everything. One in the default language and one in markup

Sure but React has been like this and that is not an issue at all.

When I write documentation, I have to write it twice, once for Java and once for UiBinder XML Markup.

Not in React because markup lives inside code.

is the added complexity worth the journey!

Absolutely, it's like the argument of whether you should train your developers with the latest techniques and risk them leaving your company. The bigger risk is keeping them around untrained. So you must adopt the latest techniques out there or risk being left behind.

React is leading the journey with the latest techniques to develop UI/UX. It has tremendous traction with developers. Your greatest risk is not meeting the React bar.

JSX I think aims to solve other issues where you want to blend together what your doing with HTML and javascript

JSX is not just for HTML, React Native generates Views (like Flutter Widgets) from the XML markup.

I think the real question is, how can the UI be built faster.

More like how UI/UX can be built better. Better meaning: faster, higher quality (code and UI/UX), smooth designer-developer interaction, etc.

By the way, really nice job done on the developer tools; 'flutter doctor' was awesome !!!
I am now cooking with gas and can be dangerously creative ;)

@InMatrix

This comment has been minimized.

InMatrix commented Aug 21, 2017

I just wanted to respond to the readability question raised here, though I understand readability is only one of the many factors we need to consider.

Code readability and simplicity which in turn drives a whole bunch of other benefits.

If this is the main benefit then this is something we can test. We could take a mixture of engineers who are used to writing HTML, React, iOS code, Android code, Flutter, command-line apps, and so on, and present them each with various syntaxes, and ask them to describe what they think the resulting UI would look like. We can then measure which syntax gets the best results. @InMatrix is this something we could look at after the animation work wraps up, maybe?

There are certainly ways to empirically study code readability, and we can have a more serious discussion when it's time for Q4 planning. To make such a study useful, we need to define what kinds of reading tasks are important to developers in the context of Flutter programming. In addition to reading a whole build method and picture what the resulting UI might be, readability also affects smaller tasks such as identifying the build method in a dart file, matching braces, reading inline comments, etc.

To support some of those more narrowly-scoped tasks, we can experiment with UI enhancements in the editor first, which is usually cheaper than introducing and maintaining a markup language. The closing label feature in VS code is one of such UI enhancements, and we should understand how well it solves the brace matching problem it sets out to address. There are plenty of other options in this space we haven't tried yet. For example, a different font or background color might be used to display the build method to help the developer mentally separate it from the rest of their code.

Another thing that strikes me as important is how we can encourage people to not write giant build method and take advantage of the composition nature of the framework. If the build method is taller than the height of your screen, it's going to be hard to read regardless it's Dart or XML.

@cbazza

This comment has been minimized.

cbazza commented Aug 21, 2017

Another thing that strikes me as important is how we can encourage people to not write giant build method and take advantage of the composition nature of the framework. If the build method is taller than the height of your screen, it's going to be hard to read regardless it's Dart or XML.

It's not just the build method. It's all other methods that the build method calls to build the widget tree. Very common in React to use smaller methods to build sub-tree pieces and then call those into the larger tree.

Also in WebStorm with JSX, each XML node has +/- that can be used to expand/collapse node and children to make reading structures larger than the height of the screen easier.

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 21, 2017

One thing we've found in Flutter is that big build methods are not great for performance, and we try to encourage people to break down their build methods into smaller reusable widgets. In particular, in Flutter having a build method that's built out of the results of other methods is somewhat of an antipattern that we'd rather discourage rather than make easier. (This is somewhat of a recent realisation so a lot of our examples and widgets don't do this well yet.)

@cbazza

This comment has been minimized.

cbazza commented Aug 21, 2017

we try to encourage people to break down their build methods into smaller reusable widgets.

Does it really become a reusable widget or simply a wrapper/composite widget? I mean to be reusable you should have at least 2 usage instances.

The AppBar on https://flutter.io/catalog/samples/basic-app-bar/ is so unique that you can't really call it an reusable component; it's a wrapper/composite component and in these cases why not just use a local method to build that part of the UI? I guess if it did more things it would make sense to place it in a wrapper/composite component.

One thing we've found in Flutter is that big build methods are not great for performance

Since you mentioned performance, having the animation loop drive the build method will cause performance problems for smooth animation. You don't want your build method called 60 times a second or more, specially considering that the build method is user code (for example, it could have a super long loop that takes forever and it would cause animations to skip). Being a Flutter beginner perhaps I got that wrong.

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 21, 2017

The AppBar on https://flutter.io/catalog/samples/basic-app-bar/ is so unique that you can't really call it an reusable component

It's also relatively small, so that's ok.

Regarding performance, this is somewhat off-topic for this issue so please file a new issue if you want to discuss it (or e-mail flutter-dev or post on stack overflow, whatever you prefer).

@nsuper

This comment has been minimized.

@birkir

This comment has been minimized.

birkir commented Dec 11, 2017

It's crazy to see this issue getting buried. In my opinion it's going to be a make or break for Flutter to implement JSX-like syntax for composing widgets.

I simply don't understand the target audience, many ios and android devs are moving to react native, it would seem to be the perfect opportunity to harvest market share.

I encourage people involved to give react native a spin and see what we are talking about.

@zoechi

This comment has been minimized.

Contributor

zoechi commented Dec 11, 2017

I don't miss JSX a bit in Flutter. This would only bloat the framework and tools for a few small gains here and there.

@cbazza

This comment has been minimized.

cbazza commented Dec 11, 2017

@birkir I am 100% with you on this issue. Lack of JSX, which is a perfect fit for Flutter, makes Flutter look old and rusty, feels like 1990s technology. Actually it seems like everyone, in one way or another, is adopting JSX; the latest one being the popular Vue.js framework.

@cbazza

This comment has been minimized.

cbazza commented Jul 24, 2018

@andrewackerman

Sorry dude I don't have the time to argue endlessly and repeat what I said before over and over; we won't end up in agreement anyways so best of luck with your FLUI.

You've waxed eloquently about what it can and will be able to do, but all we've actually seen is a small handful of purpose-built code snippets and your word that they were generated by the transpiler.

The online DSX transpiler has been live since Feb 2018 and anybody can use it so there is no need to take my word for anything. Press 'Compile' and it compiles what its written on the left panel and places results on right panel. Open debugger and you will see the AST written out.
https://spark-heroku-dsx.herokuapp.com/index.html

The problem is that, where JSX was built on a weakly-typed dynamic language like JavaScript, DSX is being built on a strongly-typed static language like Dart.

It makes no major difference at all, like the OOP (Object Oriented Programming) concept and syntax for 'classes'. It's almost identical in typeless Javascript or typed Dart; same can be said for 'if' statement, 'for' statement, etc

it still needs to bring something to the table that is going to convince people to use it.

Apparently it already does for 100 people in this ticket; and that's 100 times larger than just me using it; good enough for me.

@andrewackerman

This comment has been minimized.

andrewackerman commented Jul 24, 2018

@cbazza

Sorry dude I don't have the time to argue endlessly and repeat what I said before over and over; we won't end up in agreement anyways so best of luck with your FLUI.

I'm not arguing with you just for the sake of argument or because of some deep-seated anti-JSX bias. I'm trying to get you to answer questions that need to be answered. You are developing a tool that you presumably intend for other people to use, yet you still haven't offered a compelling reason why they should use it beyond the vague and subjective benefits of "familiarity" and "because it's better". The former, as I said before, is not necessarily a good thing, and the latter is as of yet a claim made without any tangible support.

If you want your tool to be a success, it needs to be set in stone what you are doing and why you are doing it, and you need to do so in a way that it can be easily conveyed to others. That's not to say that you can't make a product until it is liked by everyone, but clear and concise objectives are crucial to shaping design and implementation. Otherwise you are just going to end up with a direction-less utility that will be a niche product at best and will be extremely lucky if it ends up in production code of any scale.

The online DSX transpiler has been live since Feb 2018 and anybody can use it so there is no need to take my word for anything. Press 'Compile' and it compiles what its written on the left panel and places results on right panel. Open debugger and you will see the AST written out.

I didn't even see that that link was a working example. I've never used herokuapp before and it just looked like a gist or something, so that's on me. :P

(Though I will point out that tinkering with an online sandbox is not the same as testing the transpiler in a more practical environment.)

It makes no major difference at all, like the OOP (Object Oriented Programming) concept and syntax for 'classes'. It's almost identical in typeless Javascript or typed Dart; same can be said for 'if' statement, 'for' statement, etc

You already had to deal with one such difference in child strong-typing. What about attribute strong-typing? What about widgets in different libraries with the same name? What happens if someone makes a widget with more than one nameless positional argument? What happens if we import two libraries that have widgets with the same name? What happens in some scenario that I haven't thought of pops up to further showcase the inherent difference between systems like Javascript and Dart? I have to say, you being so flippant on this discussion point makes me worry about DSX's longevity in a real-world setting.

Apparently it already does for 100 people in this ticket; and that's 100 times larger than just me using it; good enough for me.

Again, that's 100 people who upvoted the issue on the basis of "Consider JSX-like syntax inside dart code". They upvoted because they want JSX, and as you've been so keen to point out, DSX is not JSX. So why else would they want to use DSX? Because inline XML-like UI declaration is "the future"? Again, I just don't see it.

We've already covered JSX in Vue not getting any traction, but there's also the two React alternatives mentioned in the Web Components article you linked: Inferno and Preact. As far as I can tell, they have both failed to make any kind of waves at all in the JS-based web-app development world, despite also natively supporting JSX-like syntax. I really think that people need to have a long and hard look about exactly why people like JSX in React, because by all accounts it just doesn't seem to be because of JSX itself. If that question can be answered, then we can move forward toward "future" innovations rather than just frankensteining that one feature from that one library we liked into everywhere else we personally think it should be.

@escamoteur

This comment has been minimized.

Contributor

escamoteur commented Jul 24, 2018

Thinking on the amount of energy that was invested just in this discussion and what could have been done good to improve the current framework instead makes me sad.

@Bessonov

This comment has been minimized.

Bessonov commented Jul 24, 2018

@andrewackerman

The problem is that, where JSX was built on a weakly-typed dynamic language like JavaScript, DSX is being built on a strongly-typed static language like Dart.

Sorry, but this isn't a problem. Furthermore, this doesn't make any sense at all. Beside of that, we use JSX with TypeScript.

@escamoteur absolutely!

@jogboms

This comment has been minimized.

jogboms commented Jul 24, 2018

@escamoteur I'm with you on this one. The 100.

@andrewackerman

This comment has been minimized.

andrewackerman commented Jul 24, 2018

@Bessonov

Sorry, but this isn't a problem. Furthermore, this doesn't make any sense at all. Beside of that, we use JSX with TypeScript.

React wasn't designed for TypeScript. It was designed for Javascript. All the widget definitions, attributes, properties, and everything else was designed to be used in the dynamic environment of JavaScript, so the type safety of TypeScript doesn't introduce any new factors with how JSX interacts with React. This is yet another example of how JSX was designed for a completely different setting than what Flutter is.

@Bessonov

This comment has been minimized.

Bessonov commented Jul 24, 2018

@andrewackerman
Why do you think it does matter? JSX is a way to describe interface. It's language agnostic on it's own. Look here. It's not JavaScript. But well, why it can't be done with JSX? (Beside there is no implementation of this (yet))

And.. you know... flow come from fb too:

Flow is a static typechecker for JavaScript.

Please, stop selling arguments for and against extensions you've never use. I use JSX every day and I'm happy with it ATM, although I was very skeptical about it. I can imagine, that JSX evolves in other patterns, like it was with AngularJS.

And maybe this topic helps to find better pattern for Dart? DSX is just one proposal. Look at builder pattern example above or other language tweaks presented here. And, well, maybe your flui is a better way? I don't know. But let's find it out and help to each other to improve their suggestions instead of discussing about bad things in someones else proposal.

@Bessonov

This comment has been minimized.

Bessonov commented Jul 24, 2018

I would like to propose close this topic and open new umbrella topic with limited conversation. All proposals to improve the way, how flutter may be used, discuss in own topics objectively with love and without hate.

@cbazza

This comment has been minimized.

cbazza commented Jul 24, 2018

Yeap, the amount of hate here is epic, just consider this:
There are 3587 open tickets, if you sort them by "thumbs down" you get
1 (this one) with 57 "thumbs down"
3586 (other tickets) with 1 or less "thumbs down"

@andrewackerman

This comment has been minimized.

andrewackerman commented Jul 24, 2018

@Bessonov

Why do you think it does matter? JSX is a way to describe interface. It's language agnostic on it's own. Look here. It's not JavaScript. But well, why it can't be done with JSX? (Beside there is no implementation of this (yet))

It's a way to describe UI in Javascript (hence the "JS" part of the name). And no, since it's an inlined DSL, it is not language-agnostic. And even if it was, that still doesn't make it the "better choice", since there are plenty of truly language-agnostic DSLs out there that would be woefully inadequate for UI declarations.

And.. you know... flow come from fb too:

Flow is just like TypeScript: a static type checking system for Javascript. It is not a React tool, nor was React designed to be used with it. React is first and foremost a Javascript library, and JSX was designed to be used with React. Whatever secondary tools and utilities get introduced into React development are ultimately irrelevant to React+JSX interoperability.

Please, stop selling arguments for and against extensions you've never use. I use JSX every day and I'm happy with it ATM, although I was very skeptical about it. I can imagine, that JSX evolves in other patterns, like it was with AngularJS.

I have used JSX, and though I do have personal opinions of it, I have deliberately left those opinions out of this discussion. In fact, had you read my previous comments, you would know that I had praised JSX for revolutionizing UI development in React. Other than some mildly tangential comments I've made about the market penetration of JSX as a whole, my arguments have been specifically about JSX in Flutter. And on that topic, there is no practical basis to determine the efficacy of DSX, so all we can do is examine how JSX has been implemented in other places, and that examination does not bode overly well.

Unless, of course, you've been using DSX every day as well and can enlighten us on the practical advantages of using DSX in Flutter?

And maybe this topic helps to find better pattern for Dart? DSX is just one proposal. Look at builder pattern example above or other language tweaks presented here. And, well, maybe your flui is a better way? I don't know. But let's find it out and help to each other to improve their suggestions instead of discussing about bad things in someones else proposal.

That is what I'm doing. DSX is being proposed as a UI solution for people familiar with JSX. There are key design elements in JSX that were intended to be used for an environment completely different from Dart and Flutter. Those differences need to be addressed for DSX to be successful. I am not being a hater. I'm trying to promote constructive discussion and ask the important questions. Yet all the responses I've been getting has amounted to subjective tautology ("JSX is good because it's the future, and it's the future because it's good"), dismissive hand-waving of crucial design points ("DSX does not need to account for differences between JS and Dart because there aren't any"), or just plain hostile ("You obviously don't like JSX so stop talking about DSX").

You do not make a successful product solely with unadulterated praise. It needs to stand up to and account for criticism as well. People showing up and saying "OMG yes please, make DSX", while uplifting, is not helpful. There have been several people throughout this thread that have brought up perfectly valid criticisms of DSX, both with its initial design and with the concept as a whole. And for the most part, many of these criticisms have yet to be directly addressed, with the general attitude being dismissive.

My only fear is that all this unconditional love for JSX is preventing people from viewing DSX objectively. I get why you guys want something like JSX in Flutter, and I can relate - my opinion that Flutter needs a dedicated UI DSL is what lead me to create flui. But if the only people allowed to talk about DSX are the people who have nothing but good things to say about it, then it will fail.

@rrousselGit

This comment has been minimized.

rrousselGit commented Jul 24, 2018

Can we recenter the discussion on this topic?
In fact, I don't see any reason to keep this issue open.

Dart team stated that they have other priorities. And the pro JSX side volunteered to make their own DSX implementation

Maybe we should just have a few open source repository proposing different solutions (even barely working). Such as DSX, or templates.
And then consider redirecting from Flutter's readme or awesome_flutter to these repos. And if there's anything blocking a DSX implementation, create another issue with the specifics.

Then let the community do its job.

@cbazza

This comment has been minimized.

cbazza commented Jul 24, 2018

Leave it opened as is because people will continue to open new tickets asking for JSX (as it has already happened twice before).

@rrousselGit

This comment has been minimized.

rrousselGit commented Jul 24, 2018

Leave it open as is because people will continue to open new tickets asking for JSX (as it has already happened twice before).

The difference here is that we would now be able to answer with the following :

"We don't plan on implementing this in dart/flutter for now. But you can take a look at community alternatives [here] and [there] or read [this issue]"

and close the issue as duplicate.

@cbazza

This comment has been minimized.

cbazza commented Jul 24, 2018

One place for comments and votes and it is here. The request for JSX-like functionality is not going away and the ticket is opened because it needs Flutter tools support (compiler & VS Code IDE) and I have updated the ticket request with this info (first comment). If an enormous number of people starts asking for this, it will give the Flutter team incentive to put resources into it.

@pulyaevskiy

This comment has been minimized.

Contributor

pulyaevskiy commented Jul 25, 2018

Looks like most of the controversy here is not around JSX at this point, but DSX. I'd suggest splitting DSX discussion into it's own thread and leave this one generic to JSX.

In the end DSX is just one way of getting something closer to JSX so we shouldn't be mixing these two discussions in one thread regardless.

@viniciusgati

This comment has been minimized.

viniciusgati commented Jul 25, 2018

Big no for this, i really think that 1 language only is a big gain, jsx syntax will come with more things like separation of xml from js, etc... Not good.

thats my opinion.

@andreyluiz

This comment has been minimized.

andreyluiz commented Jul 26, 2018

That's the longest and pointless Github issue I ever seen.

@BarryYan

This comment has been minimized.

BarryYan commented Jul 31, 2018

@cbazza Good job 👍
DSX + 1

@cbazza

This comment has been minimized.

cbazza commented Jul 31, 2018

@BarryYan, Thank you

@rrousselGit

This comment has been minimized.

rrousselGit commented Jul 31, 2018

Please avoid this kind of comment, be it "+1" or "Thanks".
This sends an email to all subscribers for nothing interesting.

@cbazza

This comment has been minimized.

cbazza commented Jul 31, 2018

Please avoid this kind of comment, be it "+1" or "Thanks".
This sends an email to all subscribers for nothing interesting.

Nothing interesting to you !!!
Please avoid telling people what they can say or do and focus only on what you can say or do.

@andrewackerman

This comment has been minimized.

andrewackerman commented Jul 31, 2018

@cbazza

Dude, it's basic etiquette. Any new message on this thread emails everyone subscribed to it, so it's rude to post comment that doesn't contribute to the discussion because it annoys people for no reason. Basic reactions like "+1" and "Thanks" can be conveyed with a simple thumbs up reaction, so just do that.

That being said, if this thread has really devolved into arguing over whether someone should or shouldn't post a "+1" message, that's a big red flag that all constructive discussion has officially died, and it really should be closed (perhaps permanently this time).

@cbazza

This comment has been minimized.

cbazza commented Jul 31, 2018

@andrewackerman,

Got it but while you are at it perhaps you should also consider basic etiquette while blasting this thread with your novels (long & fictional writing).

Please stop spreading FUD (fear uncertainty & doubt) with your spray-and-pray barrage of senseless questions (you know, throw as much crap on the wall and see if anything sticks) and demands.

After all your writings you haven't added any value to DSX so I have no interest having a discussion with you on this subject. Your motive is obvious though, promote FLUI while blasting DSX.

Tell me something, do you have answers to your own questions when they are applied to FLUI? Let's discuss FLUI for a bit shall we?

@andrewackerman

This comment has been minimized.

andrewackerman commented Jul 31, 2018

@cbazza

Got it but while you are at it perhaps you should also consider basic etiquette while blasting this thread with your novels (long & fictional writing).

The fact that you refer to my responses that I put a lot of time and effort into being as well-thought-out and unbiased as I can make them as "long & fictional writing" illustrates a lot about your character and how you are approaching this discussion. I'm trying to promote discussion regarding very real issues surrounding any implementation of JSX in Flutter, while you lambast anyone with any form of contrary opinion. Which of us is the bigger offender of basic etiquette?

Please stop spreading FUD (fear uncertainty & doubt) with your spray-and-pray barrage of senseless questions (you know, throw as much crap on the wall and see if anything sticks) and demands.

The only thing I am "demanding" is that you address the numerous issues brought up by many people regarding DSX with more than either a hand-wave or open hostility. For someone who is proposing a significant change/addition to Flutter's feature set, I feel like that's not an unreasonable expectation.

After all your writings you haven't added any value to DSX so I have no interest having a discussion with you on this subject. Your motive is obvious though, promote FLUI while blasting DSX.

I'm asking you to defend your position. You've repeatedly said that JSX/DSX is the best/future, but have yet to explain how or why. Several people have expressed valid concerns about DSX, but instead of addressing them, you wave it off by hiding behind the counterargument "if you don't like it, don't use it". My "motive" is to get you to answer questions that need to be asked regarding any technical project, first and foremost being why people should ever use it over the alternatives. (And as I have explained before, familiarity is not a good enough reason.)

As far as FLUI is concerned, all I am doing is proposing an alternative solution to the overall problem (UI declarative syntax for Flutter) while requesting that people do the same to it that I am doing to DSX - offer sincere and constructive criticism. I am not saying that FLUI is objectively better than DSX - I'm proposing an alternative formed from a different approach to UI development and asking people to form their own opinions.

(I'd also like to point out that, other than my initial mention where I was proposing a possible alternative approach to GUI representation, the only times I've ever even talked about FLUI is when you brought it up. So how does it makes sense that my ulterior motive is to promote it when you are talking about it more than I am?)

Tell me something, do you have answers to your own questions when they are applied to FLUI? Let's discuss FLUI for a bit shall we?

FLUI is not DSX - it doesn't have to answer every question that I posed to you regarding DSX because many of them are specific to DSX's design. That's not to say that it doesn't have its own set of questions that need to be answered, though, and no, I don't have all those answers. That's why I value critical discussion - FLUI/DSX aren't going to stand up to the court of public opinion unless they can survive getting raked across the coals a couple times. This is not the appropriate place to discuss FLUI though. If you want to discuss FLUI at length, the project has its own issue board, so feel free to post there.

Instead of responding to criticism, you've instead been defensive and evasive, so much so that you are directly responsible for the two separate occasions (approaching three) where this thread had to be temporarily closed due to things getting too heated. So I'm going to break from "etiquette" and say this once: shelf your ego, stop interpreting criticisms as personal attacks, and answer the important questions. Either that, or make peace with DSX never getting off the ground.

@jstansbe

This comment has been minimized.

jstansbe commented Jul 31, 2018

andrewackerman Good job 👍
+ 1

@cbazza

This comment has been minimized.

cbazza commented Aug 1, 2018

@andrewackerman

Good job

Dude, you get a compliment from @jstansbe which conveys a lot more information than a thumb up and you thumb down on the compliment?

Obviously you didn't take my hint on length to heart but don't come to conclusions about my character because you don't know me at all.

The fact that you refer to my responses that I put a lot of time and effort into being as well-thought-out and unbiased as I can make them

That I appreciate and I read all your 'long writings', answering everything: no way, but when I answer properly you don't understand my answer and concludes that I am being dismissive.

It is obvious to me that you are not very experienced with JSX, you really don't understand how it works. So instead of doubling down just own it and I'll explain it in more detail. For example JSX & DSX only does the following 2 transforms (mentioned several times before):

(1)
<A property="a" />
    becomes
new A(property: a)

(2)
<A property="a">
  <B />
  <C />
</A>
    becomes
new A(property: a, children: <Widget>[new B(), new C()])

Everything else is handled by the host language, so for example: how does it handle import of components named the same; answer: host language. I am not being dismissive, it is the way it is designed and the source of it's strength. You see if you separate markup and programming into separate files, you start to duplicate the programming inside the markup with simple constructs for 'if', etc. You end up building a declarative programming language inside the markup that can never be as powerful as the main programming language. So by bringing the markup into the programming language you have the best of both worlds and that's the power of JSX/DSX.

Notice above on (2) that the transform hardcoded <Widget> and that's not always the case, so now you can specify that if needed as discussed before. Look at the transforms and now all symbols come from source or can be specified so there won't be some major magic gotchas in the future.

while you lambast anyone with any form of contrary opinion.

That's not true, you can have contrary opinion but you can't claim something true when I can proof otherwise.

For someone who is proposing a significant change/addition to Flutter's feature set, I feel like that's not an unreasonable expectation.

But that's the thing, I wanted the Flutter team to implement DSX but then I did it so what they need to implement is generic stuff that doesn't depend on DSX and DSX is not the only beneficiary. The browser js engine supports source maps which enabled an ecosystem of new languages in the browser that transpiled to js; it enabled the creation of Dart !!! and several others (Coffeescript, Typescript, Reason, etc). Dart could do the same now and benefit from the ecosystem that it helps bring up, all boats rise.

I'm asking you to defend your position.

I've already done it many times and the conclusion is that Plain Dart or DSX comes down to user preference; and the important thing is to provide option instead of forcing people one way.

first and foremost being why people should ever use it over the alternatives.

I would use DSX because I prefer it, like spaces or tabs, type definition before or after the variable name. There is no point fighting for it, just accept that people have different preferences; there is more than 1 programming editor out there right?

familiarity is not a good enough reason

Just your opinion, why do we use "if" statements in almost every language, 'for' statement, 'class', and now 'asyn/await'.

This is not the appropriate place to discuss FLUI though. If you want to discuss FLUI at length, the project has its own issue board, so feel free to post there.

Very good, now you gained my respect.

you are directly responsible for the two separate occasions (approaching three) where this thread had to be temporarily closed due to things getting too heated.

Thing is even if it gets closed again it won't stop people from asking for JSX-like capabilities.

shelf your ego, stop interpreting criticisms as personal attacks, and answer the important questions.

I have no ego but I do have short temper so there is no mistaking when someone pisses me off (it comes out right away). Not to offend you but your questions were not important.

Either that, or make peace with DSX never getting off the ground.

You are not the meter used to measure success and you don't know what I am up to.

@andrewackerman

This comment has been minimized.

andrewackerman commented Aug 1, 2018

Dude, you get a compliment from @jstansbe which conveys a lot more information than a thumb up and you thumb down on the compliment?

You apparently didn't pick up on the sarcasm inherent in his comment. (He literally did everything I said not to do.) While a fun bit of trolling that I can appreciate, it's not appropriate here. And if, by chance, he was being sincere, then I apologize for my snideness, but my point still stands - that kind of comment is still not appropriate here.

It is obvious to me that you are not very experienced with JSX...

Did my disclaimer in my very first comment on this thread perhaps tip you off?

...you really don't understand how it works.

You equate me not having much experience with JSX and me not knowing how it works at all? While I've never worked on any serious React project, I've done my fair share of tinkering. I understand perfectly well how it works.

Everything else is handled by the host language, so for example: how does it handle import of components named the same; answer: host language.

And that makes sense in the case where the markup language and the host language are distinct. With JSX, the markup language is designed as an extension of the host language. As such, JSX was designed as an extension of JS, and that's why it works as well as it does. DSX is an implementation of JSX for Dart.

You don't see the problem there? A markup language designed as an extension of one language being jerry-rigged into a foundationally different language. It is inevitable for there to be a load of issues, edge cases, and considerations.

You see if you separate markup and programming into separate files, you start to duplicate the programming inside the markup with simple constructs for 'if', etc. You end up building a declarative programming language inside the markup that can never be as powerful as the main programming language.

First, the whole idea behind separating markup and programming is that, if you are doing it correctly, there is a clear separation between the two which results in no duplication.

Secondly, if you are doing anything much more complex than ifs and fors in your UI code (which are constructs that can easily be handled in many markup solutions), then I would argue that it's a sign there is something wrong in your design anyway. As per MVC/MVVM design principles, if you are incorporating complex logic in your UI constructs, that's a potential sign of smelly code and you should seriously consider a redesign anyway.

(That's not to say that you can't write declarative UI in the MVVM fashion using JSX, but it's just something that invites trouble for little objective gain. Why use something in which you can write code that is standards-compliant when you can use something that makes it difficult to write code that isn't?)

That's not true, you can have contrary opinion but you can't claim something true when I can proof otherwise.

You haven't "proved" anything. You've given a bunch of subjective claims that have yet to be backed up with any substantiating logic. (Though to your credit, this latest post is a big improvement.)

But that's the thing, I wanted the Flutter team to implement DSX but then I did it so what they need to implement is generic stuff that doesn't depend on DSX and DSX is not the only beneficiary.

You are still asking for them to do non-trivial stuff, so the onus is on you to convince them and the rest of us why they should and why it's so important that they should push down other things on their to-do list.

The browser js engine supports source maps which enabled an ecosystem of new languages in the browser that transpiled to js; it enabled the creation of Dart !!!

It is in the nature of JS itself that such a thing is easily doable (relatively speaking), so much so that Dart is far from the only language that has a transpiler to JS. As I have pointed out many times, Dart is not JS. It is static and strongly typed, meaning a lot of things that would be easy to do in JS are hugely complex in Dart.

I would use DSX because I prefer it, like spaces or tabs, type definition before or after the variable name. There is no point fighting for it, just accept that people have different preferences; there is more than 1 programming editor out there right?

By that logic, I should make a UI solution in which you define constructs using hex-encoded braille. I mean, if all that really matters is personal preference, all I need to say to defend its existence is that "some people prefer it", right?

You are developing a tool that you intend for other people to use, so you need reasoning beyond "some people might like it" to make yourself convincing. If you can't put it into words why they should use it over something else, then what makes you believe that they will? And what's there to incentivize you to ensure that they will when designing DSX's feature set?

Just your opinion, why do we use "if" statements in almost every language, 'for' statement, 'class', and now 'async/await'.

First, those keywords (aside from async/await) became common programming lexicon because of the immense popularity of languages like C and BASIC over the course of several decades. As I've mentioned before, JSX is far from proven in its longevity - it's been around for 5 years and is yet to see any significant use outside of React despite the option being available.

Second, there's a big difference between familiarity and convention. if, while, for, struct, class, enum, try/catch/finally, async/await... those are all great ways to verbally represent a concept. There are reasons to defend using those keywords beyond them just being what people are familiar with - they make conceptual sense. (Of course, that doesn't mean that they are constants. Some languages do if ... then. Some do if ... elif while others do if ... else if and still others do if...endif. Some do foreach, others do from. And so on, and so forth.)

Meanwhile, the argument to use JSX because it is "familiar" doesn't fit the same category. JSX is one way to represent declarative UI, but it is neither the only one nor the most popular one. Furthermore, it was designed to be used in one type of environment, so using it in another environment can turn familiarity into a bad thing - familiarity leads them to expect it to work more or less exactly the same way it works elsewhere, so if it doesn't then that leads to a mental disconnect which is something that you want to avoid.

Thing is even if it gets closed again it won't stop people from asking for JSX-like capabilities.

They ask for it anyway, and the issue gets redirected here all the same. I don't see how the thread being closed would change that.

You are not the meter used to measure success and you don't know what I am up to.

Read any book about product design. Chapter one is always about creating a statement, a manifesto, a slogan, anything tangible and expressible in plain English that describes what the product is and why people should care about it. There's a reason that the most common form of advice given to amateur entrepreneurs is to make an "elevator pitch", something that clearly and concisely communicates the product and the draw in 30 seconds or less. If you can't put it succinctly why people should use your product, it's a sign that it's suffering from an identity crisis. If the person designing the product can't adequately respond to criticism, then that gives the impression of a lack of faith in their own product. Both of those things are big red flags to investors.

In this situation, the product is DSX, and the investors are developers considering using it. The only people you have backing you are people who apparently would unconditionally cheer on anything with "JSX" in the description. Every other person in this thread I have seen question what you are doing has walked away seemingly unconvinced following your answer.

You are currently sitting at or near a 0% conversion rate, and that's where I'm coming from when I say that you have yet to adequately respond to criticism. Maybe you don't care, but if you seriously intend for DSX to be a UI declaration markup plugin usable and used in real-world projects, you might want to start.

But then again, maybe you are an exception.

@Hixie

This comment has been minimized.

Contributor

Hixie commented Aug 1, 2018

Ok this conversation has gone well beyond the kinds of discussions that we consider acceptable in the Flutter community, and so I'm going to lock this thread and close the bug. Please consider reading https://flutter.io/design-principles/#conflict-resolution for more details on how we behave here.

The next step if anyone wants to contribute code to address this issue would be to come up with a design for how to do build system integration such that we can have code generation work with Gradle, Xcode, hot reload, and integration with existing apps. If anyone is interested in working on this, please don't hesitate to reach out to me. Otherwise I expect this is something we'll work on early next year. Once we have a mechanism to do that, solutions like DSX will be easy to integrate into the Flutter ecosystem. We may even find solutions that should be integrated by default. In the meantime we're also working on improvements to Dart's syntax to see if we can make UI expressions even easier to write.

I would like to ask that people do not open new bugs on this topic unless there is something very constructive and new that is worth bringing up.

@Hixie Hixie closed this Aug 1, 2018

@flutter flutter locked as too heated and limited conversation to collaborators Aug 1, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.