-
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
Adding index file to include all of trine without needing to include individual files #46
base: master
Are you sure you want to change the base?
Conversation
Thank you for taking the time to contribute! This should be as a generated file instead of being done at runtime, in order to support browser environments as well. Also the modules need to be grouped under the categories they're in, because there might be overlap in the names, e.g. import Trine from "trine";
({ foo: bar })::(Trine.object.entries)()
(...)::(Trine.someOtherType.entries)() EDIT: Which makes me question the ergonomics of this feature... |
maybe just for each module? import { values , entries } from "trine/object"
//... |
that seems like a good option! 👍 |
But different types of data often have similar methods that require different implementations - this requires either name collisions or overloading (which both contribute to mental overhead). I personally prefer name collisions because it's more explicit and leaves the developer in control, instead of imposing branches that are not necessarily needed. Consider #49 for example: Lodash/Underscore have a
import { pick as pickFromObject } from "trine/object/pick";
import { pick as pickFromMap } from "trine/map/pick";
import { pick as pickFromArray } from "trine/array/pick";
({ x: 1, y: 2 })::pickFromObject(["y"]) // { y: 2 }
new Map([["x", 1], ["y", 2]])::pickFromMap(["y"]) // Map([["y", 2]])
[1,2]::pickFromArray([1]) // [2]
import { pick } from "trine/iterable/pick";
import { to } from "trine/iterable/to";
import { entries } from "trine/object/entries";
({ x: 1, y: 2 })::entries()::pick(["y"])::to(Object) // { y: 2 }
new Map([["x", 1], ["y", 2]])::pick(["y"])::to(Map) // Map([["y", 2]])
[1,2].entries()::pick([1])::to(Array)[0][1] // [2]
import { pick } from "trine/any/pick";
({ x: 1, y: 2 })::pick(["y"]) // { y: 2 } or [["y", 2]] ?
new Map([["x", 1], ["y", 2]])::pick(["y"]) // Map([["y", 2]]) or [["y", 2]]?
[1,2]::pick([1]) // [2] or [1] or [[1, 2]] or [[0, 2]]? |
There's no ambiguity currently: For example in the case of |
(please don't prefix numbers with # to avoid referencing issues :)
I guess that's just my bias for small focused modules speaking, then. :) Wikipedia's definition for modularity:
If a single JS module exports more than one functionality, it means that even if you want only one of the exports, you get all of them, which breaks the "may be separated" part. Same goes for methods with overloads (by definition, overloading means it does more than one thing, e.g. "returns a new object with only the specified fields of the original object" vs. "if object, returns ... if map, returns ... etc.") - if you need the method for only one type, having a method with overloads forces you to take them all and pay the costs that come with it. This is why I prefer modules that export only one function (other things, such as constants that are required for working with that function are OK IMO). In such modules, I can't really think of a case where you'd need more than one version of This conversation is actually making me think that having index modules in Trine at all is a bad idea. :D Making bad choices (importing all of Trine) easier than good ones (importing only the things you need from Trine) usually tends to lead in a lot of people going with the bad choices. What I'd like to see is better module discoverability features in editors, e.g. you type |
I'd use the word encourage - and why not? It's good to encourage good practices, no? And it's just what you'd expect from a library. You don't go into a real library and take every book with you because you're too lazy to figure out which one you want to read either. It's not because you wouldn't like to have all those books available to you in your living room, but because it would cause you inconvenience to do so. However if it was actually easier than just taking the books you need, people would do it, regardless of how it makes all those books unavailable to everyone else.
I'd rather not see either because if a single module requires that many things, the module is too big and does too many things / skips abstraction levels which is bad for modularity.
You shouldn't need to know either - discoverability can and should be fixed by proper code editors.
No, I mean that |
Very solid reasoning @jussi-kalliokoski Tangent on an earlier point: it's perfectly possible to import arrayPick from 'trine/array/pick'
import objectPick from 'trine/object/pick' And of course it's trivial for any author using modular Javascript to create their own wrappers, eg export default function pick(){
return this::(
this instanceof Array
? arrayPick
: objectPick
)( ...arguments )
} |
No, I'm not forcing anything. Anyone has the freedom of choice to not use this library, or to make a wrapper around it that exposes everything in a single module. And even if one ends up in charge of a codebase that uses Trine and doesn't like it, the modularity allows them to refactor and replace it with something else without an intermediary state of two gargantuan libraries in the codebase.
Yes, lodash recently added support for this and it is now the recommended way of using lodash for minimal footprint. As for
My differing preference is why I created the library in the first place. Lodash/underscore, prototype.js and Ramda also impose their own preferences on the users and if I agreed with those this library would be a pointless (and possibly even harmful) clone of one of them. That's not to say I want this library to be based on my preferences only, discussion about different preferences changes and leads to better understanding of one's own preferences as well, like this discussion has made me consider this feature to be a bad idea (while I originally thought of including it in the initial release).
Ever waited for
Sure you should, and those editors should provide the tooling to help make it easy for you.
You don't. Having a better editor just makes it easier to code. I code roughly 50% in Vim and 50% in Atom (shifting more and more towards Atom as it's become more suitable to my preferences and supports more modern features), and I think both of them should support module discoverability, otherwise they're going to become more and more annoying to use compared to editors that help their users more. Currently the best method of discoverability most libraries have are their docs, and as such Trine's docs tell you how to import each and every endpoint.
Neither is dead code elimination for unused exports and not having that affects more people (unless the only users of the application using the library are the developers). The tooling is there (flow/tern), all editors need to do is integrate them with good UX.
Is this hypothetical? If not, I'd love to know what build environment you're using. This kind of dead code elimination is an extremely hard problem to solve, especially with requirements of async loading and code splitting (method |
Maybe worthwhile authoring a |
Or maybe
The startup is still relatively slow, usually because some plugin requires a whole bunch of code it doesn't use. Performance matters.
Battery life is an important thing, and while detached – especially on mobile – network is usually one of the biggest battery life hogs. By sending only the necessary code over the network (be it a website or Basically, your reasons for not using atom are the reasons why I think this feature is a bad idea.
If you don't know what the library contains, how do you figure out what to import anyway or end up using the library in the first place? By looking at the docs? If so, the docs immediately expose you to the internal structure. Now let's consider some use cases of working with an existing codebase.
Single module library, use case 1
Single module library, use case 2
Single module library, use case 3
Split module library, use case 1Same as for single module library. Split module library, use case 2Same as for single module library. Split module library, use case 3
Even without editor support, what's the advantage of the single module? I don't want to be annoying here or downplay the problem you're having, however before making it easy to do things that demonstrably have bad consequences, I want to get to the bottom of the problem that the feature is supposed to solve. What exactly is the inconvenience? Once we have that information, we may notice that there may be better solutions to the problem, such as improving the documentation. |
I'd also note that the example you had in your comment does not reflect any realistic case because method names are more often than not more than a single character long, so the same with actual names: import { dropTail, dropHead, intersection, sortAlphabetically, uniq, toFunction, partial, difference, enumerate, zip } from "trine"; or, more realistically spread along multiple lines: import {
dropTail,
dropHead,
intersection,
sortAlphabetically,
uniq,
toFunction,
partial,
difference,
enumerate,
zip,
} from "trine"; versus import { dropTail } from "trine/iterable/droptail";
import { dropHead } from "trine/iterable/dropHead";
import { intersection } from "trine/iterable/intersection";
import { sortAlphabetically } from "trine/iterable/sortAlphabetically";
import { uniq } from "trine/iterable/uniq";
import { difference } from "trine/iterable/difference";
import { enumerate } from "trine/iterable/enumerate";
import { zip } from "trine/iterable/zip";
import { toFunction } from "trine/value/toFunction";
import { partial } from "trine/function/partial"; Now the comparison doesn't seem that bad, and as an added bonus you see the input types of the methods. |
Wow, that was a lot to read throgh. @zyklus, I have to admit I don’t understand your frustration – sometimes even brushing against arrogance in my view. I can recommend an interesting conversation I held with the creator of module-best-pracitces. It led me to change my point of view and prefer modularity even more radical than module-best-pracitces is itself a great read I highly recommend. |
No description provided.