var, const, let... now ‘using’?
Вставка
- Опубліковано 29 чер 2023
- TypeScript 5.2 implements a new keyword - 'using' - which helps to handle explicit resource management in JavaScript.
The 'using' TC39 proposal has reached Stage 3, meaning it's nearly ready to come to JavaScript - so TypeScript has added it in anticipation.
Full article: www.totaltypescript.com/types...
Become a TypeScript Wizard with my free beginners TypeScript Course:
www.totaltypescript.com/tutor...
Follow Matt on Twitter
/ mattpocockuk
Join the Discord:
mattpocock.com/discord
So JS introduced "using", while C++ introduced "import"... What a time to be alive!
and C# has had it for ages
And VB has had it for decades.
@@suuunly that's not a lot in c# years
i read this "What a time to be alive!" in Two Minute Papers voice
@@suuunly C# = Microsoft Java
Sounds cool but still waiting for that Pipe | operator
Yeah I’m looking forward to pipe and iterator method chaining
It's taking too long! I checked the status recently... and while at it, I played creating my own pipe function (like rxjs).
rxjs has that basically
I feel like at this rate I’ll retire before being able to use the pipe operator…
@@JonathanRose24😂
This is actually pretty useful for WebAssembly libraries that expose objects that need to be manually memory managed. The generated bindings to Rust code have classes with a free() method. So the end user needs to be aware to to call it when the value isn’t needed anymore. Maybe this can even be unnecessary when WASM garbage collection lands, but I think for now using will be a nice improvement.
Reminds me of Drop in Rust
@@zzzyyyxxxIt’s more akin to Python’s ‘with’, but it’s all scope hooks anyways so yeah.
One example is the library, Shiki, which relies on WASM bindings for a regular expression, Oniguruma. But it failed to dispose the objects (by manually call free/dispose) and resulted in a memory leak. Had Symbol.dispose and `using` existed already, it would've saved a ton of debugging.
It's literally like C# using. Used for unmanaged resources too. Async/await was in C# first too
@@_sorashi Isn't the same language-architect that did C# now heading Typescript?
Also, this reminds me of Java's Autoclosable + try-with-resources but with the single keyword as syntactic sugar.
Love the new background, happy to see you back posting videos!
Python has context managers, C++ does it with RAII, Java also has similar with try(resource) and Kotlin later implemented a more clean approach
I'm surprised that javascript took so long to implement this, but I'm glad they did!
I was about to say thta lol
And golang have defers, please don't forget about golang 😢
@@JosueRodriguez08 Swift also uses defer
They did it in the most stupid way. 🤢🤮
@@JosueRodriguez08 I have never used Go but defers are a bit different, since you still have to explicitly call open and close (I think?)
TLDR: We move the process of "cleaning things up" from outside the function inside it.
so.. basicly they added an destructor that most other language already have..
Your new setup looks tidy and neat. Congrats!
use useUsing using use
This is awesome, I often find some of my messiest code comes from writing IO and having lots of connections and objects which need to be closed/released after you're done with them. This keyword pretty much resolves that.
Thanks for the information! This seems like a pretty cool concept, although I'll need to wrap my head around it a little bit more to fully understand it.
"Is JS trying to turn JS into C#?" YES! That's precisely what's happening, as well as every other language with good useful features.
We've reached a point in technology where ALL languages are adopting the best ideas of all of the other languages to popularize and fortify their offerings.
I'm not sure but wasn't async await promise based from C# async await?
@@iooosef6006, I mean, it's a generic functionality, but C# uses the `Task` object and `Task` to communicate what is awaiting a response, not a "Promise" per se. But I think they have similar methods and options.
@@iooosef6006 Yep. C# originated the use of async/await keywords in 2012. However, the semantics (and underlying structures) are slightly different between any of the implementations with which I'm familiar (Python, Rust, C#, now JS).
Not sure if this is the „best idea“ which should be adopted.
Brilliant video!
Well thank you for the update, here's a sub!
You got my sub! Love coding content and we need more TS gurus
Thanks for the video! Only critique on the new setup is the audio. There's a decent amount of room sound being captured. I'm sure you're still putting things together, but in case it wasn't on your radar, there's a new free de-reverb plugin out called Goyo. Might help with the post production.
De-reverb. My god we're truly living in the future aren't we?
Thanks! I have a setup fix for this coming. Agree that it's _just_ outside the bounds of acceptibility.
Nice to see more c# features coming to JavaScript. Assuming the connection is Typescript being built by the same person behind c#
yeah i really miss "using" now that i switched from c# to kotlin (i mean i love both languages and kotlin has .use {} which is nice too but just not the same sadly)
Matt we need more videos).
U r best of the best )
I've always wished JS would have something like Python's context manager. Amazing. Generator functions were always awkward for this
Good stuff!🎉🎉
great video , nice clean, minimal setup
Nice! Thanks for sharing.
Honestly a pretty subpar solution for something that has already been solved in Go for example with the defer statement. More complex, worse syntax, does basically the same thing.
Miss you matt !!
Congratz with the new place Matt!💙
I feel like you can add something that handles the teeny tiny echo-ish thing
Agree, there's a ton of empty space on the walls around me so that can't be helping. Overall happy with it (I don't think my viewers listen on studio-quality headphones so I can get away with it being slightly crap) but as I add more furniture to the office I think it'll get better.
@@mattpocockuk Even if you have the worst sound system on youtube, you can be sure that we will enjoy watching it! 😄
@@mattpocockukI’m just listening on my shitty iPhone speakers and the reverb is still pretty bad. Thanks for the great content as usual.
@@invinciblemode Thanks! That's useful. I have a setup fix coming this week.
We love you Matt
Thanks, great article! Just a heads up the audio sounds a bit echo-y compared to previous videos.
My immediate thought: "Rust's drop in JS? I'll take it"
I love this "news" videos ^^ ❤
Sounds like defer keyword in Go but without special symbols:
const conn = ....
defer conn.close()
This will be called after function execution and before throwing any exceptions.
One difference is `using` runs on block boundary, whereas `defer` run on function boundary. Placing `defer` on a loop doesn't run it every loop, but stacks them up and runs once the function ends.
So what is TypeScript's _using_ going to be transpiled into? What will the native JS code look like?
It does make sense, I came to FE from DotNet long ago, and I've been missing this feature. In Typescript we now deal it on our own.
Other than syncronous thenables, what would be the reason for having separate sync and async disposal symbols instead of inferring it from the syncronicity of the returned function?
Nice addition to the language. Thanks for sharing.
Also nice for handling sockets etc, nice
Really exciting, i dont know if it would be mass adopted, but im sure the libraries will and it'll benefit everyone aboard, great news!
Very interesting, I wonder if this could be used to manage state on the front end
didn't know about symbol keyword, thnaks
Why would we close db connection? In all real world apps there is connection pool and connections are not being closed after work is finished, rather they are reused by other operations. This eliminates overhead of creating and disposing connections over the wire all the time.
You are not very up do date my friend, closing connections is very common in most apps.
@@jrmc732 Why is that better?
@@jrmc732 its only common if you are using transactions, otherwise drivers will provide a convenience method on the pool that releases the connection for you.
Sometimes you need to close connections. If you don't, you'll introduce issues. Perhaps an example could be a cron job that only does one task and then is done.
You still need to tell the connection pull you are done with using the connection so it can go back to be used by something else.
I cant believe you havent done a video on ts-pattern yet!
*Explicit Resource Management* wow that is what I need in NodeJS it was tricky to manage some stuff to close and such...
Ok, sound useful thing. Thanx for video :)
Ah, so JS is introducing a keyword to do RAII.
That’s a good idea, especially since the JS interpreter itself is usually written in C/C++ with reference counting and RAII. So it’ll be easier to directly map the backend implementation to the scripting, there’ll be an explicit destructor you can use for things like I/O flushing, and (esp. complied) JS will pick up one of the core features that enables high performance in languages like c++ and Rust.
My only mild criticism is that “using” might’ve been a suboptimal keyword choice for this. Since your exact intent is to have a scoped variable, why not “scoped”?
Scoped is longer to type and `using` keyword already exists. Why invent a new keyword?
"JS interpreter itself is usually written in C/C++ with reference counting and RAII." Would love a source on this, so far it seems all major JS interpreters/compilers use tracing garbage collection, not reference counting. This allows JS values to have cyclical references and still be able to be GC'd.
powerful speaker... i like the way you speak..
Nice I saw your post on LinkedIn about that :) thanks for sharing:)
The DB example looks hard to read and a little bit more verbose than a simple try catch.
Probably won't use this that much but it does look neat.
If you use it only on one place yeah, but if you are using it in multiple places in your code its worth it.
Even more so if you create a factory function that generates the connection resource from the get db function
Edit: or your getDB function already creates an object with that feature in mind (e.g. the close function is replaced with the dispose one)
It moves the "cleanup" code to be with the item itself. The setup looks a little weird at the moment, but using using (har har) will be far more clean and will help prevent unused resources from still being reserved. Essentially, the library or factory can include the cleanup code so you won't even see it. Also, as the other commentator said, it will be something you write once but reuse in multiple places. Many other languages have some auto-cleanup technique so it makes sense this would be added to JS.
"using" functionality is a great addition to typescript, thanks for the straightforward and easy to understand explanation. You are a very good teacher.
The setting is nice and cool, a picture or two two at the back would be great, can't wait to see what you'll choose.
@Matt what is today wrong with async await and try catch when reading files, and what symbol.dispose solving for the same case?
C# has using which lets you initialize a variable and sets a scope, when operations inside that scope are finished that variable is disposed.
This concept also exists in python with the "with" keyword
Thank you.
He's back!!
Hey, great. Can't wait to abuse this to the fullest 🙃
very cool implementation of IDisposable
This would be perfect for closing AWS Xray segments. Wish I could use it now!
everything is nice in this video❤
I'm intrigued about an important part: catching and handling errors in such scenarios. Looks like we still have to wrap it in a try/catch? I didn't see error handling in this demo.
Thanks for keeping the rest of us current :)
I'm at this very moment (well, this week anyway) trying to get my head round this same concept in Python... With your explanation of how it works (or will work) in TS/JS, I might have grocked it in Python... we'll see in the morning when I get back to my Python code. (sorry for saying "Python" so many times... I'll go wash my mouth out)
With blocks using a class with __enter__ and __exit__ does this in python
context manager
Yeah... context manager
Would be nice for class properties too
Hi Matt, thanks for that.. Interesting how using will enable a whole set of capabilities in the JS land..
I know tensorflow has something similar like tf.tidy() builtin that kind of takes care of gc for the tensors. Using sounds like a similar native capability.
I started of in C# and moved to JS/TS too just as jQuery was becoming a thing :)
Javascript 30 years later to the idea of automatic object destruction tied to a scope.
Would it work with classes? like a cpp destructor? 🤔
Sweet! While this looks much clumsier than what C# has, this does look like a nice improvement.
So like try-catch with resources in Java and the Autocloseable interface?
So when does the dispose function get called? On garbage collection or before?
does dispose execute after a sigint?
I remember using this in C# years ago 🙂
It is like a useEffect in react, where you return the function to be called when the component unmounts.
C# plus TypeScript about to be the new badass stack
sorry for being a noob but could be using be used also for subscriptions?
I recall it from my C# experience many years ago
As we see here, modern additions to JavaScript are quite frequently influenced by C# and DotNet.
Not many years ago, Java eventually also added a simular kind of solution, but in a different way, by integrating it into the try catch finally notation, the so called try with resources.
Except C++ was using RAII in 1984. Python's With statement dates back to 2005 and try/finally was already in the language. Java's try/finally predates C# 'using' and probably C# as a whole.
@@sadsongs7731 I was talking about the try-with-resources variant, which exists since Java version 7 and 8, but not earlier. The old try catch finally had nothing to do with RAII or resource cleanup.
What would happen if your dispose or asyncDispose fail? Also, what about dangling references? Are they handled on the compiler level? Seems like a lot of things to think about and not necessarily preventing problems as much as it’s creating new ones, but maybe I’m wrong.
Your question can be asked for every language even system that has the similar functions. For language/code you write/use, The short answer is probably there is nothing you can do about other than reattempting the failing dispose (of cuz system is totally different, they built tons of stuffs to mitigate/negate this problems). But what happen if the reattempt got cut off for any reasons (like power off)? Whether it will be cleaned after a while by extremely smart GC. Or it will stay there forever until at some points someone have to reboot the server (in web client side case, refresh the website) then nothing will be left.
Your question is pretty similar to what happen to the halfway transferring files if you are transferring files but someone unplugs the usb. The short answer is the files at the "exact moment" of transferring will be damage or lost no matter what. We just need to make sure the original and the already stored files in USB wouldn't be corrupted.
For most of the cases, your question doesn't matter, but for financial/bank (not sure about the embedded code), they have tons of guards, multiple trustful sources, backups to validate/invalidate the potential corrupted data that is caused by your problem.
@@doc8527 Seems like a lot of examples that are very significant. You can't just say "it doesn't matter cause I'm not working in a bank/something else important". To me, every line of code that I write is important even if I'm writing a fart joke generator. And of course, you can ask this question for every language/code that does it, and I do. For the most part the answer is either "we didn't think about it" or "we don't care" or "this is an edge case". To all three my response is you should care and you should think about it. What happens if this new using and dispose functionality is written poorly and is mutating some wider scoped variable? What if the GC already cleaned it? This is incredibly important because that is a security breach waiting to happen with dangling references. I'm not saying it's not useful, or even that I won't use it, I'm merely asking what would the TS compiler do to prevent such obvious problems? Would it work like the Rust borrow checker and make it virtually impossible to create dangling references? Would it just not care? This functionality is very useful exactly in the areas that you yourself have defined as important, so I think it's very important to talk and understand what would be the consequences of this failing and not working with the happy path.
@@ThEldeRS This is discussed in the TC39 proposal!
Why would dangling reference matter? If you have a dangling reference it would have been an issue/bug in the old style of doing resource freeing using try/finally anyway. JS doesn't fundamentally solve this problem in its current design and if you care about it, you should use Rust or wait for JS to have a borrow checker. Either way dangling reference is orthogonal to this new feature.
If your dispose fail, I would imagine you handle it just like you handle it in the past? This feature isn't providing a fundamentally different way of programming, but rather providing a more ergonomic and foolproof way of invoking a dispose function.
This feature is about to lower coupling. When you work with some resource you have gotten, you basically want not to know how to dispose it. Disposing should be on another level of an application, on the same level where getting a resource is implemented. Thus, by itself the feature neither adds new issues with handling a failed dispose nor creates a new approach to do that.
Can Symbol.dispose be used in conjunction with objects in WeakMap?
Looks like a roundabout way of using a defer statement like you have in Go?
Great video. I think I heard a bit of echoing in the new office.
what does dispose mean in this context?
Wow! Cool!
When we do functional programming and therefore without mutation we create more instances, is this useful in this case to perfect the behavior of the grabage-collector to consume less memory?
My biggest question - will it warn if I *don't* use using, but the function I call returns a dispose function?
Also a big question for me. I am pretty sure it'll be possible to lint this even if TS doesn't support it natively (which I bet it will).
this is good to know for when I have to use ts/js! tbh javasript-fatigue is a real thing
Very useful with RAII
So to me its like a deferred function in golang? that is mostly used to clean up /close file handlers and database connections at the end of the scope they were instantiated.
Is this like defer in go?
So the "using" keyword and resources is used to handle the lifecycle of an object?
thanks for the video) The concept itself though - not sure if it comes any handy, makes the code less explicit, in my opinion.
Thank you JavaScript for making me love simpler languages such as golang even more
As soon as he showed the first piece of code I thought "oh so it's like C# but with more complicated syntax"
Is it like "with" in Python?
Wouldn't an alternative for the DB.disconnect() dispose be good for a try catch too? Idk, I see use for "using", but I don't see where it would be 100% better with something else. Does seem cool the [Symbol.Dispose] concept though.
C# had this for a long time it's excellent.
Python has it too and it’s excellent when you know you need to borrow a resource but only got a section of code.
The best part is that this programming interface also works with other resources. for python you can do anything from opening a file to setting up the context to use GPU. If it throws or finish execution, you don’t have dangling opened files or connection
Great video 👌 Could have mentioned that Anders Hejlsberg is the father of TypeScript & C# 🙂
He is, but he's not involved with this proposal.
@@mattpocockuk Agree. It was just to remind people why Typescript & C# share so many features 🙂
Does the resource get disposed as soon as the variable goes out of scope, or is it when the object can be garbage collected? What happens if you pass the resource variable to an async function or reference it in a closure, which uses the resource later?
it is tied to scope, not garbage collection. as for passing it to a closure or storing it somewhere, i gather (though i have not verified) that the object will still have its dispose method called when the initial binding goes out of scope. thats the main point of it being explicitly managed. if you wanted to do cleanup after everybody is definitely done using it, thats where implicit management with a finalization registry can come in handy
So... They just reinvented the destructor...
So this is the drop trait from rust?
They are features imported front c#
What about exceptions? Let's say I get exception while working with db - would Symbol.Dispose-fun still be invoked afterwards?
Yep
Looks pretty cool but would take a while for me personally to develop intuition for it.
so it's like, you add your own function to the garbage collector? Am I thinking of that correctly?
C# has using of IDisposable since forever.
Is it similar to Java's Try-With?