4 ms·
My process is something like this: 1. Start with code centered around pure functions. This is a really good default for your project. It gives you flexibility,
by djacobs 16y ago
My process is something like this:
1. Start with code centered around pure functions. This is a really good default for your project. It gives you flexibility, completely DRY code, and an easy way to think about concurrency.
2. Store large datasets or shallow objects inside maps. They can be efficient and work really well with functions, especially in languages like Python and Clojure. They're even more useful when, for example, they have a literal dot notation (Javascript) for keys.
3. Sometimes, though, it's just easier to structure data inside of objects. Having a map of maps of maps is fine, but projects can quickly become confusing--at least in my experience. The problem is especially bad if multiple people are coding around maps without any enforced structure or validation on creation. In these cases, objects can make things simple and (often) more unified. When I use objects, though, it's good to avoid mutable state. I think of an object as a handy, unified interface to a map, but with the following extras in a unified way:
- A constructor, potentially with sensible defaults
- Validations and sensible fallbacks
- Data-specific error messages
- Methods that are closely related to the data it
holds (and always return the object itself, so
chaining is simple)
In my perspective, building code using functions and organizing it around objects is a nice middle point. It's optimized for both productivity and order, especially if you're careful to avoid state.
- weavejester 16y ago> The problem is especially bad if multiple people are coding around maps without any enforced structure or validation on creation. Using a functional style doesn't mean you can't use constructors, and constructors don't necessarily mean you have to use objects.
- djacobs 16y agoSure, you can have all of the things I listed in FP with some effort. My point is just that OO seems to be good at bringing them all together in a really useful way. (And that way isn't inconsistent with FP.) I aim to strike a balance, to use each style where it is strongest.
- weavejester 16y agoAh, I see your point. But... whilst I can see that a lot of the functionality objects provide is useful, there is also a lot of functionality one might not necessarily need in all instances.
- noidi 16y agoI think generally object validation should remain separate from construction. The documentation for Python's FormEncode library explain this well: > Validation is contextual; what validation you apply is dependent on the source of the data. > Often in an API we are more restrictive than we may be in a user interface, demanding that everything be specified explicitly. In a UI we may assist the user by filling in values on their behalf. The specifics of this depend on the UI and the objects in question. > At the same time, we are often more restrictive in a UI. For instance, we may demand that the user enter something that appears to be a valid phone number. But for historical reasons, we may not make that demand for objects that already exist, or we may put in a tight restriction on the UI keeping in mind that it can more easily be relaxed and refined than a restriction in the domain objects or underlying database. Also, we may trust the programmer to use the API in a reasonable way, but we seldom trust user data in the same way. -- http://formencode.org/Design.html#validation-as-directional-not-intrinsic http://formencode.org/Design.html#validation-as-directional-... Lately I've even played with the idea that maybe Clojure style strict separation of data and functions is just taking the single responsibility principle of OO design to it's ultimate conclusion as the responsibilities of storing a piece of data in memory and the responsibility of deriving new data from it are separated...
- cicero 16y agoThis sounds like how I am currently programming, but I consider myself an FP novice. In Python, I avoid writing classes until I need a data structure too complex for a dictionary of tuples. In C# I have to have more classes, but I am still aiming towards a more functional style by preferring passing parameters and returning values over manipulating instance variables. I would like to learn F# and start using it for my .net work, but I haven't had the time yet.