Skip to content
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

Variable color elements; Vector defaults #38

Closed

Conversation

ricardomatias
Copy link
Member

Small improvements proposal.

I find myself having to do some copying around to apply changes on a color property/channel.

The defaults on the vectors is just some glsl-like syntactic sugar.

@morisil
Copy link
Contributor

morisil commented Nov 12, 2019

It's a very disputable change. This is how all the initial java structures were designed in the beginning of the language, 20 years ago - as mutable structures. And mutable objects proved to be very error-prone in object oriented design. Joshua Bloch is describing this problem well in Effective Java and defensive programming chapter. See also discussion around the design of original java.util.Date and new time API.

@ricardomatias
Copy link
Member Author

Fair point. Although I'd argue in the context of creative coding and for color usage the downside is limited. Of course, that's just my opinion.

@morisil
Copy link
Contributor

morisil commented Nov 12, 2019

Here is an example of a side effect this change is permitting, it seems useful, but I see it very error prone in bigger projects.

class Particle(
    var position : Vector2,
    var velocity : Vector2
) {
  fun update() {
    position += velocity
  }
}

fun createParticles() {
  val initialPosition = Vector2(10.0, 10.0)
  val particle = Particle(initialPosition, Vector2(1.0, 1.0))
  // ...
  initialPosition.x = 42.0
}

If the last instruction happens when some particles are already updated, it will arbitrary change position only of those which haven't been updated.

@morisil
Copy link
Contributor

morisil commented Nov 12, 2019

I might be wrong, but I believe in GLSL we have slightly different situation, because by default function parameters are passed by value, not by reference. This is reducing the scope of side effects.

@ricardomatias
Copy link
Member Author

The comparison to GLSL was regarding the defaults, f.ex: vec3(0.0) as opposed to declaring it 3 times vec3(0.0, 0.0, 0.0).

@morisil I do think immutability does bring something to the table and Kotlin considers it a first class citizen in its data structures. Although, in this scenario it's not the common practice. Processing's PVector allows changing xyz just as C++/Openframeworks glm library.

@edwinRNDR
Copy link
Member

What @morisil brings up are exactly the reasons for choosing immutable types for Vector, Matrix and Color values. Immutability has made OPENRNDR's implementation easier to write because we just don't have to worry about an entire category of problems anymore (the one in which you have to worry about copying values to prevent unwanted state mutations). I personally do think that has a place in creative coding as it saves time chasing down problems for which the search and solutions are intellectually not rewarding.

But I also understand where @ricardomatias comes from. Immutability admittedly comes with a mental overhead and additional work for the user (and I have found it hard to explain to those not familiar with immutability). I am opposed to dropping immutability but I am all in favor for making tools that make things easier.

@ricardomatias
Copy link
Member Author

ricardomatias commented Nov 13, 2019

@edwinRNDR, @morisil Fair enough. What about making use of the infix syntax and have something like this:

val pink = ColorRGBa.PINK
val hollowPink = pink change ("a" to 0.2)

var pos = Vector3(20.0)
pos = pos change ("x" to 100.0)

Just to be clear the return of the change function would be a new instance of the Class.

@edwinRNDR
Copy link
Member

Note that there is the Kotlin-idiomatic.copy

val hollowPink  = pink.copy(a = 0.2)

Potentially one could implement the invoke operator to produce code that reads like

val hollowPink = pink(a = 0.2) 

* Add default one parameter initialization to vector classes
@ricardomatias
Copy link
Member Author

ricardomatias commented Nov 18, 2019

@edwinRNDR I've updated the code to reflect your comments:

val foo = Vector4(0.1)
// Vector4(x=0.1, y=0.1, z=0.1, w=0.1)

val bar = foo(y = 0.8, z = 2.0)
// Vector4(x=0.1, y=0.8, z=2.0, w=0.1)

I've changed the defaults to a secondary constructor, because that's the actual glsl behavior.

@ricardomatias
Copy link
Member Author

Changes already incorporated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants