-
-
Notifications
You must be signed in to change notification settings - Fork 623
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
[closures] Concept examples and explanation needs improvements #1529
Comments
Creating an issue about improving the closure concept was on my todo list. 🙂 In addition to adding to the existing concept documents I think it would also be good to maybe rework/simplify some of the existing content. Do you want to work on this? |
Yes. I can try :) |
Hi @junedev! I don't know if this is the place for this, but I notice something about the closure explanation. In the explanation it says: "Closures are a programming pattern in JavaScript which allows variables from an outer lexical scope to be used inside of a nested block of code. JavaScript supports closures transparently, and they are often used without knowing what they are." // Top-level declarations are global-scope
const dozen = 12;
{
// Braces create a new block-scope
// Referencing the outer variable is a closure.
const twoDozen = dozen * 2;
}
// Functions create a new function-scope and block-scope.
// Referencing the outer variable here is a closure.
function nDozen(n) {
return dozen * n;
} But most explanations, including the one on MDN define a closure as being In the explanation it says that referencing the outer variable from the first block scope would already be a closure. Looking at the docs from MDN, that would then not seem to be correct, as that first block scope is not a function? I'm mostly asking because it is confusing me as well, and as closures are a hard concept to explain, I wonder if we might need to make sure this explanation is correct. |
Great question! I am not 100% sure myself. @SleeplessByte, what's your opinion on this? Would you can the block example a closure as well? In any case, I would recommend making all the main content about the function version of closures as this is what most people think of when they hear the term and how they are mostly used. Then if we decide the blocks count as closures as well we can add that as an additional knowledge nugget in about.md. |
I'm curious what @SleeplessByte thinks (if only to learn ;)), if y'all think it's better to delete the first shown block-scope, let me know, I'll remove it and open a PR. |
@khendrikse Either @Jasstkn will already incorporate this in their current re-work of the concept files or it can be addressed afterwards. In any case, I would like to avoid you and @Jasstkn working on the same files at the same time. |
That is also fine :) |
Sooooo. 👋🏽 Definitions are as difficult as naming is (I wrote articles about similar subjects in the past, for example: JavaScript, Ruby, and C are not call by reference), which is what makes this even more interesting. Yes, in general closures are often defined as enclosing values inside a function, which is often possible in languages that "do not treat functions as a special case" (meaning functions are first-class citizen, and can be passed around, just like other values). This is usually mentioned because if you can pass functions around, it means you can often execute the function on a completely different call site then where it was defined. The operational bonus is then that that function has access to variables it had access to when it was defined despite the call site NOT (necessarily) being able to access those. Okay. Great. In JavaScript blocks (the first example) cannot be passed around, but in some other language (hello there Ruby), some forms of blocks are callable (effectively making them similar or the same as functions), ánd can be passed around. Because the block from the example is static/fixed in place, its power to enclose the variable is "lost". It doesn't matter. Therefore I would agree to bin the example, despite you probably being able to find references where a writer argues that any enclosure is "a closure". I'm not willing to say that we absolutely cannot call this a closure, but in general, when people who know JavaScript or similar languages talk about closures, they will almost always refer to instances of functions that enclosed variables, and thus not talk about blocks. TL;DR; correctness of the first example doesn't matter. It's use-case is basically none (other than creating a new block which can be great when writing
Are there other ways to enclose other than using a function? Yes! For example classes can do this too. const definedOutside = 'hello, world!'
export class Shout {
// This function is technically a closure
call() { console.log(definedOutside); }
// This variable is, once this proposal becomes language,
// technically enclosing a value from outside this class, but will
// probably not be called a closure
#privateVar = definedOutside
}
const utterance = new Shout()
utterance
// => Shout {#privateVar: 'hello, world!'}
utterance.#privateVar
// => SyntaxError Private field '#privateVar' must be declared in an enclosing class
utterance['#privateVar']
// => undefined
utterance.call()
// => 'hello, world!' Classes can in fact enclose values passed from the outside in their constructor, variables created in their constructor, or even variables attached to themselves export class Enclosing {
constructor(passedValue) {
let increment = 0
this.magicNumber = 21
const self = this;
// Return a new object that does NOT have Enclosing as its prototype
return {
// encloses variable defined in constructor
increase() {
increment += 1
return increment;
},
// encloses variable passed in constructor
call() { console.log(passedValue); },
// encloses the entire object that was created by the constructor
ref() { return self.magicNumber * 2 }
}
}
}
// Now try it out
const enclosed = new Enclosing('Goodbye, Mars!')
enclosed.magicNumber
// => undefined
enclosed.increase()
// => 1
enclosed.call()
// => "Goodbye, Mars!"
enclosed.ref()
// => 42 |
Thanks so much @SleeplessByte |
No problem! Gewoon blijven vragen :) |
@Jasstkn How is it going? Do you still want to work on this? |
@Jasstkn Since I haven't heard from you in a long time, will un-assign you from this issue for now so someone else could pick this up. |
+1 on this. I'm doing this exercise for the first time, and I had no idea what I was being asked to do, and I couldn't manage to glean much context from the test cases either. I haven't finished it yet, but particularly task 1 seems to be lacking information for someone who has never encountered this before. Intuitively, if I were to write the translate2d function myself, I would write something like
Ok, cool, but now looking at the task 1 information
My first thought is how on earth does the arguments from It wasn't until I somehow just happened to stumble upon the answer, that I was able to work backwards from there and understand what is happening.
I'm not sure if I accidentally missed a lesson before this one or if I'm just not the brightest around, but some more information would be extremely useful, maybe as @Jasstkn mentioned an example of returning a function to give the user some more guidance towards the solution, because as it is, I'm pretty sure if I didn't have some prior experience and this was my first time learning I would be hard stuck here for sure. |
You haven't seen it thus far, because we make sure that you don't "see" something until you've had the concept about it, which this exercise is supposed to provide. However, the current |
hey @junedev I would love to work on this issue! |
@sahaankit I am sorry but we currently don't except community contributions. Here the official notice with a link with more info.
|
Hi @junedev, I think you still don't accept community contributions, but is it OK if I open a topic on the forum to discuss this and then submit a PR based on the opinions? I feel this is an important part of improving the JS syllabus, along with promises! |
@safwansamsudeen A forum thread to get to a good plan for this issue is definitely appreciated and a good idea. As for the PR, I can make no guarantees at the moment. The JavaScript track does not have any active maintainers currently. If you are very confident, that you understand enough about how concept exercises on Exercism are supposed to look like, have very good JavaScript and English skills, you can make a PR and I can quickly check and approve. (Probably good to ping me with whatever the final ideas where from the forum thread beforehand.) |
Is this still available? |
@Zumh here's the forum thread for it. I'd appreciate it if you could voice your ideas there. I didn't actually work on it, as I didn't really know much about Exercism back then, but I'm willing to give it a go now. If you think you can do it, though, please work on it (as long as junedev approves, see previous comment) - and if you find it too hard, I'll take over 🙂. |
Won't that dilute learner's understanding of how the language is designed? Understanding closures helped me digest the idea of classes. Also have some fun defining a function conditionally, instead of running whole logic of selecting every time the function runs I could just run the favourable flavour of the function. |
Hi.
While I was learning concepts for JavaScript I found out that closures theory isn't very helpful for solving the suggested practical exercise: Coordinate Transformation.
I would like to propose to improve it by
return
Let me know what do you think.
Connected links are here:
https://exercism.org/tracks/javascript/concepts/closures
https://exercism.org/tracks/javascript/exercises/coordinate-transformation
The text was updated successfully, but these errors were encountered: