brownplt / pyret-docs

The documentation for Pyret.
9 stars 18 forks source link

num-trig functions need to specify inputs are in radians #6

Closed kfisler closed 4 years ago

kfisler commented 8 years ago

... rather than degrees. Currently, no input units are specified.

blerner commented 8 years ago

Yes. Very.

I had a thought last night, actually, about these functions: given that the image functions require degrees, but trig functions require and produce radians, what if we defined

data AngleUnit: degree | radian end

As an extra argument to every trig function. Eg, sin(30, degree) is 1/2. Then instead of relying on convention or documentation, students can be explicit and also not have to convert between the two units unless they really need to.

Thoughts?

On Aug 10, 2016 11:15 AM, "Kathi Fisler" notifications@github.com wrote:

... rather than degrees. Currently, no input units are specified.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/brownplt/pyret-docs/issues/6, or mute the thread https://github.com/notifications/unsubscribe-auth/AA4DwODRdTdxb4oEMJ-0YyH-E48QZfilks5qeer7gaJpZM4JhQPs .

shriram commented 8 years ago

I really like Ben's suggestion. For one thing, we're not even consistent (rotate takes angles). Second, I can't remember which one it would take. And finally, it's sometimes really useful to provide one and at other times really useful to provide the other. For instance, when I'm doing trig I think in terms of radians, but when I want to use rotate when drawing a figure, I'm much more likely to want to use degrees.

The best part about Ben's suggestion is that the calls become self-documenting.

All this will make a Pyret-controlled bot much less likely to crash on Mars.

Question: should it be as Ben has specified? What about

data AngleNumber:
  | degrees(n :: Number)
  | radians(n :: Number)
end

so I can call num-sin(radians(PI)) or rotate(s, degrees(45))? I know it looks a bit backwards to write the units outside; on the other hand, functions become single argument as people would expect. On the other other hand, maybe forcing people to confront the units is not a bad thing (you can't blindly say num-sin, you have to say what radians you mean). The advantage to my suggestion is that the number is already wrapped in its units, so I can say, for instance, map over a list of unit-ed numbers, instead of having those live in parallel lists.

How do we decide between these two options? (Are there any others?)

ds26gte commented 8 years ago

Why not just define

degree = (2 * num-asin(1)) / 180

and have people use

num-sin(30 * degree)

Requires nothing more than what we already have, and is no more verbose.

shriram commented 8 years ago

Also, we should do something consistent for other things that take unit-ed numbers…

blerner commented 8 years ago

I picked standalone constants, rather than data values with a field, because trig and images and rotations might easily come up well before we introduce data definitions (e.g. the physics folks, who aren't using data at all). So the constants can be treated like keywords, rather than a new concept.

Using a conversion constant is convenient, mostly, but do I multiply to get into degrees, or divide, or what ...? (It's weird that the definition of degrees is in "radians per degree", and multiplying by degrees produces radians.)

ds26gte commented 8 years ago

A degree is not "radians per degree". It is a certain constant number of radians, indeed, simply, a constant number.

To specify an angle that is x degrees, you multiply x by degree.

To find out how many degrees there are in an angle, you divide by degree.

About the benefits of forcing people to specify what units they use, I can see the point for things like distance, mass, time, current, and composites thereof that don't cancel out dimensions. But for a dimensionless quantity like angle, both physics and mathematics implicitly rely on it being a pure ratio rather than a number of units. When we say C = 2 * pi * r, 2 * pi is a pure dimensionless ratio. Of course 2 * pi is also an angle in radians, and the circumference is the special case of an arc being equal to the subtended angle times the radius. Once we start thinking of allowing a choice of units for this angle that must always be specified, lots of simple formulas, even at the high-school level, become very complicated indeed.

kfisler commented 8 years ago

I'm reading but not saying much here because I don't have a good sense for what kinds of programs people write using the trig functions (my usage which inspired the remark was quite simple). I do agree with Ben's point that users should have to confront Data prematurely -- we will have users who just want to use trig functions as directly as possible.

shriram commented 8 years ago

@schanzer Do you want to weigh in on this? Let's do something harmonious across various "mathy" uses.

blerner commented 8 years ago

@ds26gte of course a degree is not in "radians per degree", but the constant degree is exactly the constant of proportionality between degrees and radians, and is indeed radians-per-degree, a dimensionless number that is only meaningful when converting between the two measurement scales.

The problem with saying "to find out how many degrees there are in an angle, you divide by degree" is twofold: it's asymmetric (why don't you need to divide by radian, for radians?) and it's unintuitive (I don't need to divide by meter to get lengths in meters, unless I'm specifying a length only in reference to some other scale of measurement).

Defining a general-purpose units-of-measure system for Pyret is _way, _way__ beyond the scope of the type system we envision for our language, even if it would be super cool. 8-)

schanzer commented 8 years ago

Okay, so this is a classic tradeoff between "best pedagogy for beginners" and "best pedagogy for non-beginners". For student who are new to programming, I think exposing them to data: early is a total non-starter. Teachers who are nervous about programming to begin with will run for the hills. For them, we need to pick radians or degrees and just go with it.

Of course, for non-beginners, this is just a pain in the ass. We have variants, so let's use them to solve the problem!

At the API level, I'd envision something similar to the way the image library handles colors. For beginners, they're just strings. For non-beginners, they're actually Colors, which must be explicitly declared. Can this be done?

For a teacher who says "I don't want to teach data: blocks, but I do want radians", we can hand-waive and say "well, there's this function called radians that will tag a value and preserve its meaning. That's enough of a fudge to get going in radians quickly, without having to cover too much PL.

That leaves the question of what our simple default is: degrees or radians? I vote degrees, for several reasons:

  1. Radians are introduced later in mathematics, and the only teachers who've ever asked which one rotate takes are HS teachers. We want the simple case to satisfy everyone else.
  2. Consistency with rotates semantics.
  3. As @ds26gte points out, the problem created by degrees also creates a lovely solution, by motivating the need for a "conversion constant" or "conversion function".
  4. Anyone who asks about radians is by definition dealing with older kids, who can deal with the hand-waive answer and may even be able to deal with learning data.
blerner commented 8 years ago

I really don't want to claim "there's this function called radians that will tag a value and preserve its meaning," because that winds up as horrible UX for the return values of functions like asin and atan and such -- how do I pull the value back out of them?

And I'm sorry, but I still am not sold on the motivation for a conversion constant here, because we're picking one scale of measure whose conversion constant is the integer 1, and so creating an asymmetry in the API that gets harder to explain later...and also makes the more mathematically useful version of these functions distinctly harder to use later on.

As to your question about "can we mimic colors-vs-strings in this degrees-vs-radians setting", no, I don't think we can. There's a finite enumeration of colors that we presupport; the same is not true for numbers. (And, frankly, using strings for colors is a lousy API, especially when we have the same-named values, without quotes, as actual proper Colors! But that's a separate discussion...)

shriram commented 8 years ago

I would say the way we handle colors is not exactly exemplary…

blerner commented 7 years ago

Given that we're going to revise the whole color and image library, and make colors be A Thing, as opposed to strings with coincidentally readable names, any further thoughts on this?