{"action":"created","issue":{"url":"https://api.github.com/repos/josdejong/mathjs/issues/280","labels_url":"https://api.github.com/repos/josdejong/mathjs/issues/280/labels{/name}","comments_url":"https://api.github.com/repos/josdejong/mathjs/issues/280/comments","events_url":"https://api.github.com/repos/josdejong/mathjs/issues/280/events","html_url":"https://github.com/josdejong/mathjs/issues/280","id":57846006,"number":280,"title":"Modularization","user":{"login":"josdejong","id":568626,"avatar_url":"https://avatars.githubusercontent.com/u/568626?v=3","gravatar_id":"","url":"https://api.github.com/users/josdejong","html_url":"https://github.com/josdejong","followers_url":"https://api.github.com/users/josdejong/followers","following_url":"https://api.github.com/users/josdejong/following{/other_user}","gists_url":"https://api.github.com/users/josdejong/gists{/gist_id}","starred_url":"https://api.github.com/users/josdejong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/josdejong/subscriptions","organizations_url":"https://api.github.com/users/josdejong/orgs","repos_url":"https://api.github.com/users/josdejong/repos","events_url":"https://api.github.com/users/josdejong/events{/privacy}","received_events_url":"https://api.github.com/users/josdejong/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/josdejong/mathjs/labels/design%20decision","name":"design decision","color":"009800"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":24,"created_at":"2015-02-16T20:06:06Z","updated_at":"2015-04-12T18:57:56Z","closed_at":null,"body":"math.js is growing. This is great. It supports quite some different data types now (number, Complex, Unit, Matrix, BigNumber, ...) and a lot of functions. We have plans for more data types and more advanced functions (for example numerical functions). It will be very powerful to modularize the libary. That way you don't have to distribute the whole library with your applications, but just the portion that you actually use. \r\n\r\nRight now, each function of mathjs checks the input type, does type conversions if needed, and executes the corresponding logic, and throws an error in case of unsupported input types. See for example [master/.../add.js](https://github.com/josdejong/mathjs/blob/master/lib/function/arithmetic/add.js#L49). We are currently refactoring the library to use a separate library, [`typed-function`](https://github.com/josdejong/typed-function), to do the type checking, so mathjs can focus on the actual logic. This results in code like [v2/.../add.js](https://github.com/josdejong/mathjs/blob/v2/lib/function/arithmetic/add.js#L39). Now, the code is split in a separate function per type of input argument. After this refactoring, it will be relatively easy step to modularize the library. We can do this in different ways:\r\n\r\n1.  **Separate packages**\r\n    \r\n    Offer different packages to the user, like `mathjs-core`, `mathjs-matrix`, `mathjs-bignumber`, `mathjs-expression`, `mathjs-numerics` etc. The default package `mathjs` can contain all available packages by default. You should be able to use multiple \"sub\" packages in conjunction, like using `mathjs-bignumber` and `mathjs-expression` together. Difficulty may be *which* packages we want to offer exactly, how to split the functionality. There are two options here:\r\n\r\n    1. Keep the source code in a single project, and generate multiple packages from that.\r\n    2. Split the source code in separate projects, each project publishing a single package.\r\n    \r\n2.  **Custom builds** \r\n\r\n    Offer just a single package like it is now, and offer a (user-friendly!) build tool to generate your own custom version of math.js. This should be easy to so both in an automated way (to integrate with your build chain) as well as by hand (using a web interfarce or command line tool). You should be able to both select coarse grained groups of functionality (like include bignumber support or not), and fine grained control of including/excluding individual functions.\r\n\r\n    When we go for this option, we get solution 1.i almost for free, but way more customizable.\r\n\r\nBoth have pros and cons. Having just a single package may make it easy for a new user, its a simple message. In first instance you're not confronted with a bunch of packages of which you may have *no clue* which ones to load. On the other hand, it may not be a big problem if in all examples and docs you just use the main, all containing `mathjs` package.\r\n\r\nAs for the customization: just selecting from a list with sub-packages may be easier than having to get into place your own custom build. But on the other hand, a custom build gives you much more fine-grained control over what you exactly want to include, and if you're looking into this sort of optimization you will probably have a build chain anyway. And besides that, the build step can be really easy if we get it right.\r\n\r\nWhat are your thoughts on this matter?"},"comment":{"url":"https://api.github.com/repos/josdejong/mathjs/issues/comments/92100399","html_url":"https://github.com/josdejong/mathjs/issues/280#issuecomment-92100399","issue_url":"https://api.github.com/repos/josdejong/mathjs/issues/280","id":92100399,"user":{"login":"josdejong","id":568626,"avatar_url":"https://avatars.githubusercontent.com/u/568626?v=3","gravatar_id":"","url":"https://api.github.com/users/josdejong","html_url":"https://github.com/josdejong","followers_url":"https://api.github.com/users/josdejong/followers","following_url":"https://api.github.com/users/josdejong/following{/other_user}","gists_url":"https://api.github.com/users/josdejong/gists{/gist_id}","starred_url":"https://api.github.com/users/josdejong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/josdejong/subscriptions","organizations_url":"https://api.github.com/users/josdejong/orgs","repos_url":"https://api.github.com/users/josdejong/repos","events_url":"https://api.github.com/users/josdejong/events{/privacy}","received_events_url":"https://api.github.com/users/josdejong/received_events","type":"User","site_admin":false},"created_at":"2015-04-12T18:57:55Z","updated_at":"2015-04-12T18:57:55Z","body":"@rjbaucells and I had a good discussion in #321 about how to group and strore functionality. Basically, there are two options:\r\n\r\n1. Group functionality per *type*, like writing all functions for Matrix and BigNumber as member functions of the prototype.\r\n  - Pros: It's very natural to store the functions acting on a data type with the data type itself in a prototype. It's a logical grouping.\r\n  - Cons: Results in a limited number of huge files, which isn't good for modularity of the code.\r\n\r\n2. Group functionality per *function*. For example the function `add` will contain all implementations of the function for different data types (number, BigNumber, Matrix, sparse matrix, etc). \r\n  - Pros: assuming that we have \"tens\" of data types and \"hundreds\" of functions, it allows for more modular code when grouping per function than per data type. This way you can easily create custom bundles containing a limited number of functions/data types.  \r\n  - Cons: code related to a single data type is scattered around lots of files. Extra \"util\" files needed to store functionality shared by multiple functions. The functions need to access internal properties of the data types, which is not so neat.\r\n\r\nFor me the modularity argument is *very* important, and this is what we aim for with `v2`. I hope math.js will keep growing and growing. That means though that in the end the average user only uses a tiny fraction of the library. It's important to make it a no-brainer to load and/or bundle only the used part, instead of having to distribute costly kB's over the wire, or have to wait for seconds before the library is loaded and having it consume lots of extra memory.\r\n\r\nTherefore I propose to go for grouping functionality per *function* rather than per *data type*. A more *functional* than *object oriented* approach. Thus, as much as possible static, pure functions, and as little as possible member functions. We can go this way and after half a year or so evaluate whether this results in a practical solution with the desired modularity.\r\n\r\nWhat are your thoughts on this matter?"}}