-
Notifications
You must be signed in to change notification settings - Fork 26
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
Potential breaking changes for elm-geometry 1.0 #22
Comments
Hey Ian, dropping a bunch of thoughts on those points that I have an opinion on. Hoping they’ll be helpful!
This makes a ton of sense! As well as being in line with the patterns emerging within the community as you pointed out, it’ll also make it work more smoothly with tooling like atom-elmjutsu (and possibly other tools that were designed in line with the community standard).
In my own code, I almost always use the myAxis
|> Axis2d.direction
|> Direction2d.toAngle
Direction2d.toAngle myDirection The convention works well for converting one value to another, but not for extracting a smaller part of a value. For example,
Oh man, that makes a ton of sense! Goes totally in line with the point I made above about converting values. Just curious, when moving away from a Circle.fromCenterAndRadius { center = center, radius = radius } Or take advantage of the descriptive naming to make the API more lightweight? Circle.fromCenterAndRadius center radius
Sounds super sensible 👍 👍 👍 |
Thanks for the comments Tomek! For the module renaming, one of the tricks is what to do with some of the more generic module names that are more likely to cause conflicts...I just edited the description to expand on this a bit, but here's the relevant text:
I hadn't thought at all about the impact on editor autocomplete etc., that's a really good point! (I tend to just use Sublime myself with a very minimal set of plugins, pretty much just syntax highlighting and As for making some of the Arc3d.around Axis3d.z
{ startPoint =
Point3d.fromCoordinates ( 1, 1, 0 )
, sweptAngle = degrees 90
} It could be that things like EllipticalArc2d.fromEndpoints startPoint endPoint
{ xDirection = Direction2d.x
, xRadius = 2
, yRadius = 1
, sweptAngle = EllipticalArc2d.smallPositive
} Making things more lightweight is good but I don't want to give up too much clarity/explicitness to get there!
For what it's worth, I've already tried to avoid function names like Frame3d.at : Point3d -> Frame3d to conveniently create a |
Yeah, the lighter weight of the API is one thing, pipeline friendliness is another that I thought speaks towards conventional function arguments and against records. The other thing I was thinking of was pipeline-friendliness. 😄 But you’re totally right – while using OpenSolid I can’t remember bumping into a situation where I was building a pipeline and stumbled upon a
I like the look of it! Judging by the list of
By the way, of course my sample had a typo in there. It read myAxis
|> Axis2d.direction
|> Direction2d.angle while what I meant is of course |> Direction2d.toAngle Corrected already, apologies for any confusion! |
Yeah, good idea. I don’t have enough knowledge to be more helpful than pointing out that renaming every module on export feels a bit “non-native” to me. I only know the Elm module system as a consumer of packages – don’t know the internals of how they work, how conflicts are resolved etc. I also never used Haskell seriously, and it does seem like Elm’s handling of imports is modeled after Haskell’s. One observation that might be worth bringing into the discussion: despite the general community push towards generic, descriptive, top-level modules, elm-community/linear-algebra exports everything as second level modules grouped under the |
No worries, I think I just interpreted it as an example of the current naming looking weird =)
Yeah, probably - might just be the ellipse/elliptical arc constructors. I think there would be a couple cases that would stay as a single record argument even after a rename, though - e.g. without a record I don't see any good way to make it clear in what order you would pass the four arguments to I've posted a topic asking about the module prefixes: https://discourse.elm-lang.org/t/removing-prefixes-from-module-names/523 |
Regarding module names, why not make all the modules a sub-module of "Geometry"? So have Geometry.Point2d, Geometry.Scalar etc. After all, this is a geometry package ;) |
I actually am using a version of that right now =) I think that For |
Hey all - 3.0 a.k.a. |
Closed now that 1.0 has been released - relevant bits moved to #56. |
This is a meta-issue for potential breaking changes to make for an
elm-geometry
1.0 version. Feel free to post suggestions in the comments and I'll edit this issue text.Module naming
I used prefixed module names like
OpenSolid.Point2d
to avoid potential naming conflicts with modules from other packages, but based on elm/compiler#1625 it seems that this might be considered "silly module renaming". Should the prefixes be removed? I think they should remain in a few cases likeOpenSolid.Geometry.Decode
, but otherwise module names could be switched to just plainPoint2d
,Triangle2d
etc. What about theScalar
andInterval
modules? Those are fairly generic names, so might benefit from staying asOpenSolid.Scalar
andOpenSolid.Interval
...but then that feels a bit inconsistent/arbitrary. Rename toScalar1d
andInterval1d
and just lay claim to all module names ending in1d
,2d
or3d
?Switching to non-prefixed names would be more consistent with other Elm packages -
elm-community/elm-test
uses top-levelExpect
,Fuzz
andTest
modules,mdgriffith/style-elements
uses top-levelStyle
andElement
modules,terezka/elm-plot
uses a top-levelPlot
module, etc.Additionally, if the non-prefixed names don't work out and run into conflicts with other packages, then these conflicts will provide additional data points for elm/compiler#1625.
Package split
This is tracked in a separate issue, but splitting this package into two smaller packages would certainly be a major version change (although it shouldn't actually require any code changes, just modifications to dependencies in
elm-package.json
).Moves/renames
SweptAngle
as its own module now thatArc2d
andEllipticalArc2d
both use the same concept (currently just two independent but identicalArc2d.SweptAngle
andEllipticalArc2d.SweptAngle
types). This would likely mean adding anInternal.SweptAngle
type and just exposingSweptAngle.smallPositive
etc.; theArc2d
andEllipticalArc2d
modules could then pattern-match on theInternal.SweptAngle
constructors. (Directly referring to stuff likeSweptAngle.SmallPositive
feels a bit weird, and I can't think of any cases where it would be useful for end-user code to pattern-match onSweptAngle
values.) On the other hand, if theOpenSolid
prefix is removed, then it might not make sense to have a top-levelSweptAngle
module (unlikely to conflict with modules from other packages, but a little less obvious what package it comes from than something likePoint3d
).Direction2d.toAngle
instead ofDirection2d.angle
.angle
is consistent with other functions likecomponents
andcoordinates
in that it treats the returned angle as a property of the direction ("the angle of the direction") instead of an alternate representation ("the direction converted to an angle"); I wouldn't want to havePoint2d.toTuple
orPoint2d.toCoordinates
, for example, but somehowDirection2d.toAngle
feels more natural thanDirection2d.angle
. Similarly shouldSketchPlane3d.plane
beSketchPlane3d.toPlane
? Does it make more sense to talk about "the plane of a sketch plane" or "converting a sketch plane to a plane"?with
functions to have more descriptive names. In some cases likeAxis#d.fromOriginAndDirection
this might also imply switching from a single record argument to multiple 'plain' arguments. Possible renames:Frame2d.with
toFrame2d.fromOriginAndXDirection
(and addFrame2d.fromOriginAndYDirection
)Frame3d.with
toFrame3d.fromOriginAndZDirection
(and addFrame3d.fromOriginAndXDirection
,Frame3d.fromOriginAndYDirection
)Vector#d.with
toVector#d.fromLengthAndDirection
BoundingBox#d.with
toBoundingBox#d.fromExtrema
Interval.with
toInterval.fromExtrema
Axis#d.with
toAxis#d.fromOriginAndDirection
Plane3d.with
toPlane3d.fromPointAndNormal
Arc2d.with
toArc2d.fromCenterAndStart
Circle#d.with
toCircle#d.fromCenterAndRadius
(althoughCircle3d
also requires anaxialDirection
parameter...)Sphere3d.with
toSphere3d.fromCenterAndRadius
Direction3d.with
toDirection3d.fromSphericalAngles
Ellipse2d.with
toEllipse2d.fromCenter
, or perhaps change toEllipse2d.centeredOn : Frame2d -> { xRadius : Float, yRadius : Float } -> Ellipse2d
EllipticalArc2d.with
toEllipticalArc2d.fromCenter
, or perhaps change toEllipticalArc2d.centeredOn : Frame2d -> { xRadius : Float, yRadius : Float, startAngle : Float, endAngle : Float } -> EllipticalArc2d
SketchPlane3d.with
toSketchPlane3d.fromPointAndNormal
Rectangle2d.with
toRectangle2d.axisAligned
Switch from
Maybe
toResult
Currently there are several constructor/factory functions such as
Arc2d.fromEndpoints
that returnMaybe
values if construction fails (invalid arguments given, no solution found, etc.). Ideally many of these should be switched to returnResult
values instead with a custom error type that indicates the failure reason; for example, @folkertdev's proposal forEllipticalArc2d.fromEndpoints
:One possible modification: change the
NoSolution
case to actually include the 'best approximation' elliptical arc with X and Y radius scaled to make arc construction possible. This way attempting to construct an ellipse with invalid/impossible radii is anErr
, but the user can explicitly choose to fall back to the scaled ellipse if they want (which is what browser SVG engines do, since that's what's mandated by the SVG spec).The text was updated successfully, but these errors were encountered: