Am 07.04.2012 22:04, schrieb Ronan Lamy:
What I said only applies to interface design in Python (it might perhaps
be generalised to other dynamically typed object-oriented languages, but
no further).

My comment applies to interface design in general.
My position is that you cannot infer whether something should be data or a function from the mere fact that the description you came up initially used verbs or nouns.

I believe it's uncontroversial that class names should be nouns while
function and method should usually be verbs. And while it's always
possible to convert most verbs into nouns and some nouns into verbs,
some formulations are more natural than others, e.g. "generate the
steps" vs "apply the step generator".

1) You can always convert a verb to a noun by appending an -izer suffix. (This applies in any language that can somehow construct and store a reference to a function and have that function executed later. In OO land, this is even named as a Design Pattern: Command; it wouldn't be if transforming verbs to nouns weren't a common need.)

2) Even if some wording might be more natural in everyday language, this does not mean it is good program design. If good program design followed natural speech patterns, every good author would be a good programmer. In fact, in the above example of "generate the steps" vs. "apply the step generator", both variants are perfectly equally valid in a programming context. Each could be MUCH better than the other, depending on nonlinguistic design considerations - including but not limited to aspects such as whether we need to transform or combine step generators (MUST be data), whether we need to decide on a generator strategy long before we execute the generator (usually SHOULD be data), whether the generation is a user-visible aspect of the system (preference for whatever the user naturally expects).

3) It's often a trade-off between several aspects, many technical, some linguistic. Most of the time, technical aspects far outweigh the linguistic ones. Starting with a single linguistic aspects to guide software design will massively overvalue them.

> So if you think about which design
will be easiest to explain, it forces a lot of constraints about the
design of the interface.

Ah, but your advice was to start the design by applying a linguistic principle, not collecting constraints. (Typical software engineering goals are massively overconstrained. The art is to priorize constraints and know which can be relaxed or dropped with the least overall damage.)

So if you say "follow the verbs and nouns in the most natural description", the questions I have are: What's your argument why linguistic design is the right principle in this case? What are the technical constraints, and why are they less relevant in this case? What is "most natural" in this situation? How did you make sure it's not just your usage of language, possibly pre-formed by your mother language, but indeed the most natural wording?

"Follow the verbs and nouns" used to be advice on OO design in the early days of general adoption of OO ideas. It didn't work very well, and mostly not at all. In the software design community, it is now generally considered as one item on the long list of desirables, and not very high on that list. (The top entries are ability to adapt to change, getting the job done, and a getting interdependent parts of the code into the same module. Not necessarily in that order.)

So what are good criteria?
- If you have a bunch of related data that is connected via consistency
conditions, putting the data into a class and making it private will
make sure that no code erroneously introduces inconsistencies.

In Python, "private" is just a matter of convention, so you don't really
make sure of anything.

Generally adhered conventions are almost as good as language-enforced rules.

> But more fundamentally, this relies on having an
implementation, so it's definitely relevant for refactoring, but basing
an interface on this ties it to the implementation, which isn't a good
idea.

This design guideline was for those cases where you have an implementation and try to refactor. If you're working on the first draft of an interface, this is helpful only if you already have an implementation in mind.

If you don't have an implementation in mind, I agree this isn't a very useful principle. On the other hand, designing interfaces without thinking about implementation at all risks defining something that's needlessly hard to implement. Just as doing design starting with implementation ideas risks designing something that's too far from the users' thinking to work well for them. Finding a middle ground between these two extremes is what makes a good software designer.

- If you need polymorphism (i.e. the "semantically same" function needs
to do different things depending on what the type of the data is that
it's working on). There are alternatives to using a class in such a
situation, and it isn't even rare that they are better.

Methods are the one obvious way to do polymorphism in Python. To choose
an alternative, you need a clear reason why a method would be
unsuitable.

Most of the time, you need to find all criteria that are relevant, come up with designs, and then evaluate how each design meets each criterion.

A clear reason why some approach is unsuitable demands far too much. It's a trade-off, not a mathematical proof.

--
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com.
To unsubscribe from this group, send email to 
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to