I know there is still a lot of hatred for PHP out there, but in my opinion with version 7 at the latest (which is already over 5 years old!), PHP e...
For further actions, you may consider blocking this person and/or reporting abuse
The first and the last (types arguments and optional chaining) are available with TypeScript. And for the "match" you can simply use object constant:-)
But nice try!
Thank you for these additions! Can you give examples for #1 and #3 in TypeScript? This article is about native JavaScript since not everyone is using TypeScript in every project.
Of course you can use an object constant, but
match
is nevertheless a bit more syntactic sugar here and directly assigns the values instead of storing them first 🤷🏻♂️The way you'd used named parameters in JavaScript OR TypeScript is through the use of an object:
JavaScript:
TypeScript:
The way you'd use optional chaining is actually available in ESNext now:
Thank you for giving these examples! As I wrote in the article, I know about using object destructuring for named arguments, but I don't like this approach very much here - just doesn't feels like clean coding style to use an object inside the functions parameter definition. I can't think of a reason, why JavaScript doesn't already provide "real" named arguments already...
Great, didn't know that! 👏🏻
I agree 100%, however, it would drastically hinder performance as it would almost guaranteed be a runtime check in the engine. That's why I'm hoping either Babel or TypeScript will tackle it in the future to essentially be compiled away into positional arguments.
Not sure I follow your thought. Typescript performs type checks on compilation only and strips all the types away, so there's never a runtime check.
Update: Oh you mean for chaining arguments? There's zero to none performance loss
We're discussing named parameters and the performance hit they would be on JavaScript's runtime.
And TypeScript does a whole lot more than type checking nowadays.
I must chime-in with a report from experience.
Some years ago I worked on a fairly large (~700k lines) JavaScript codebase that implemented a 200-line helper that permitted the following:
It was used extensively, including in time-critical places such as during render operations. While there was a performance hit that could be measured with dev-tools, it was nothing compared to the usual day-to-day bottlenecks that were encountered.
The point is to say that sure, worry about performance, but perhaps rest/spread/destructuring isn't the first place you need to look these days.
Sorry another thing to add on would be that almost everything in JavaScript is an Object. In the example in this thread there was the example below. But in JavaScript/TypeScript you will normally have a variable that is being passed around. so you're not going to normally pass an Object literal to every function call. Python has both Named Parameters and "Unpacking" (Object Destructing) using the
filename, *args, **kwargs
. This is also why I do not like usingtypeof
operator to determine the data type i am being passed. Because if you are passed aMap
and are using bracket/dot-notation you are not using theMap
correctly.Valuable addition! Thanks for that.
I don't follow the link between "native javascript" and typescript. TS is compiled to JS. I think you can use a Map to achieve the same results with a php match. EDIT
This is a haphazardly written code complete with as close to replicated functionality you would expect from PHP match
As you already said: TS requires a compiler to JS. This article was meant for those writing JS directly.
Cool idea, can you give an example with Map?
Your example of the switch wouldn't work, you are assigning to a constant variable. I consider declaring without defining an issue, and would rather split the switch to a separate function (e.g.
getFontWeight
) and create the variable withconst fontWeight = getFontWeight(value)
. It's cleaner and better to test.My bad, thanks for pointing out 👏🏻 I updated the example code. Totally agree with you about the separate function, nevertheless I just used
let
to keep things simple.You can easily replicate match behavior (actually not, see edited version):
Edit
As Stephen pointed out by using the above solution fontweight will contain a function.
For some reason I did not come up with an even simpler solution first:
You can also do it without having to store the object in "match":
And if you need a default value you can achieve it like that:
That’s very clever 😀
It reminds me of the guards expression in Haskell.
The issue I can see with this is now the variable fontweight is a function is it not?
No it isn't.EDIT: Sorry you are right it is a function, for some reason I was so focused on the Arrow operator on PHP that I wanted to do something similar but did not come up with the even simpler solution.I will update my post.
This is a great addition, thank you!
#1 Named parameters
Everybody's entitled to their opinion - but at this point using an (
options
) object and destructuring it is an established idiom which means that adding "real named arguments" would add more complexity to the language for very little gain.That's actually pretty common in languages that support pattern matching on the language level (pattern matching is a conditional construct, destructuring is not - example: Elixir).
#2 Match Expression - There is a TC39 Proposal ECMAScript Pattern Matching - as it is only at stage 1 at this point it may never happen.
That said your particular example could be readily implemented with a Map:
PS: the examples employing objects in this manner overlook that an object's keys have to be either strings or symbols - while a
Map
's keys can be any value. So using anumber
on an object as a key will result in it being coerced into a string.Granted it would be really useful to have something like Rust's match expression or ReScript's switch (i.e. OCaml's match).
However Franceso Cesarini of Erlang Solutions observes that newcomers to Erlang have three hurdles :
i.e. pattern matching isn't something that people find all that intuitive, at least initially - though from what I've witnessed once they "get it", they can't get enough of it.
#3 Optional Chaining is part of ES2020 (June 2020), Chrome 80 (February 2020), Firefox 74 (March 2020), Node 14.0.0 (April 2020). (caniuse: JavaScript operator: Optional chaining operator (?.))
(Related: Nullish coalescing operator (??) - caniuse: JavaScript operator: Nullish coalescing operator (??))
Wow, thank you for these detailed insights 😍👏🏻 I really like how the discussion explodes here 😅
FYI: Often the answer is Use Functions!:
3 - it means for 15% of internet users app or website using optional chaining will break because older browsers does not support it.
Given that you are supposed to be practicing Differential Serving anyway it's a non-issue.
ESNext is transpiled down to ES2017 to yield smaller bundles for modern browsers while larger bundles transpiled all the way down to ES5 are available for legacy browsers.
A Universal Bundle Loader
Bringing Modern JavaScript to Libraries
Publish, ship, and install modern JavaScript for faster applications
Still, the post is a comparison between JavaScript and PHP, and you write about EcmaScript:
= JavaScript does not support optional chaining
JavaScript is nothing more than a trademark of ORACLE America, Inc. which they obtained through their acquisition of Sun Microsystem, Inc.. The trademark was licensed by Sun to Netscape and later to the Mozilla Foundation.
Other than that JavaScript is just a colloquialism to refer to the scripting language features that are used for browser automation. ECMAScript is an effort to standardize that scripting language. As it is, no browser claims to implement any ECMAScript spec in full - they only aspire to do so (and often they implement features beyond the spec).
Back in the day we used jQuery to bridge gap between the variations between different browser vendor implementations. Today we use Babel to bridge the gaps that have emerged over time. The more things change, the more they stay the same - so while the tools have changed, we still have to bridge gaps.
You are free to use whatever dialect you prefer - though I don't envy anyone who may have to help support your work.
But ES2020 includes the Optional chaining (?.) operator so it is now part of what people colloquially refer to as "JavaScript" - MDN lists it under the JavaScript Reference - and it is available to everyone to use via Babel.
Didn't realise PHP had such nice language features these days!
Here's a JS solution for #2 just for fun:
I included a memoizer just so that it would (with usage) have the "lookup-iness" of
switch
, but obviously it's not quite as elegant as PHP'smatch
!Awesome, thank you for this addition 😍👏🏻
To follow this up, I've since learned about an upcoming TC39 spec on adding pattern-matching to JavaScript.
It's Stage 1 -- so a long way off -- but there are many libraries available that offer it, now including my own.
I even reused your font-size example in the README. :)
No worries! Nice article. 👍
Also I think maybe our termi ology may be different. Parameters are declared with the function definition, what the function is expecting. Arguments are passed to the function when called. So when arguments are destructured in the parameters it doesn't use an object, they are just local scope variables.
developer.mozilla.org/en-US/docs/G...
Destructure, assignment, rest, and spread are all JS language specific techniques to make code readable and cleaner. Different languages can feel clustered if you are not use to working with it, but that is why different languages exist because they all are useful for some use case. Like why can PHP use keywords "let, const, var" to declare variables? Or why can all languages do as Python and just have no keyword required for variable declaration?
.
Thank you for this clarification 👏🏻 I do love the variety of programming languages, but sometimes you used a feature in one language you really liked and wished it also existed in another, that's all 😅
1:
2:
3:
(Requires Typescript or ESNext)
You could always use something like this for the last one (fairly sure I did something similar in PHP before this was an option):
Named Arguments: pass in an object ;)
Match: This is proposed but is only at Stage-1 and hasn't really progressed over time. See github.com/tc39/proposal-pattern-m...
Optional Chaining: This is already part of ES2020. See bram.us/2017/01/30/javascript-null...
darn near anything is allowable as an object key. Besides that, that's a high corner case.
const x = {
["\$&n"]: 12
}
x["\$&n"]
12
I tried to paste this here in a code block, but it wouldn't show.
The one JS feature that I wish existed in any language: async-await.
100% yes to that! 👏🏻 async/await makes code so much more readable and clean.
$fontWeight = match ($weight) {
100 => "Super Thin",
300 => "Thin",
400 => "Normal",
600 => "Bold",
900 => "Heavy"
};
Error prone code... What's the value of $fontWeight if $weight = 101 ? Is there an error ?
Safe "Switch expressions" constructs should assert there is always a default clause (i'm looking at you rust 😍)
match
has a default case too. Also, you can comma-separate multiple values:Edited the example in the article accordingly.
Awesome! Didn't know #3 was already possible in JS 👏🏻
Thanks for this post. Really interesting discussion in the comments. As someone who primarily works with JS/TS, it’s cool to learn a little more about modern PHP.
I'm glad this was useful for you! And yes, the discussion here quickly escalated - I like it 😅
Great post. But actually I am disappointed that people try to defend js by writing false info about availability of these features. PHP is a leading language. It is normal it has things earlier
The reason js doesn't have a couple of these is that the same thing can be accomplished in a similar amount of code with already existing features. Therefore, adding them doesn't truly make things better. Why add a named parameter feature if it's already doable with an object?
It is not the same. Named parameters are enforced. Object params are not
Optional chaining is now available in newest ES.
This post got me excited to use PHP8!
Awesome, glad to hear that 👍🏻
Loads of folks saying that named arguments is possible using an object have a fair point. I’d still like to see it as an actual feature, tho! It could be an optional thing.
Exactly what I was thinking 👍🏻
Bruh, the optional chaining was introduced to javascript back in 2020 javascript.plainenglish.io/new-ope...
you should do a little research before publishing this kind of stuff
For your last point, there is the optional chaining operator that just came to JavaScript in 2020: developer.mozilla.org/en-US/docs/W...
Thanks for sharing
My pleasure 😊
Can you elaborate more on how the #2 works?
You can do all of this (or something damn close) already in JS in almost all modern browsers. You dont even need TypeScript (but that's true as a general statement anyway!)
In the section #3 Optional Chaining, i think it was exists in javascript
I use this since years ago with Nim lang.
I think Scala also has them.
All these features happen to be available in C#. Named arguments are in C# since version 4, switch expressions since 8, and null-conditional operator since 6.
In JavaScript, all of these features are available but the syntax can get dirty as pointed out by others. I really wish if PHP has a strong hinting system for associative arrays.
Waaw, is this php? İ'm not sure. So beatiful 🤩
😍👍🏻
What about 200, 500, 700 and 800?