processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.7k stars 3.34k forks source link

replace const with let in reference examples #3877

Closed stalgiag closed 5 years ago

stalgiag commented 5 years ago

Hi all, this is in no way urgent but just wanted to open an issue to discuss the usage of const for mutable assign-by-reference variables.

This can be seen in a number of places, here for example or here. This isn't always the case as seen here.

This is technically okay since the immutable part of an assign-by-reference variable is the reference and the data is able to change. A clear explanation is available here.

Though it is technically okay, I personally feel that it is little more clear to only use const for declaring variables that will not be modified within the scope of that variable. If the data connected to a variable will be changed through use of that variable then it should be declared with let.

limzykenneth commented 5 years ago

I kinda feel the opposite. JS, even after ES6, is still very quirky and as you mentioned const in this case doesn't make the variable immutable but instead just make sure the variable cannot be reassigned. It is something that I thought could have been better named at least. However, this prevention of reassignment is actually quite useful development wise to prevent accidental reusing of the same name for something else. As a rule all variables should be const unless it needs to be reassigned in which case it should be let (something similar exist in Swift for example with let and var).

For immutable objects, it would be better to Object.freeze() them so that they are truly immutable and the assign them to a const for the full C/C++ style constant (almost).

stalgiag commented 5 years ago

That is interesting. I guess I take const as a suggestion about how to think about the variable. But I guess these reductive conceptual tools are not great to lean on. The protection against reassignment does seem helpful, and definitely more reliable than an implied protection against mutability through the contributor's association with the word constant.

Either way I think some consistency should be added, both in the source and the examples.

hsab commented 5 years ago

My justification for using const, had to do particularly with reassignment in line with the description of its capabilities rather than immutability. In the examples you mentioned, my thinking process was "we shouldn't reassign verts but we should be able to append to it, etc. Same applies to props. Although it doesn't ensure immutability as @limzykenneth mentioned, it is a pretty clear indication of the significance of the variable and the fact that it shouldn't be reassigned.

The same mentality is how lebab applies its transformation. If the variable is never reassigned, it will be marked as const and I tried to follow this rule also in some of the leftover examples in src/utilities.

Nonetheless, I couldn't agree more that we need to have a consistent methodology for using let and const, and I really like the following:

As a rule all variables should be const unless it needs to be reassigned in which case it should be let (something similar exist in Swift for example with let and var).

However, I'm not sure if this will be informative or confusing for the example codes and newcomers.

stalgiag commented 5 years ago

Cool that all makes sense @hsab. I especially like this way of describing its use

clear indication of the significance of the variable and the fact that it shouldn't be reassigned.

So I guess then the to-do would be to use const for all variables that don't need to be reassigned?

As for examples, I think we should follow the same use as in the source. The distinction between when to use let and when to use const may be very confusing for new coders, but this is unavoidable to a degree, and better to show the correct usage from the start.

Also to touch on an earlier note, I would say that yes, objects that are truly immutable should use Object.freeze and const but I don't think there are many examples of immutable objects in the code.

limzykenneth commented 5 years ago

For me this is a rather tricky thing to balance, on the one hand there's the "use const always and switch to let when reassignment is necessary" argument which I use myself; then there's the problem with introducing three types of keywords for variable creation to people new to coding (var often still needs to be taught as a lot of materials online still use it).

lmccart commented 5 years ago

For the codebase, I favor the approach @limzykenneth mentioned "use const always and switch to let when reassignment is necessary". I think this is most in line with native ES6 functionality, even if the naming const makes it a little confusing. For the examples, I don't have a strong opinion. I see the argument for both ways. I guess I'd lean slightly think leaving mutable objects as let since it isn't incorrect, and might require less explanation for beginners. But I feel like either approach is reasonable, and we generally allow a little more variation in examples anyway.

hsab commented 5 years ago

It seems like the consensus is in favor of using let only when reassignment is needed and const as the default. I just wanted to point out, again, that since lebab uses the same philosophy, we don't really need to change the codebase as it already takes assignment into consideration.

So perhaps this discussion should be more focused on the usage pertaining to examples?

For the ones that switched to ES6 in src/utilities, I was more generous with let than const, having newcomers in mind. But there were some instances of const used, only to signify that variable shouldn't be reassigned, (e.g. unchanging strings and arrays, or a collection/array of light properties)

Yet, I agree with @stalgiag in that

better to show the correct usage from the start.

lmccart commented 5 years ago

Ok it sounds like we're pretty agreed on keeping things as is for the codebase. Regarding the examples, I wonder if we should deploy as is for now and listen for feedback. I'd be curious to hear if there are any other opinions from people teaching with ES6 @brysonian @saberkhaniscool @shiffman

brysonian commented 5 years ago

I teach similar to what @limzykenneth said, that const should be used by default unless the value needs to change. This then includes arrays and objects. I only mention var in passing, that it is an older syntax that shouldn't be used, so if people encounter code samples that use it they recognize it. Of course var and let are not the same, but there aren't good reasons to use var anymore.

In my experience the clarity of "const by default" is easy enough for new learners and I stress that the difference between the two provides a mechanism for expression in the code which ultimately makes it easier to understand, write, and reason about.

limzykenneth commented 5 years ago

This then includes arrays and objects

Is it possible to teach the concept of assignment/reassignment at the very beginner stage instead of making it seems like constants? This is what I'm personally unsure of since I've never tried teaching this concept from the beginning especially regarding how to introduce this concept of assignment/mutability/value & reference/etc. without overwelming art students (in my context) with a bunch of computer science concepts.

I do like trying const by default in teaching which harks back to Swift's let constants by default.

shiffman commented 5 years ago

For my own coding these days as well as contexts like intermediate JavaScript courses like those that involve node.js and other JS libraries I use exactly this principle:

"use const always and switch to let when reassignment is necessary"

However, for contexts where I am with younger (K-12) audiences or total beginners, I only use let and ignore the existence of const or bring it up towards the end of a foundational curriculum. I have found that multiple ways to declare a variable is confusing / off-putting. Also "const" is not an understandable word so has the downside of feeling very technical.

I don't know the right answer here at all and I recognize there are important concepts and reasons for having const and let. But I feel the distinction is a needless distraction for beginner audiences playing and experimenting.

brysonian commented 5 years ago

@limzykenneth I'm always teaching in an arts context, normally college and grad level and teach both const and let but without CS terminology like mutability and reference. So for example when discussing arrays, I generally use the metaphor of a day-of-the-week pill box. So then we might talk about something like when you declare a const things = [] you are making a new array with the name "things". If i say "put an asprin in grandma's pillbox for wednesday" it doesn't change the box itself, it changes the contents of that part of the box. It wouldn't make sense to then start calling another pillbox "grandma's pillbox" It is a strained metaphor, and strange to type out, but seems to get the point across.

I honestly haven't had students express confusion over const and let. (and they do tend to express it in general so i hope they would bring it up). Using const as "name for a value" has been successful for me, vs let which is more complex.

saberkhan372 commented 5 years ago

I was still using var this past year with middle and high schoolers. I have been reading up on let and const and planning to make the switch for the coming semester. This from @shiffman makes sense to me

I only use let and ignore the existence of const or bring it up towards the end of a foundational curriculum.

stalgiag commented 5 years ago

I agree and feel that exclusively using let with the examples seems the safest.

It seems to me that in order to make sense of the distinction between changing the value and reassigning, one must have an understanding of how different types relate to memory. const requires a learner to understand that changing some values reassigns the container, and changing others does not. It doesn't feel intuitive, without some sense of what a reference is, to understand that a const variable that is multiple Numbers (array) can be changed but if it is a single Number it cannot.

My earlier point about teaching the correct way from the beginning is a nice aspiration but in this case it may undermine the goal to make this accessible for all stages of experience.

lmccart commented 5 years ago

This makes sense to me. We use let exclusively in examples as the lowest barrier for beginners learning JS. While we're not teaching the concept of const, this usage to me still feels more clear than using const only for constants.

LisaMabley commented 5 years ago

Hi. Experienced developer, first-time open source contributor here. I can take this task.

outofambit commented 5 years ago

sounds good @LisaMabley! let us know if you have any questions!

welcome! 🎊

LisaMabley commented 5 years ago

Ok, a little confused already. Are we talking about these reference examples -- which are in a different repo? https://p5js.org/examples/

LisaMabley commented 5 years ago

Or everywhere it says @example?

LisaMabley commented 5 years ago

I'm assuming the above is what needs to be changed, and that (given the conversation above) I should also replace var with let for consistency

outofambit commented 5 years ago

hi @LisaMabley! yes we are talking about everywhere it says @example. (those comment blocks are used to generates the examples on https://p5js.org/examples/, which is indeed a bit confusing).

and yes i would say changing all vars to lets would be great too! feel free to open multiple PRs for this work if that's helpful! (no need to do all of it in one fell swoop.)

HenrySkup commented 5 years ago

Might this prompt a look at aiming to have different "levels" of examples/tutorials?

API : showcase different variables for each function

Beginners : more of an eye of teaching basics/MVP of JS and basic P5 functionality

Intermediate : maybe more elaborate/advanced P5 functionality and use in larger things (classes, flocking might be a good example)

Advanced : more of a focus on performance and P5 interacting with other libraries/hardware (buffers, data structures, other libs, machine learning, shaders)

Key would be that within each "level" that variable declaration, data structures (1D arrays vs. 2D arrays vs classes vs etc.) would be common (as much as is possible).

LisaMabley commented 5 years ago

I changed all the consts and vars I found in the @example blocks to let and updated my outstanding PR. So I'll consider this done until feedback comes my way.

shiffman commented 1 year ago

I know this thread is many many years old, hopefully a comment notification is not disturbing anyone here! I just wanted to pop in and mention that I am working on a p5.js version of The Nature of Code book and am planning to use let only for the examples. I wrote an explanation and referenced this discussion thread which you can see here:

https://github.com/nature-of-code/book-website-2nd-edition/issues/140#issuecomment-1426860500

Any feedback or thoughts there would be welcome!