4 ms·
But (a) classes demand names, and that's critical, and (b) I almost never need more than one closure. Oh, and (c) this is far from the organizing principle of t
by gruseom 15y ago
But (a) classes demand names, and that's critical, and (b) I almost never need more than one closure. Oh, and (c) this is far from the organizing principle of the system.
- barrkel 15y agoDictionaries, lists, tuples and other structures also demand names. Getting away from classes does not free you from the need for names; and in a dynamically typed language, it requires even more attention to names - see my other comment http://news.ycombinator.com/item?id=3719056 http://news.ycombinator.com/item?id=3719056 I almost invariably find I need more than one closure down the road, outside of simple predicates handed off to algorithms. Even for such simple things as specifying a sink for output (out :: string -> ()), later on I find myself wanting a flush() routine. That's just my experience: problems grow thornier over time, and starting out with something more object-like adapts to that growth more gracefully than a closure does. I think a lot of the problem comes from the syntactic weight of classes. I've implemented closures in a commercial compiler; the actual implementation, when it uses captured state, is very similar to a class, and in fact the implementation method I chose behind the scenes was a class. So I tend to view closures (rather than simple function literals that don't capture state) as just a concise way of declaring and instantiating an object. I've had some success with blending the two. For example, a read-only collection facade is often implemented in .NET with ReadOnlyCollection<T>. But the normal way of implementing that thing is to pass off an IList<T>, which you may need to implement wholly if the logical read-only collection is not already a list. I think that's a complete waste of time; instead, I wrote a function that takes two closure arguments, getCount :: () -> int and getItem :: int -> T, and henceforth I can create a new collection with new behaviour without worrying about the "name" of the descendant, but with the benefits of a class for flexibility down the road.
- sixbrx 15y ago> Dictionaries, lists, tuples and other structures also demand names. Those are just names for values though, we don't have to create a name for a new general principle just to use one. Not to mention values often do not need names at all, in an expression oriented style where function calls are composed.
- barrkel 15y agoAny time you have a dictionary or list of something, there must be some regularity in the entries, otherwise you can't do anything meaningful with them; call that regularity a type, and you can give it a name (or choose not to). If you don't give the type a name, you'll probably give it a name via the variable (or else have very cryptic code). In any case, it has a name, irrespective of whether it's a type or a value.
- sixbrx 15y ago> you'll probably give it a name via the variable Variables are easier to name than the more general notion of class or type (being specific to what is immediately at hand and thus not a distraction), which I think was the original point. And even assuming that my structures will be named is assuming too much. Consider common uses of the fold function, e.g. which act on the pair of (accumulated-value, item). It's common that the pair isn't named. It's parts are named usually, but that's beside the point, I wasn't forced to name the structure itself, much less create a "AccumulatedSumWithNextItem" class.
- barrkel 15y agoIf your problems are trivial enough that they reduce to folds, sure, these concerns go away; but AccumulatedSumWithNextItem would be a terrible name in any case, because it only describes the type, not its intent. For example, List<Customer> describes both the type and its semantic content. List<Tuple<string,DateTime,int>> just describes a type; it's a lot less self-documenting, and code using it will be cryptic. In a dynamic language it will probably be customer_list or somesuch. Point being, "customer" is a name and it crops up somewhere, whether it's in the variable or the type.