-
Notifications
You must be signed in to change notification settings - Fork 35
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
Readme doesn't explain what the library does #24
Comments
The docs (linked from the README) list all the methods and show you how to use them. Trine needs ES7 (via Babel, with runtime included and experimental flags). This enables it to be far more convenient than Lodash because you can then chain methods without using wrappers. The README shows an example of an array that's filtered and then mapped (native array methods), but then has a Trine method (flatten) applied to it using ES7's bind operator. This feature (plus ES6 iterators under the hood) mean you get all the benefits of Lodash's chaining without having to wrap or unwrap your data — you can call the Trine method on the data object directly :D The key gain is that by using the features of ES7 idiomatically, your code reads far better in source (and it's far easier to reason about what you want to write without thinking about how to write boilerplate), but compiles down to something similar to Lodash for use in ES5. |
Thanks for feedback. I opened the issue not only to get the info myself, but more to make a feedback on what can a newcomer understand from landing there and what IMHO could be nice to explain more in detail. :) |
If there's any ideas on how to improve the README in this regard, I'd be more than happy to take PRs. :) I'm not quite sure how to communicate this information in the README myself. :/ |
As for this question, given that Trine is built on the bind syntax proposal that may or may not ever land to JavaScript (although it seems unlikely to me that it wouldn't), production usage is not advised, and should be considered carefully. You might end up being bound to a specific version of Babel if you depend on the bind syntax. That's part of the reason why I didn't add very specific instructions on how to easily get set up either, because you should know what you're doing as well as possible if you decide to take Trine into production use. |
@jussi-kalliokoski that would be hilarious. "The functional programming library that Javascript definitely deserves, but can't actually run" – that should keep the haters happy ;) |
@barneycarroll hahah, yes. 😆 |
Of course, there's the performance benefits as well. For example the case that's in the README, getting the first 15 items of a large product catalogue, sorted by price. Here's a benchmark of doing that for a product catalogue of 1 million items: "use strict";
import { quickSort } from "trine/iterable/quickSort";
import { head } from "trine/iterable/head";
import { to } from "trine/iterable/to";
function inMilliseconds () {
const seconds = this[0];
const nanoseconds = this[1];
return seconds * 1e3 + nanoseconds / 1e6;
}
function measure (samples) {
const times = [];
for ( let i = samples; i > 0; i-- ) {
const start = process.hrtime();
this();
const elapsed = process.hrtime(start);
times.push(elapsed::inMilliseconds());
}
times.sort((a, b) => a - b);
const medianTime = times[Math.floor(times.length / 2)];
console.log("%s took %sms", this.name, medianTime);
}
function * randomProducts () {
while ( true ) {
yield {
price: Math.random() * 1000,
};
}
}
const SAMPLES = 1000;
const PRODUCTS = 1000000;
const products = randomProducts()::head(PRODUCTS)::to(Array);
function native_sort_15_first_items () {
return products
.slice() // copy the array to avoid manipulating the original
.sort(function (a, b) { return a.price - b.price; })
.slice(0, 15);
}
function trine_quicksort_15_first_items () {
return products
::quickSort(function (b) { return this.price - b.price; })
::head(15)
::to(Array);
}
native_sort_15_first_items::measure(SAMPLES);
trine_quicksort_15_first_items::measure(SAMPLES); The results on my computer were as follows:
(The benchmark took around an hour to run for me, so might want to adjust the constants if you want to run it yourself). As you can see, Trine is almost 2.5x as fast in that example compared to the native equivalent (and AFAIK, lodash, underscore and Ramda all use the native sort internally so would have similar or worse performance characteristics as the native version). However, if you start decreasing the catalog size, you'll quickly notice that the native equivalent becomes faster - this is because of the current overhead of iterators due to not being provided natively but by pretty complex state machine logic in regenerator. And the current quicksort implementation in Trine is actually rather naive and could be optimized to be much faster, and also at some point when engines start optimizing generators and Trine doesn't need to be compiled anymore, the difference will likely become even greater. Unlike with other utility libraries, you usually don't even have to be thinking about performance and computational complexities with Trine, as just naturally spelling out what you want will most likely be the fastest way to perform the operation. Using plain old ES5, you'd have to hand-write a sort implementation that only does precise sorting for the first |
The readme.md file does a pretty good job introducing issues that arise while writing functionnal js. It really gives desire to avoid those.
But in the end, I haven't picked up:
For instance, I use Lodash. Are there any reason I should consider moving to trine?
The text was updated successfully, but these errors were encountered: