-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
if-else
and switch
as expressions
#10841
Comments
You seem to be wanting to change ECMAScript, and TypeScript is the not the right way. I assume you have reviewed the design goals of TypeScript. In particular goal, in particular:
Also there is the non-goal:
If there is an improvement to the initializer syntax for |
@kitsonk wrote:
ECMAScript is a very slow moving standard, and I don't even have a clue of how to build up enough support to get a feature change pushed through there. When there are huge design wins that are naturally superb without any notable negative implications, then transpilers are one way of getting the functionality sooner and influencing the direction of ECMAScript by validating the popularity, utility, and soundness of improvements. There are at least two reasons I believe TypeScript may be not only the right way but also the _only way_ in this particular case:
One transpiler which supports this feature is Nim, but it has so much heavy-weight baggage that I can't consider it. CoffeeScript also supports this feature, but is too limited to meet my needs. I do appreciate TypeScript's light-weight design goals and avoiding "everything and the kitchen sink" approach to adding features. That is why I am only suggesting what I think are features which are very frequently required and are also light-weight and/or very specific to TypeScript's main goal of typing (and tracking) ECMAScript. Brenden Eich referenced CoffeeScript w.r.t. to influencing his thinking about the future of JavaScript.
Yes I had read it.
I am not adding any keywords nor changing the syntax any keywords. I am proposing to interpret two existing keywords as both statements and expressions, which albeit does add syntax for expressions that was only formerly available as statements, it doesn't add syntax which didn't already exist and isn't already familiar to all JavaScript users. And the emitted JavaScript isn't mangled and is very clear. TypeScript has added expression level syntax sugar such as index properties (granted that is constrained to the expressions for property name slots). And that is entirely new syntax that is very unfamiliar to JavaScript programmers. A general first-class expression level syntax added by TypeScript is I believe function type parameters. Yes it is entirely erased, but nevertheless it is very unfamiliar (to JavaScript programmers) new expression-level syntax.
I am not proposing to _exactly_ mimic the design of existing languages. The ability to treat And the intentions of program authors is very much inline with this feature suggestion, because there is no other way to accomplish it, which respects the general software engineering principles DNRY, SPOT (Single-Point-Of-Truth), and encapsulation. Thus it makes the most sense and entirely agrees with 1).
This initialization for a This is already a feature of JavaScript via the anonymous function construct which this suggested sugar would transpile to. So it isn't like we are doing something that JavaScript programmers can't and don't already do. I am proposing sugar to make it less fugly to write.
The typing of the suggested sugar is entirely erased in the emitted JavaScript and the emitted code very closely resembles the sugared code minus the fugly anonymous function wrapper. No metadata is emitted. Also apparently informing TypeScript that these are expressions in this context, would enable TypeScript's inference engine to infer the union type, which it can't do currently when they are considered only as statements with |
The fact that the ECMA committee doesn't move with the speed/openness many would prefer doesn't change who's responsible for adding new expression-level syntax to JS (re-using existing keywords doesn't mean it's not new syntax). |
P.S. Thanks for marking it as a Suggestion. Out-of-Scope is okay for at least it meets my minimum goals of documenting it as a valid suggestion for potential derivatives of TypeScript, ECMAScript committees, etc. @RyanCavanaugh wrote:
Did TypeScript wait for EMCAScript to add type parameters to first-class function expression syntax before adding them to TypeScript? Granted type parameters are germane to typing which is TypeScript's main goal apparently. But it is entirely new syntax that isn't even remotely similar to anything in EMCAScript. _Another problem is that TypeScript can't currently type the transpiled JavaScript with the anonymous function._ So there really isn't any way to do what we normally can do in JavaScript in TypeScript! function f(z) {}
var x = 1, y = 2
f((function() { if (x) { for(var i = 0; ++i < y;); return i } else return true })()) // Error "No best common type exists among return expressions." TypeScript can't infer the type So I am forced to annotate the type which makes it more verbosely fugly: function f(z) {}
var x = 1, y = 2
f((function():number | boolean { if (x) { for(var i = 0; ++i < y;); return i } else return true })()) Should I file a bug or is that intended behavior? And would treating Obviously the goals are guidelines only and the design goals document says sometimes the goals will be conflicting. Given the great amount of effort that has been poured into TypeScript to support type narrowing (discrimination) guards on |
@shelby3 wrote:
Also I forgot to mention by "other potential derivative", that there is a small possibility that I may in near-future (if my plans proceed as hoped) hire someone to add the features I want to the toolchain and maintain the fork for me. And influence what I want by making a variant popular. Obviously that is pie-in-the-sky at the moment, but isn't as if I haven't produced million users software before. Obviously it is best to work within the larger community for the moment, so best to record these ideas here and observe reception. |
@kitsonk wrote:
Posted to ES Discuss and also the discussion group for SoundScript, for continuing discussion here or there, applicable to acceptance in any relevant scope of responsibility or willingness to adopt. Also the proposed Units of Measure (#364) is yet another example where there is considerable popular support for a very unfamiliar (to EMCAScript) expression-level syntax; and which appears to me to be a special case syntax pollution that could instead be more generally accommodated with nominal types. Hypocrisy of stated goals of TypeScript or is it because anything germane to improving typing receives a pass? (I hope the bias isn't the affiliation to Microsoft projects such as F#) |
Accusations of hypocrisy and bias are hardly constructive. TS has a very clear mission which your proposal does not align with. Period. Your basic idea has already been proposed for ES in the form of the |
The difference with "Units of measure" is that you can erase all the expression-level type hints and get valid JavaScript. Thats not the case with the above modifications to FWIW there is a pattern matching proposal (which has been sitting for a while w/o anyone to properly champion it) here: http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching and I believe it modifies |
@rtm wrote:
Question marks and hope are not accusations. Reading comprehension matters.
Is that your opinion or is there some basis other than what has already been stated here? What is that clear mission succinctly?
Link please? @spoin wrote:
I presume you mean you can erase (elide) it without any transpilation of remaining code without the type hints. Because afaik erasure (as opposed to reification) in programming language design context usually means to not put any metadata about types in the runtime, and doesn't concern itself with compilation of source code to the target runtime. Yet there are artifacts of TypeScript which can't simply be elided and produce valid JavaScript, e.g. index properties. What is the consistency of the goals succinctly? My interpretation is that the goals are to minimize the transpiling (on a cost vs. benefit analysis) and to prioritize erasable typing over other feature enhancements. Is that approximately correct? Again I reiterate that I am in full support of a light-weight transpiling layer. I reject JavaScript compilers for such as Scala and Nim, because I can't even readily comprehend the JavaScript they emit and interoperability with JavaScript is an important facet to maintain at this juncture. I am enthused about Google's SoundScript idea of possibily integrating the TypeScript syntax into the VM, to make my toolset cycle even more efficient (in addition to potential performance gains). Just a few moments ago, I wrote a defense of TypeScript against some claims made by N4JS. |
@spoin wrote:
Thanks. That is very much in the constructive spirit of aiming for solutions. I also found some examples employing the alternative Since that is already a proposal for ECMAScript, then doesn't that give us some basis to consider adding it to TypeScript on a very careful cost vs. benefit analysis? (including the cost of prematurely adopting a proposal that might not gain sufficient support to become a standard someday, and noting my points upthread about how minimal the transpile footprint is for this, only wrapping in an anonymous function). Note however, the problem is that proposal also carries with it a lot of new syntax for matching patterns, but perhaps we could choose not to implement that facet of the proposal, which would maintain the very minimal transpile overhead (as stated above) and would still be compatible with the proposal. I would still argue for the need for the expression |
There is an ECMA script proposal (apologies for not having a link to hand) for using the 'do' keyword to introduce a statement lexical environment from within an expression, which achieves what you want, while being general enough to support many other statements in addition to if and switch. For example:
|
You might as well try beating your head against a brick wall as to continue With regard to the Bob On Sun, Sep 11, 2016 at 4:35 PM, shelby3 [email protected] wrote:
|
@MatAtBread it is a Stage 0 proposal documented here: http://wiki.ecmascript.org/doku.php?id=strawman:do_expressions It is listed as still active on the Stage 0 proposals page though clearly it isn't being actively championed at the moment, as the last edit was 2011. |
@MatAtBread thanks for the summary. I am doubting if there is any advantage to introducing superfluous syntax instead of accepting my proposal, because then Edit: a On Monday, September 12, 2016 at 1:18:19 AM UTC+8, Shelby Moore wrote:
|
@rtm wrote:
Lol, I like the fortitude. Notwithstanding that I haven't entirely abandoned the remote possibility of convincing sufficient people that this feature should be added to TypeScript, but I am not pushing hard or expecting, perhaps you missed my other statemenets upthread quoted as follows:
@rtm wrote:
Maybe some care about clarifying the interpretation of the scope of TypeScript's goals. I for one am still finding ambiguity in every attempt to do so, juxtaposed against the contradictions in features that have been added. I do believe there may be a clearer interpretation and that is one of my goals by continuing the discussion. @rtm wrote:
Tracking language extensions is obviously one of the goals of TypeScript. Also TypeScript has added expression-level syntax that isn't merely elided from the emitted output. The demarcation that you are claiming is clear, is actually fuzzy and apparently somewhat subjective. Even if you claim that anything to do with typing (even expression-level) is out-of-scope of ES language extension and thus the exclusive domain of TypeScript, then I can still argue that adding typing was discussed on ES-DISCUSS this month. Even statement versus expression is also involved with typing, since statements have essentially the
Agreed, but that didn't stop TypeScript from adding features that might not be in ECMAScript until many years from now if ever.
I wasn't clear if you weren't referring to a proposal made in some discussion in the TypeScript community, i.e. that someone else like me had attempted to propose something for ES in the TypeScript community. Thus I wouldn't have thought to search ES-DISCUSS. Also please know that I haven't not been aware of how EMCAScript is developed. I had no clue at all that ES-DISCUSS even exists before @kitsonk mentioned it. I am not even clear as to where the official discussion takes place, how to add proposals, etc.. Hadn't applied the time yet and not sure if that is a good use of my focus. Generally and lately I tend to lean towards being oblivious of standards committees because my experience with standards committees has been they are a waste of my time. I am for example listed as a contributor to CSS2.1, but my attempts to help on CSS3 and WebSockets were a total waste of my effort (they conflated the framing and data layer because they were worried about making the implementation simplistic, same to very poor design decision for the Opus container). |
Technical Committee 39 is the governing body for ECMAScript (ECMA262). The current official specification is here. Their GitHub repo is here. There is a proposals repo and a process document of how proposals are progressed. TC39 meet bimonthly in person to continue to move forward with the standard. They have published contribution guidelines. For a standards organisation, they are one of the most open and transparent ones, in my opinion. My opinion is that around the time of the ratification of ES2015, the processes bedded down for proposals (because ES2015 was a bit of a ruby scrum) and the process has added a great deal of transparency to the process. The problem was that ES2016 was fairly light (especially compared to the behemoth that was ES2015) though it is looking like ES2017 is picking up a bit with 5 proposals at Stage 4, ready for ratification. |
@shelby3 wrote:
Major design decision quagmire which makes that the inviolability of that goal seem unwise? Or are we so purist on the goals that we instead prefer unsoundness and manual tsuris instead? |
@kitsonk I think the stance I will take is if this feature becomes important enough to me to allocate resources to paying someone to champion it, then I will direct them to this thread. I won't champion it myself because I don't have the time to do that activity. I filed this issue not as top priority concern, but just to get it out of the way as something I wanted to register as an issue. And I am actually happy it is on my Github activity archive and not spread around a dozens of mailing list discussion groups I have participated in over the decades. It doesn't mean everything I write about has to be immediately actionable. Our discussion also caused me to think more about the goals of TypeScript. Even I am not expecting any immediate action (nor even expecting an enthusiastic reception for) the typeclasses proposal I am developing as an issue. The point is to document what I think and enjoin any discussion. This can help my planning process as to where TypeScript fits into my current strategy. Given I only started learning TypeScript 48 hours or so ago, I am trying to lay down as quickly as possible my areas of major concern and then figure out where I go next with it. Thanks for everyone's points in this thread. I suppose comments in this issue thread will wind down soon which is also my desire. I will need to move on to other work, but also my strategy w.r.t. TypeScript, EMCAScript, modules, etc is being formed. |
@spion wrote:
We've been discussing that document throughout this thread. |
All because of inflexible, purist design goals, we are unable to fix a type design error in JavaScript:
|
@shelby3 If by index properties you mean let o = {
['prop']: 1
} This is already in ES6. See object literal extensions |
The extensions that are most likely to be implemented in TypeScript next are existing ES6 features. Next are roughly the ECMAScript proposals on this list: https://github.com/tc39/proposals . Finally, some stage 0 proposals might also find their way in; they are here: https://github.com/tc39/proposals/blob/master/stage-0-proposals.md) |
@spion wrote:
Thank you. Even I have viewed that linked site many times (have a copy open in one of my browser tabs always), I hadn't paid attention to "object literal extensions". |
@spion wrote:
Note that Private Fields is proposing a syntax which is different than the one TypeScript uses (and apparently some different semantics as well, so perhaps it is an orthogonal concept?). Someone from TypeScript should probably try to influence that proposal to adopt the Edit: note I have posted to that discussion there to propose how to avert the issue and be able to employ |
This and this impact on TypeScript is being covered on #9950. Why are you dragging this issue off topic? |
@kitsonk wrote:
Thanks for cross-referencing. Future discussion on that particular point should continue there.
Because (if the design goals are off-topic then) you did in the 2nd comment of this thread, but I interpreted your comment to be on-topic. And because narrowing by-example relevant to our discussion derived from your linked comment above (example of how TypeScript violated its own design goals and created syntax that could be rendered deprecated by the coming changes to ES) caused you to cross-reference to the more specific issue above. ;) Certainly you don't expect every commentator here to live in this TypeScript Issues their entire days and nights and be entirely aware of every issue thread. Kudos to you for doing that for us. The implied example is to point out that the design goals aren't 100% steadfast and leak-proof. They are apparently guidelines, not infallible absolutism. |
I want to elucidate the "syntax" thing since there is a distinction that has not been made clear. TypeScript has added syntax "holes" where needed to express type system behavior. For example, type annotations in function parameters, or generics in function expressions, as you noted. This doesn't change the existing behavior of the JS, of course. TS has also added some top-level declaration forms: The thing TS hasn't done is added new behavioral expressions (those without ES Stage 1 or higher proposals):
This is actually very consistent. Attractive things like the "elvis operator", implementing |
There are scenarios that require we produce a result from an
if-else
orswitch
which is not returned:Even if we abandon
const z
forlet z
, the code above is noisy (not DNRY, SPOT, and encapsulated) and if we modify the spelling of the identifierz
, then we have to remember to change it every where it is assigned in theif-else
(orswitch
) statement.Some languages (e.g. Scala) allow
if-else
andswitch
to optionally be used as expressions:Obviously we could use ternary operator expression instead:
But that won't help us for
switch
, nor is the ternary able to employ blocks containing (multiple) statements where only the value of the last statement or expression is the result value:Additionally an expression can be placed inline as a function parameter argument:
The transpiling to JavaScript is straightforward:
I presume it is not necessary for me to write multiple line
switch
examples for the reader to visualize the utility of this suggested feature.The only potential blocking issue I am contemplating is whether the parser grammar has any conflict with accepting
if-else
andswitch
as expressions.As example of a language which supports
if-else
andmatch
(switch variant) as expressions is Scala.The text was updated successfully, but these errors were encountered: