-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
V11 with typed-function@3 #2560
Conversation
@gwhitney this looks very good 😎 . You've done a lot of tiny little improvements, to many to list them all here, thanks! Some small remarks:
|
Thanks for the excellent feedback. I am now on a post-finals trip to some national parks and so will only be able to get to this a bit until next week. |
On 1, createCompareUnit and createTrigUnit do not construct any typed function, just a plain object with a key which is the respective Unit signature, which is then incorporated as one signature of various typed functions in the respective category. I don't see any way to further optimize this but if you have an idea how please justcley me know. |
On 2-4 I will certainly do as requested as soon as I can get to it. Responding to 5-6 will have to wait until I have more time to focus on this. And 7 I don't think there's any action item on my part, sounds good. |
👍 enjoy |
Ahh, now I see. You're right, there is nothing to optimize there, my fault. |
b14bb92
to
eaa85e2
Compare
OK, have rebased this branch on develop with all of its changes to the typescript stuff, will look at items (5) and (6) and implement whatever's needed as soon as I can. |
Thanks 😎 . Was it difficult to get the branch up to date again? |
@gwhitney is this PR still on your radar? |
Absolutely! Have just been trying to get through an onslaught of other responsibilities. Should get back to this soon. |
👍 no problem, take it easy. Just wanted to make sure we don't forget about it. |
@gwhitney do you expect to have time to finish this PR on short term? If not, I will see if I can finish it up next week (shouldn't be too much work, you took care of about everything). |
I do think I can get to it next week. That is my plan. I am working right now on a change to the "inkscape-silhouette" package that I promised them long ago I would do when they changed the name of the primary branch away from "master" and they have finally done that so I feel owe them. As soon as that's done, it's back to mathjs. |
That is good news, thanks for the update! Take it easy. |
OK, back to being (re)based on develop. I will see if I can stay afloat this time! |
On review item (3): renaming valType => valueType. But there are already numerous tests of it in test/unit-tests/type/unit/Unit.test.js. |
Review item (6) was not really an action item but a question for me. The point of the comment in src/utils/is.js that "I don't understand the Node class hierarchy" is that it shouldn't be necessary to have the special case for isNode; all of the different Node types (are/ought to be) "official" JavaScript classes and as such, there should be a way to compute their types "for free" without relying on some property that we set up, i.e., based on the name of their constructor. And if they were all defined with current class syntax, I think that would be the case. But they are defined with an older pattern that I am not familiar with, and it seems like the constructor name is just "Node" for all the types. So rather than trying to figure out a "direct" way to extract the type, I fell back to running the isNode() test and then using the particular data item that the hierarchy set up. But for performance I had wanted to minimize the number of cases and tests that were run on all objects, and maximize the situations in which the type can just be directly extracted. But I punted on that for the Node hierarchy, potentially slowing things down for other types, hence the comment. |
Ok that just leaves review item 5, definitely the most complicated of all of them. I will attack tomorrow. |
One question on name mangling though: did you try your test on the code in this branch? I added a number of constructs like
that supposedly should disallow such name mangling. They seem to work for me but I agree if they are not reliable we shouldn't use that property. So it would be good to know, if you have a chance to check. Thanks. |
As I mentioned in my last question, I believe that I have added code to prevent such name mangling, and I believe it is properly tested by the generated/node tests.
Well, most of the uses of typeOf are for messaging purposes, where I think doing "something" on non-mathjs types is completely positive. The next biggest use is for function dispatch on Units (the motivation for the rewrite), where we control the types that go in in the first place, so I don't see a worry. Then there's a similar use in the matrix classes, also not a concern. It's used "directly" in the
This is admittedly not ideal. Actually the Node-family tests currently only rely on the Node classes keeping the ".type" property in line with the .isXxxNode properties, which presumably they do. And the other .isBlahblah tests could be changed to run through typeOf, or left alone; happy to hear your thoughts. Whether or note we change implementations to be more consistent, we do have tests of all of the .isBlahblah predicates and that typeOf returns the expected thing on an example instance of each entity, so any discrepancies are likely to be caught... so I am willing to live with this if you are, either with doing what's feasible to align implementations or not. Let me know what you'd like.
Basically, I think my analysis of the point about returning "something" addresses this, too. Yes, a foreign class could spoof any mathjs type, but that was already true with the old typeOf, and none of the uses of typeOf make such spoofing seem particularly harmful.
Well, it was the only non-object case where typeOf didn't match typeof, which seemed counterintuitive, and it was not much entrenched, so seems worth changing for consistency. OK, just let me know what remaining action items you have for me based on your review, and let's get this merged :) |
Good to have you back, thanks for the updates :) (1) about constructor.name Ahh, now I see what you did, by setting
Thanks. I think you're right and we do not need to worry. Ok let's go for the new (2) about Node class hierarchy About the node class hierarchy: now I understand the confusion. The if (isSymbolNode(x)) return 'SymbolNode'
if (isOperatorNode(x)) return 'OperatorNode'
... It's just utilizing the fact that if a class instance is a Node, then we know that it has a With your new approach, I think the line (3) about inconsistency between say isSymbolNode and typeOf: I think we do not need to worry too much here, this code isn't changed often and is well unit tested. I like the idea of letting the (4) last action points:
|
Thanks for the feedback!
|
|
I know you found my response to (1) humorous, but really, I am very confused with all the prototypes floating around in the Node class hierarchy and explicitly setting the prototypes and the properties on them. Is there a reason mathjs can't use current class definition syntax? Is it OK if I try? |
Sorry. I think that I didn't fully understand you. The "by hand" class definition with a function constructor and then methods and props under |
Maybe this article helps (it's no magic, you just have to know the notation): https://medium.com/@parsyval/javascript-prototype-vs-class-a7015d5473b |
Yeah, well, I did warn you. Despite numerous tries, I couldn't figure out where/how to assign properties in the derived Node classes to get the "standard" typeOf implementation to produce the correct result, so I just went ahead and converted to class syntax and as expected typeOf() then works perfectly on all of the Node classes. It makes the diff in the latest commit huge though, I am afraid. As for testing, it turns out that it's the doc test on the documentation of the typeOf function that was checking a lot of cases (hurray for doc testing) so I just went ahead and extended that documentation page to include all of the relevant types. And note |
…value E.g. `math.unit('5cm').valType()` returns `number`. Also uses this for an internal method that directly gives the number converter for a Unit. Also fixes lint errors from previous commit (not clean, I know, I forgot that build-and-test does not run lint). Adds tests for unit.valType()
There is no mathematical meaning to a hyperbolic function operating on an angle (the proper units of its argument is actually area), and it eliminates a number of uses of `this`, so remove such arguments.
Mostly this involves replaceing instances of 'this' with used of (preferably) typed.referTo() or typed.referToSelf(). Some repeated batterns of boilerpolate signatures within different divisions of functions (bitwise, relational, trigonometry) were factored out into their own files and reused in several of the individual functions.
Also had to deal with new typing for `resolve()` in that it now accepts strings and Matrices; added tests for the new possibilities for `resolve()`, and eliminated empty comments from the Node representation of parsed strings as they can't really be doing anyone any good and they are a pain for testing. Also updates the TypeScript declarations and tests for `resolve()`
Also removes 'resolve' from the known failing doc tests, now that it handles strings.
This change simplifies the typeOf() function, because now all subclasses of Node have the expected constructor name. Also, reformats the documentation of the typeOf() function so that the doc test of that function will serve as an exhaustive test that the bundle returns the proper types.
OK, fortunately the rebase had no conflicts and it is force-pushed and passes all tests. Speaking of tests, has mathjs dropped Node 12 support? If so, I see in the commit history of this PR that at some point we switched Thanks for letting me know. If not, I hope this can be merged, it's been quite the saga (sorry that several of my other projects and the end of the semester really dragged it out). |
Oops I see we have not yet merged the no breaking chain parameters PR into this one yet. I guess there is one remaining review comment in #2559. I will rebase that PR and address that comment. Definitely want to get this done with. |
OK, #2559 is back in good shape and should be merged here before this is merged into develop. Other than the question of implementing #2617 (which I am personally against) I believe everything is ready for merge into develop and release of v11. If you need help writing a release notes to facilitate that -- this is definitely the most major change in a while -- just let me know and I am happy to help. |
…ter (#2559) * chore: Prevent confusion with standard matrix functions. (#2465) * chore: Prevent consfusion with standard matrix functions. Prior to this commit, many functions operated elementwise on matrices even though in standard mathematical usage they have a different meaning on square matrices. Since the elementwise operation is easily recoverable using `math.map`, this commit removes the elementwise operation on arrays and matrices from these functions. Affected functions include all trigonometric functions, exp, log, gamma, square, sqrt, cube, and cbrt. Resolves #2440. * chore(typescript): Revise usages in light of changes sqrt() is now correctly typed as `number | Complex` and so must be explicitly cast to number when called on a positive and used where a Complex is disallowed; sqrt() no longer applies to matrices at all. * feat: Provide better error messages for v10 -> v11 transition Uses new `typed.onMismatch` handler so that matrix calls that used to work will suggest a replacement. * fix: prevent chain from matching rest parameter with stored value Since the revised code needs the isTypedFunction predicate, switch to using the typed-function implementation for that throughout mathjs, rather than rolling our own here. Also adds a test that chain() no longer allows this kind of usage. Removes the two type declarations in types/index.d.ts that were allowing this sort of "split rest" call and added tests that such calls are forbidden. Adds to the chaining documentation page that such "split" calls are not allowed. * chore: Refresh this PR to reflect underlying changes Also addresses the review request with a detailed comment on the correctness of a new code section. Note that it reverts some changes to the TypeScript signatures of the matrix functions ones() and zeros() -- they do not actually have a typed-function signature of two numbers and an optional format specifically for two dimensions. What they have is a single rest parameter, from which the format is extracted if present. Hence, due to the ban on breaking rest parameters, it is not valid to call math.chain(3).zeros(2) to make a 3-by-2 matrix of zeros, which seems like a perfectly valid ban as the division of the dimensions is very confusing; this should be written as math.chain([3,2]).zeros(). The TypeScript signatures are fixed accordingly, along with the edge case of no arguments to ones() and zeros() at all, which does work to produce the "empty matrix".
Thanks, let's go all in then with the class rewrite 😄
I think you figured that out before: in Object.defineProperty(Unit, 'name', { value: 'Unit' })
Unit.prototype.constructor = Unit
Unit.prototype.type = 'Unit'
Unit.prototype.isUnit = true With classes we can write it as follows: static name = 'OperatorNode'
get type () { return 'OperatorNode' }
get isOperatorNode () { return true } I added unit tests to test |
Thanks Glen, I think everything is ready, I will press the merge button now 🎉 . Thanks again for all your efforts! |
This PR on branch
v11_on_v3a
replaces thev11
branch, and updates it to use[email protected]
.It contains all the commits of all PR's listed in #2476