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.67k stars 3.33k forks source link

paperjs style operator overloading #1497

Closed ofZach closed 8 years ago

ofZach commented 8 years ago

Paperjs has a really nice and elegant system for bringing operator overloading to the point object via some nifty pre-processing (you write "paperscript" which is turned into javascript).

This allow you to do stuff like this: http://paperjs.org/reference/point/#add

I find this to be super helpful, especially when doing animation and physics and for folks who are coming to javascript from another language. The downside to this is it adds a layer of "parsing" and maybe isn't as pure or idiomatic javascript.

Anyway, I was just discussing this with @shiffman and he suggested to open an issue for discussion here to see if this approach is relevant / helpful to p5.js.

ping @lehni

lehni commented 8 years ago

@ofZach @shiffman good to hear this is appreciated!

We've added PaperScript to Paper.js exactly for the reason of teachability of math when working with graphics, since vector algebra, vector geometry and vector graphics go hand in hand in beautiful ways.

But it does come at a cost, as you pointed out already. JS purists frown upon it, mostly. It adds a layer of confusion too sometimes, when people see scripts on our site and expect them to work directly in JS. And there is definitely a performance impact that is measurable. But the impact is actually surprisingly low on modern browsers in most scenarios. It also might still break some not so conventional code statements, but that would be a bug in PaperScript that could be fixed.

Another "issue" is that PaperScript expects the underlying math methods to not modify the object itself but return copies instead, so they can be chained. I think p5.Vector goes the other way, and each method modifies the instance. I see why this was chosen for reasons of performance (garbage collectors probably hate the paper.js way), but I find it quite hard to write meaningful and readable vector algebra with p5.Vector, with or without operator overloading, because each statement ends up on its own line, and one needs to make copies of vectors quite often to not accidentally modify a value that I want to use further down again...

A while back I wrote a little text about how we achieve operator overloading, as I thought it may be useful to others: http://scratchdisk.com/posts/operator-overloading

Please note that in the meantime, there has been more work on PaperScript, and I haven't found the time to update the above article yet. The latest version resides here: https://github.com/paperjs/paper.js/blob/develop/src/core/PaperScript.js

I would still like to create a separate module out of this, and offer server-sided transpilation, source-maps and better debugging.

If the p5.js folks are interested in this, then perhaps such a module could come out of a shared effort?

lmccart commented 8 years ago

Thanks @ofZach, I'm so excited to hear you're trying out p5, and I appreciate the feedback and suggestion! and thanks @lehni for the detailed overview of what's happening here. It makes sense what you're saying, and the fact that a lot of people may be coming from different languages is a big consideration for this project.

I do have two concerns, which are the two that @lehni mentions performance -- which is less of concern as we are aiming for usability over high speed generally, and the larger one -- layer of obfuscation / confusion. We have generally stayed away from doing too much "magic" behind the scenes, even at the cost of performance sometimes. There are two reasons for this.

First, we want to play nicely with the rest of JS and make the transition out of p5.js as easy as can be. p5 is a really good library for bringing a lot of different pieces together, but sometimes you need more specialized libraries for more advanced, powerful, or specific purposes. At this point, we hope that people are able to pick up another library and have a basic understanding of JS, and not feel like everything works differently. Sometimes you may even want to use two different libs together, in which case you really want the patterns of JS to hold steady.

Second, I really believe that it's important to have as many people as possible feel able to not just use the tool but to develop as well. My hope is that even a beginner programmer could feel able to contribute some lines of code of they wanted. So we've made a lot of design decisions that maintain the comprehensibility of the code. The more layers we have behind the scenes, the trickier it can get for someone new to wrap their heads around what's going on.

(You can see an overview of design goals here: https://github.com/processing/p5.js/wiki/Design-Principles)

I'd love to hear other perspectives if others feel differently. Maybe @shiffman has a better read on this, having done more physics related work?

Alternatively, would it be possible to make something like an addon library that bolsters p5 objects with this functionality? Maybe this is actually what @lehni is suggesting. In this case, I'd be really excited about this idea, because people would know they were adding on some feature rather than expecting it to be in native JS, and the core development wouldn't need to account for it. Is this a possibility?

lehni commented 8 years ago

Thanks @lmccart for the detailed response. This all makes sense. I realized that I should have explained a few more bits:

But yes, I would recommend that if you decided to add something like this to p5.js, you should keep it optional, not something that's always on. You could still add it to the core, since you'd naturally hide it behind a feature. The way it works in Paper.js is that you declare / load the script in different ways:

<script type="text/paperscript" canvas="myCanvas">
...
</script>

Instead of:

<script type="text/javascript">
paper.setup('myCanvas');
...
</script>

So you could declare your own script type, e.g. "text/p5script", and add whatever magic you like to it, through JS to AST translation, and some added code-mingling based on the AST information. In Paper.js we use an embedded version of the nicely small Acorn.js to do so. At version v0.5.0 (before ES6 support) this only adds about 25kb to the final file size.

lehni commented 8 years ago

PS: By changing the original code directly through string operations, we eliminate the need to translate modified AST back to JS, which simplifies things a lot. It also allows os to keep original code comments and line offsets intact in the resulting JS code, which means debugging PaperScript almost is the same as debugging JavaScript. And a while ago we've added support for dynamically generated source-maps, allowing you to see the original PaperScript code in the debugger of all modern browsers instead of the product of the mentioned code modifications.

shiffman commented 8 years ago

Love the idea of operator overloading! I am so used to teaching all the vector stuff without it since this is how it works in Processing/Java as well that I can barely imagine this possibility.

I agree that the idea of p5 add-on that allows operator overloading for p5.Vector objects is a good way to start out. This can be an optional feature for certain workshop/tutorial contexts. If someone wants to take this on as a project, I would be game to make versions of the nature of code physics simulation examples that work with the overloading. But that's really the question here -- who can work on this and how much of a priority it is. I think we leave this open and anyone who wants to try out developing an add-on to implement this I say go for it and I would be glad to help test!

lmccart commented 8 years ago

👍

lmccart commented 8 years ago

I'm going to close this since it's not an issue or feature request for the core library, but it's a very interesting idea and if anyone is interested in tackling this as an addon I'd be happy to chat about it.

sarahghp commented 8 years ago

I might be ... in January. But I keep thinking about it.

On Thu, Sep 15, 2016 at 2:32 PM Lauren McCarthy notifications@github.com wrote:

I'm going to close this since it's not an issue or feature request for the core library, but it's a very interesting idea and if anyone is interested in tackling this as an addon I'd be happy to chat about it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/processing/p5.js/issues/1497#issuecomment-247412188, or mute the thread https://github.com/notifications/unsubscribe-auth/ABaK8q_AmZCWoBMpc99S3TktAxocmwweks5qqY9RgaJpZM4JDWU9 .