-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Style guide questions #6607
Comments
|
Simple iteration for (let mover of movers) {
mover.update();
mover.render();
} movers.forEach((mover) => {
mover.update();
mover.render();
}); Using an index for (let i = 0; i < movers.length; i += 1) {
let x = i * 10;
let y = 20 * sin(x * 0.01) + 200;
movers[i].pos(x, y);
movers[i].update();
movers[i].render();
} movers.forEach((mover, i) => {
let x = i * 10;
let y = 20 * sin(x * 0.01) + 200;
mover.pos(x, y);
mover.update();
mover.render();
}); Updating for (let i = 0; i < sizes.length; i += 1) {
sizes[i] += 1;
} sizes = sizes.map((size) => size + 1); Everyone's learning path is different, but it's probably safe to assume that someone programming with arrays could pick up All that said, it seems like @calebfoss suggested a more general principle of using syntax with the fewest prerequisites (please feel free to correct me). @katlich112358 @dkessner @MsQCompSci @limzykenneth @davepagurek @Qianqianye what do y'all think about array methods? Are there any other opportunities to simplify the the code style guide? |
The point about having the index is interesting. With a On the other hand, |
I don't have a super strong opinion on this one, both One minor bit to add to the discussion: I'm not sure about everyone else, but even though I know the difference between |
Thank you for the discussion! I appreciate y'all taking the time. I wanted to clarify a couple things. I personally really like using array methods and find them quite readable if written well, but speaking as an instructor these are the aspects of using array method that would present obstacles for my students:
My students would have already learned about for loops, so that syntax structure would be familiar. Honestly, if the p5 code examples use array methods, as an instructor, I would most likely show my students a modified version that uses the tools they've already learned. I wrote a little add-on with a Python-esque range function to help students with numerical iteration. It could also be used for updating array values, since for... of doesn't allow for that: for(let index of range(sizes.length)) {
sizes[index] += 1;
} I was thinking about proposing that function for the base p5 library, but I'll put that in a new thread. A big benefit is that infinite loops are impossible, which is a huge plus for beginners. @davepagurek Good point about the "in" vs "of" confusion. That is a notable downside. @limzykenneth Good point about break, continue, and await. One annoying thing about iterating over the entries method is that the indices are strings. It's not a huge issue, but something that caught me off guard that I wanted to mention. Hearing the pros and cons for different options makes me wonder - maybe the style guide could include multiple and suggest different ways of iterating for different situations? Using only array methods would be more consistent, and if we're sticking with that, I'll make sure all the relevant examples use them. Again, I would just work around that when I'm teaching. |
Also just to contradict myself a bit and confuse things - the same thing I said about => being a new symbol would be true about the keyword "of". My opinion is that using "of" is much simpler to learn, and the syntax involved is much simpler. As an English speaker, though, I'm biased towards English keywords over abstract symbols. |
A more verbose approach that would avoid arrow functions would be: function addOne(size, index) {
sizes[index] = size + 1;
}
sizes.forEach(addOne); |
function addOne(size, index) {
sizes[index] = size + 1;
}
sizes.forEach(addOne); Just a quick note that this style is also what I see Dan Shiffman do in the beginner oriented videos for Coding Train, albeit for event handlers, so it's not out of the question. |
Since it doesn't look like this goes against the style guide as-is, I'm thinking this would be a good format to use in the examples. We have already examples with named functions being passed into DOM element event methods, so this would be more familiar. If anyone sees any issues with that, please let me know. If not, it might be worth including this style in the style guide as an alternative. |
I think this is OK as long as we keep the function and its use side-by-side like in these snippets so that people can still read the code linearly without jumping around too much, as opposed to placing them next to globals like |
For me it is still a bit hard to decide which to go for. In everyday coding I instinctively use One thing to note also is that we might do some edits to the style guide later on to clarify differences between example code and p5.js source code style, ie. example code style are designed to be consistent, simple, and beginner friendly; while the p5.js source code style may have more in the ways of case by case analysis, small tricks, and optimizations when necessary. One example is Forgot to add, sizes.forEach(function(size){
size = size + 1;
}); is also possible if the desire is to avoid arrow syntax, as long as this loop is not used in object methods. |
That's a great idea to distinguish between examples and source code. For examples, I think beginners would find it easier to read with the function declared outside the method call, which is why I wrote it that way, even though I'd personally never write code that way. In my experience, the more nested parentheses and braces, the more students/beginners get stuck on syntax issues that hold them back from doing what they want. |
I think that's the essential point. Arrow functions are dope, but they're definitely an intermediate concept with enough nuance to trip people up. I also agree that most beginners and their instructors are more comfortable with some variation of a What do y'all think about the following? Array iteration // Updating.
for (let i = 0; i < sizes.length; i += 1) {
sizes[i] += 1;
} // Not updating.
for (let size of sizes) {
circle(200, 200, size);
} Callbacks // Bad.
button.mouseClicked(() => {
thingOne();
thingTwo();
});
// Good.
button.mouseClicked(handleClick);
function handleClick() {
thingOne();
thingTwo();
} |
@nickmcintyre I'm in favor of that of course. I must admit that I went into this discussion only thinking about documentation and not source code. I don't see any issues with using arrow functions passed into array methods in source code. The only one I might be cautious of is reduce, which can become super confusing to read if not written carefully. If we're sticking with one style guide for both source code and documentation though (at least for now), what you have there looks great to me. |
Oops. To clarify, my style suggestions are focused on documentation. I don't actively contribute to the p5.js source code (yet), so I don't really have an opinion there. There's probably an upside to adhering to something standard-ish such as Airbnb for most situations. |
Great discussion! Somehow I missed this issue but found it when @nickmcintyre mentioned it in #6527. I think there's a case to be made for using only traditional Reasons to use
|
I think that there should be different style guidelines for source code vs. examples. Examples should use the most simple and beginner-friendly code, while the library source can use more "cutting edge" stuff.
Of those two I have a strong preference for
I very rarely use
I agree that the difference between |
I disagree with this rule in the current documentation style guide. Since we are aiming for clarity and beginner-friendliness, I think that the explicit For the record, we use the unnecessary |
I really appreciate this discussion! It's great to see a range of perspectives all working to make our documentation that uses iteration more accessible. This a great reminder that there is no universal concept of what is beginner-friendly. As @nickmcintyre said early on
To be a bit more open about the origins of my position, let me write a bit about my own learning path: One of my first introductions to code was JS expressions in After Effects. I then moved on to JS for Unity (back when that was a thing), Processing, and Arduino as my first environments for writing programs. By the time I started using Python, the way it handled iteration confused me. I was so used to a 3 statement for loop, I didn't understand why that was no longer an option. From Processing Python reference loadPixels()
for i in range((width*height/2)-width/2):
pixels[i] = pink
updatePixels() Now reflecting years later, I wished I had first learned to iterate using the Python structure. I find the syntax quite a bit simpler, but more importantly, it removes the risk of infinite loops. I could have had such an easier time experimenting and making mistakes with less severe consequences. The only reason Python's way of iterating seemed strange and confusing was that I had learned a 3 statement for loop first. Part of my point here is that I want to question the idea that a 3 statement for loop is the most basic approach. It opens up the risk of infinite loops, and it squeezes 3 statements into 1 line. It feels basic to me personally because I learned it first, but as an educator, I think of it as a hurdle of abstraction and syntax that I need to guide students over to get to the fun creative part and in no way basic. With all that being said, I've opened issue #6644 for adding a range function that would allow a consistent way for handle numerical iteration and iteration over arrays without the risk of infinite loops. |
Thanks @calebfoss! I appreciate all the work and thought you've put into this. These are the kinds of discussions that make p5.js great. To clarify the case I was making, I agree that It sounds like you're proposing we use The users who are introduced to loops for the first time with p5's special In general, I feel that p5.js is about opening doors and making creative coding easier in JavaScript, rather than making the underlying JavaScript language easier to work with.1 Part of the reason is that JavaScript itself opens a lot of doors. Modifying fundamental language usage also feels out of scope and carries certain risks. Avoiding infinite loops is an interesting point. This seems like less of an issue with Footnotes
|
The case where I normally end up with an infinite loop using only for loops is if I copy-and-paste a for (let x = 0; x < 100; x++) {
for (let y = 0; y < 100; x++) { // Notice it's still x++ here
// ...
}
} Since I accidentally never modify |
@GregStanton To contextualize, I teach p5 with university students, many of whom have never written code before. Infinite loops are a very common problem when they are first working with loops. In the p5 editor, it's pretty easy to leave the auto-refresh button on and end up with it running a loop that hasn't been written out completely. I've had the same thing happen in Glitch's live preview window. I make a point of warning students about this in class and in resources I share with them, but inevitably a couple students miss that and sometimes even lose unsaved progress. I'm under the impression that many p5 users are using the tool to write code for the first time, given its emphasis on beginner-friendliness and use in introductory coding education. It would surprise me if three-statement for loops were a nearly universal experience for folks starting out with p5. I hear you on not wanting to modify the language. I would just clarify that I'm not proposing modifying the language. For...of loops are a core feature of JavaScript. The range() function I'm proposing is simply a more beginner-friendly way to create an iterator. Similarly, you could write out the arithmetic for linear interpolation in vanilla JS, but the lerp() function makes the process more beginner friendly. I don't necessarily think our documentation needs to stick with one single structure for iteration, but since I'm hearing that syntax that feels new is less beginner friendly (and that's a big part of my concern about array methods with arrow functions), I'm offering that if we want one consistent way to handle most cases of iteration in our documentation, this would be an option. |
Thanks @calebfoss. I hope I'm not being too disagreeable! The approach you proposed is pretty sweet, I think. I'm sort of playing devil's advocate in order to hash out the trade-offs. To be clear, I'm not saying everyone who starts learning p5 has already seen I get that I guess we can wait to see whether others prefer |
@GregStanton I think you're bringing up valid points worth considering and not being too disagreeable. Likewise, I hope I'm not coming off stubborn. I want to make a case for my suggestion, but I don't mean to invalidate other options. I'm actually not sure how I feel about the idea of always using |
Yeah, it would definitely be a nice utility regardless of whether it's what we use in the documentation, and a lot of my sketches have a version of a So it seems like there are two scenarios we could encounter in the docs: (1) iterations over lists, and (2) iterations that are not backed by data. The |
I think so.
I proposed sticking to |
Topic
As we're working on example revisions, I had a few questions about the code style guide.
Tagging @nickmcintyre and @raclim for thoughts
The text was updated successfully, but these errors were encountered: