concepts
An overview of concepts in programming. This is mainly as a practice for interviews.
closures
I always see a closure as a 'saved' stackframe. This text from the web says it quit clearly.
A closure is just an evolution of the concept of the stack.
- The stack is used to separate/isolate scope when functions are called. When a function returns the stack frame (activation record) is popped off the call stack thus freeing the used memory allowing the next function call to reuse that RAM for its stack frame.
- What a closure does is that instead of actually freeing that stack frame, if there's any object/variable in that stack frame that's referenced by anything else then it keeps that stack frame for future use.
- Most languages implement this by implementing the stack as a linked list or hash table instead of a flat array. That way, the stack can be re-ordered at runtime and is not constrained by physical memory layout.
- From the point of view of the language, it's definitely the stack. Since that's what closures are in theory - a modified stack.
- From the point of view of the machine language or underlying C/assembly code, the idea of a linked-list stack is nonsense. Therefore the higher level language must be using the heap to implement its "stack".
- So the variable is in the stack but that stack is probably located in the heap.
- When you return a closure you return not only the result of a function but the whole thing with it's variables. So it also is NOT a function pointer, because that only returns a pointer to the code from which a stack frame can built.
asynchronous concepts
callbacks
The most known asynchronous construct used is the callback. This is just a function (pointer) that gets called whenever the lengthy processing task is done. It will then present the result as a parameter to that function. In the man time the rest of the program continues , listening for other things to do.
One of the problems with callbacks is known as callback hell. This happens when you have to chain lengthy actions together. So you start a method with a callback inside a callback, and so on.
promises
To avoid callback hell you can use promises, which are objects that are returned from an asynchronous function. They have methods you can call to provide the callback functionality (.then()) or error (.catch()).
Mostly you use it like this:
| promises | |
|---|---|
But its is the same as :
| equivalent | |
|---|---|
Just to show that someAsyncOperation is not a promise itself, but a function that returns a promise.
There is still nothing conceptually different from callbacks, but here you can chain the promises. So let a promise return yet another promise and wait on that as well, again by calling the .then() function. That means you get all then calls at the same level but probably more important you get only one .catch() for all of them.
Mostly you could view a future as the token you get in some bars after you order, then when it's done it flashes so you can get your food.
The terms futures, promises, delay and deferred are often used interchangeably. At least in java the main difference seems to be that a future is a read-only reference to some value that is not computed yet, but a promise can be written to as well. In java they are also connected, you can get the .future() from a promise object. A promises in that sense is also the promise that it will fill the future's value (once only).
In other cases a future and a promise are created together and associated with each other: the future is the value, the promise is the function that sets the value -- essentially the return value (future) of an asynchronous function (promise). Setting the value of a future is also called resolving, fulfilling, or binding
So these are a value that will be filled in the future, and a function that promise(s) to fill the value.
dart
Dart specific only talks about futures and the future API. It can be used by the API functions or through syntactic sugar 'await'. Await is used more.
If we have two waiting functions :
| dart async | |
|---|---|
Then the sugared version would be :
If you use the future API it would be a lot more elaborate :
The wrapper functions fBeers() and fCoins() seem to be needed to get the parameters through the functions. There is probably a better way to do this, but the dart docs are very bad at this point.
In main we call the fCoins wrapper which creates a future that is 1 second delayed. So that mimics the getCoins() function taking a second to complete. The then(_) function in the wrapper is a common way to denote you don't need to use the variable. We used the one from the outer scope, the start value passed to fCoins(16). After a second the callback ( (c) => fBeers(c) fires with the result of money/2.0 and returns a new future. This again fires it's callback (the print) with the result of coins/2.0.
This is a tedious way of doing it but will give you more insight in the futures mechanism.
Note that 4 then() functions are called, if you put a print statement in each function, you would get : main, fCoins, getCoins, then, fBeers, getBeers, Drink 4.0 beers
To get a print in the first .then() you would have to drop the arrow notation and modify it like this :
Dependency Injection
This next very clear bit is from : visit
Let's do a quick recapitulation of what is a dependency injection. Feel free to skip this part and get straight to the main course 🍽️
Dependency Injection (DI) is a way to create objects that depend on the other objects. A Dependency Injection system supplies the dependent objects (called the dependencies) when it creates an instance of an object --- Angular Docs
Formal definitions are nice but let's talk about it in more relaxed fashion. Our components and services are classes. Every class has a special function called constructor which is called when we want to create an object (instance) of that class to be used in our application.
I suppose we have all seen code like constructor(private http: HttpClient) in one of our services. If we wanted to create our service without Angular DI mechanism we would have to provide HttpClient manually.
Our code would look something like this const myService = new MyService(httpClient). But from where do we get the httpClient?
Similarly, we would have to do const httpClient = new HttpClient(httpHandler) to get it. Now, what about the httpHandler? When does this stop? As we can see, wiring stuff together manually would be a tedious and error prone process...
Angular DI mechanism does all what was described above automatically. All we have to do is to specify dependencies in the constructor of our components and they will be provided to them without any effort on our part. But nothing is for free...
angular DI
In angular you can inject the dependency object in the constructor :
| dependency injection | |
|---|---|
but you still have to declare the HttpClient provide somewhere in the component.One way of doing it (the old way) is to put it in the provider[] array of the @NgModule decorator.
| @NgModule decorator | |
|---|---|
However in angular6 and later you can also us another syntax. Here you specify on the service itself where it will be provided. So this is the other way around :
This is the most commonly used version. You can say providedIn: OtherModule but root just suffices for normal use.
Also you cannot use this in @Component and @Directive
So this is wrong :
| wrong | |
|---|---|
We still have to use providers[] so i tend to favor sticking with the providers[] array for all instances.