Business Innovation Patterns.
Nov. 23rd, 2004 06:25 amNothing profound here, but I thought I would write this down before the idea slipped away.
Once upon a time Christopher Alexander wrote "A Pattern Language" about ways of designing buildings that were pleasant to live in. While the book had many omissions and contained much that was apocryphal, or at least wildly inaccurate, it had a large friendly cover. It also got people thinking about overlapping patterns in design space. From that thinking emerged, a number of years later, the software industry's current obsession with design patterns. Now, for the most part this is a good thing™ as making people think about the abstract design elements in their code helps make the code better, although many of the books I have read on the subject also follow the tradition of many omiissions, and much that is inaccurate. Lately there has been evidence that this subfield is starting to mature and more competent books are now being written, but that's beside the point.
What I recently noticed when I sat down to write up all of the various business notions that I have had, is that they seem also to follow a set of design patterns. If I worked hard I could probably extract a set of business design patterns and write a book about it. I wonder if it would sell?
Once upon a time Christopher Alexander wrote "A Pattern Language" about ways of designing buildings that were pleasant to live in. While the book had many omissions and contained much that was apocryphal, or at least wildly inaccurate, it had a large friendly cover. It also got people thinking about overlapping patterns in design space. From that thinking emerged, a number of years later, the software industry's current obsession with design patterns. Now, for the most part this is a good thing™ as making people think about the abstract design elements in their code helps make the code better, although many of the books I have read on the subject also follow the tradition of many omiissions, and much that is inaccurate. Lately there has been evidence that this subfield is starting to mature and more competent books are now being written, but that's beside the point.
What I recently noticed when I sat down to write up all of the various business notions that I have had, is that they seem also to follow a set of design patterns. If I worked hard I could probably extract a set of business design patterns and write a book about it. I wonder if it would sell?
no subject
Date: 2004-11-23 04:36 am (UTC)Would such a book sell?
Hard for me to say. Since this topic is something I haven't really looked at (neither design patterns (as you know ;-) or business models) I don't know if there already exists such books or not. If there's a few hundred books which try to do what you describe it might drown, if there are none it could very well become a new "bible" of sorts. That is... unless some narrow minded [university professors / business school teachers / whoever] might shut out the book because it questions their way of doing things.
no subject
Date: 2004-11-23 05:07 am (UTC)no subject
Date: 2004-11-23 09:56 am (UTC)What I find the most critical about these patterns is giving them names that people will agree on and use in their communication, so that instead of saying "well, we'll have this object here, with pointers to these other more basic objects and do things on them without really adding anything, just making it easier", you can say "let's add a facade object". Most of the patterns in the GoF book aren't all that new, I was fairly familiar with most of them, but it made communication much easier. You can just ask "you've read Design Patterns, right? well, I think we should have foo here".
Really, out of the ocean of books written on this subject, in my opinion, they all have no weight at all, because listing patterns, accurately/completely or not, is rather useless if the names they're given don't fall into common usage (which happened for the original GoF book).
Don't the business type people already have such books naming common patterns? Software engineering is rather new, so it's not surprising we only (relatively) recently got this book, business is, um, much older.
In fact, I know there has to be some, because I, of all people, know of a few semi-complicated business patterns that have a name, like a golden parachute, for example.
no subject
Date: 2004-11-23 09:58 am (UTC)no subject
Date: 2004-11-23 10:10 am (UTC)no subject
Date: 2004-11-23 10:14 am (UTC)But Alexander's book - while it was happy to document standard practise (with its own slant) where this appeared to be a good idea - contained a lot that was probably fairly novel and/or whackball (though I believe it was all tested, so in that sense there was nothing new).
(It's actually amazing what isn't new if you read the research.)
no subject
Date: 2004-11-23 10:16 am (UTC)no subject
Date: 2004-11-23 10:17 am (UTC)no subject
Date: 2004-11-23 10:33 am (UTC)And while some are in fact workarounds for design flaws, they're in wide use, and often just complicated enough that having a short name to refer to them is useful.
no subject
Date: 2004-11-23 10:39 am (UTC)no subject
Date: 2004-11-23 10:52 am (UTC)I guess it always makes me upset that in my mind, OO programming is about delegates, mixins and self-ownership, and what do we get? C++ (which lacks delegation and ownership) and Java (which, last time I checked, lacked mixins other than maybe Serializable, which is inexplicably magic)....
They're all mad! :)
But you know? It wouldn't be a bad thing if someone wrote a Patterns book that you could learn from (as a programmer rather than as a language designer, I mean).
no subject
Date: 2004-11-23 11:00 am (UTC)Doesn't delegation make a good alternative for mixins? Setup a chain of delegation in your constructor or something? Just an idea...
What do you mean by self-ownership?
no subject
Date: 2004-11-23 11:06 am (UTC)no subject
Date: 2004-11-23 11:16 am (UTC)Then again, my ideal notion of an OO language would have first-class, name-scoped selectors, so that selector name collisions are essentially impossible (which is the other thing required for implementation to be safely heritable).
As to closures? Since the closure is the implementation of the abstraction that covers a programme, you don't have a programming language without closures!
no subject
Date: 2004-11-23 11:18 am (UTC)Well, that's well known.
no subject
Date: 2004-11-23 11:25 am (UTC)The problem with C++'s lifetimes is that people don't use destructors. They use pointers (which have no destructors and can't even have one), or when they get some spark of sanity, start using a kind of smart pointer (which can have a destructor), but then they usually go and use a single type of smart pointer everywhere, like if there would be one size that would fit all.
You could say that the fact that this all happens is a sign that it sucks, and you wouldn't be wrong. I can't say I love C++ too much, I just use it as well as I possibly can. I like the more dynamic method dispatch of Objective-C, for example.
no subject
Date: 2004-11-23 11:36 am (UTC)If we had delegation, you could have a member object and delegate to it. If you wanted more than one, make that member object delegate to the next one, in a chain.
I have to say that name-scoped selectors would be awesome. It's the only thing I miss from C++ that I can do easily in C when I do my component stuff (which is much less flexible in language expressiveness than the OO support of C++ itself, disappointingly).
For closures, I mean first-class, of course. It's so silly to have all these languages that couldn't even exist without the concept of a closure, but don't bother to provide them as a first-class element! (my favorite flavor of them is as they have them in Perl)
no subject
Date: 2004-11-23 11:41 am (UTC)As to thread-per-object being puke-inducing, I can't agree. It goes on the list with templates, runtime compilation, arbitrary precision arithmetic, lazy evaluation, garbage collection and dynamic inheritance as a feature that is very easy to implement unacceptably inefficiently, but in fact as a semantics it is quite transformable into a good implementation. Indeed, it's theoretically quite attractive for real-time work because it may give you the abstractions you need to discuss hard time bounds in the presence of synchronisation primitives (because the temporal dependencies all fall at work-cycle ends for at least one of the synchronising agents, and because any priority inversions or whatever become very explicit). I mean, not that I've tried it in practise....
As to C++ and smart pointers - is someone would please give us a full implementation of templates it would all be much better. There'd still be one missing feature: inhertiance through templates so that I could arrange that readonly-pointer-to descended from readonly-pointer-to precisely when foo descended from bar. But it would be oodles closer.
Having to write 90% of the implementation in the header files destroyed any sympathy I ever had for C++ - but then, templates and destructors are almost the only things in C++ that I really like.
no subject
Date: 2004-11-23 11:57 am (UTC)But really my point was that when you say 'you have to support the same interfaces and forward your methods', well, yes, it's a style of delegation and that should be the language's job and not yours - if it can do dynamic method dispatch, it can do this too. (Consider Self, in which an object is deemed to include all slots of any of its prototypes, and a prototype is the value of any slot whose name starts with a star. Safe, I will grant you, this is not. But simple and expressive? It's hard to beat. And whether that's supporting delegation or mixins or prototypes or what it's just not meaningful to ask.)
And first-class closures? You must have a garbage collector and you cannot have deterministic destruction, because statically predicting the deallocation of first class closures is precisely the halting problem.
no subject
Date: 2004-11-23 12:32 pm (UTC)I'm still a bit too attached to the current output of my compiler (as in "what can I do *today* to make it suck less" rather than think of "how it *really* ought to be") to go there. I'd love a perfect world, but I'm in this one, and it's really far from perfect!
By output of the compiler, I mean an ELF or a PE binary, not anything in particular that C++ outputs, like vtables or whatnot. But generating code and changing object layout at runtime (which basically requires generating code if you want to do it efficiently) is a bit too iffy (code that doesn't go in the text segment!?! whee!!!).
I agree that it'd be nice if C++ typed in the forwardings for me, but I like remembering that what I'm doing sucks, so I don't mind it too much. At least, if we could have tail calls for methods with identical signatures (which is perfectly easy in x86 (and probably others) assembly, it's just the stupid C/C++ not letting me generate the code I want and even know how to do!), it'd be a bit less bad...
I used to like dynamic method dispatch, but it seems to me that considering each method individually is a bit of a risky business. Really, methods are not islands, they go with something. At a first level, you could say that some groups of methods go together, but the important part is that they go with a contract of some sort, they go with their semantics. So vtable-style interfaces seems to me like a good compromise, as they also happen to be a thing you can associate the contract with.
Hmm, do you need GC for first-class closures? Say that what I deem first-class in a closure is the Perl-style syntactic sugar, but underneath, they can be done in C++ with an object that has a single operator() method. Thus, they're an object like any others, and the lifetime rules that work with other objects would also work with them. It might be GC, but could be whatever else you normally have.
Heck, I do this in C++ all the time now, it's just that the syntax is horrid, and it shouldn't have to be.
no subject
Date: 2004-11-23 12:48 pm (UTC)I believe that Perl currently uses reference counting, and some code will leak storage badly. With normal objects you can give annoying advice like 'zero it out when you think you;re done with it', of course (and Perl does), but with a closure you'd need a dangerous level of reflection even to be able to do that much.
And don't get me wrong - I disassemble the output of the compiler as a regular bit of my debugging strategy. I just don't think that static compilation is the best known technique. Even if it's often the best implemented.
When you say 'methods are not islands' and need contracts, it sounds like you're asking for interface-checked mixins to me ;).
And C++? It should simply never have happened. Like Perl it grew rather than being designed; unlike Perl it wasn't grown by someone who had a serious devotion to engineering. Or so it seems to me.
no subject
Date: 2004-11-23 01:13 pm (UTC)I know they're transformable. Threads don't have to be real pre-emptive threads. It's just that my mind doesn't seem to be wired like most people. Everyone want to be able to take as much time as they want to do whatever they do, in a straight line, but me, I like state machines better. They seem clearer to my eyes and when I think of a problem, the obvious solution comes to be as a non-deterministic state machine, usually.
But again, I tend to program now, in this world, and all that it pains me, I don't think this is about to change any time soon. So I have to leave lazy evaluation, garbage collection and runtime compilation aside.
I also have tendencies to dislike those for hiding complexities that I feel are important and unavoidable. For example, I feel that you really have to understand the ownership of your objects in order to design properly, and once you understand the ownership well, explicit lifetime management is just about completely figured out for you, you just have to type in your knowledge (which is good anyway, as others will then be able to read back your knowledge!). So why would I want GC if I need to figure this out anyway in other to truly be a great programmer? In my mind, it's almost as error-inducing as explicit lifetimes! Think of it: it encourages people to stop thinking! As if we didn't have enough people who don't think, already...
Templates are really nice, but have an horrible syntax and are missing much capabilities. For example, they have next to no error reporting capabilities. I have extremely strong semantics checking in some areas of my code that is very neatly verified by the compiler, but I have to express the error as some other weird error involving a strange variable named after the error... Eurgh... We'd need something similar to sizeof() (pure compile-time construct), but would give us capabilities like #warning and #error do.
I remember using something called OpenC++ that just basically added metaprogramming facilities in straight C++ (you'd write plugins for the compiler, where you'd have access to the AST and could transform it before the real compilation took place). If it would be more popular, I'd certainly use it a lot!
The compatibility of smart pointers has been figured out. I forget the solution, but my smart pointers have it (foo derives from bar, I can pass a smart where a smart is expected).
no subject
Date: 2004-11-23 01:32 pm (UTC)Perl uses reference counting, yes, with surprinsingly good results. I like the deterministicality (that's a word?) it exhibits. I think the problem is when refcounting is used completely by itself, that's when you have circular references and just can't avoid them. But if you have various types of references to correctly reflect the underlying design, you're fine (at least an owning reference that increases the refcount and a non-owning reference that gets notified when the object goes away, preferably also a non-owning reference that has scope-garanteed lifetime, for parameter passing).
Well, I don't know about mixins, but I'm asking for interface checking, that's for sure!
no subject
Date: 2004-11-23 02:44 pm (UTC)The thing about GC is that it lets you work with pure values. That's my quirk: I like pure values. I tend to design languages in which mutables (that is, non-constant variables) are arbitrarily expensive objects; that's where all the complexity of locking, synchronisation, distributed time management, transcoding, delayed compilation, garbage collection, virtual memory, everything comes home to roost. The idea being that you don't use them - not until you come to that one value in a thousand that really truly represents a nondeterministically updated, shared, distributed, polymorphic, serialisable, upgradeable entity. And then you have the big hammer: the whole of the Internet can be hiding behind that side-effect, and that's the semantics of side effects - they induce time, and are induced by space - so I don't mind.
Templates - agree - have no idea why C had separate base language and preprocessor, and adding a third language for templates was uberdumb. Why don't we get to screw around in the AST, a la LISP? It's bizarre, since every compiler has that layer somewhere, and every language needs extending in the end.
Programming in the real world - it may not be obvious, but we agree on this one, too. It's just that my original field is programming language design and implementation, so these language design parameters are actually quite specific and concrete to me, I'm often thinking 'sure, I remember when we got to that bit in our LISP compiler' or 'I have a favourite implementation technique for that'. It's not what I'm doing now, because it's not what they pay me for at the moment, of course.
no subject
Date: 2004-11-23 02:52 pm (UTC)Of course, one approach to this is to separate ownership from references, and provide 'arenas' to do the owning with a stipulation that you can do what you like with a reference but it must never outlive its target's arena. If I have to have explicit storage management in a language that's more the flavour I'd like.
(It also avoids the overhead problem of refcounting - contrary to popular belief, GC is much faster than refcounting, because all there's no overhead for use, and somewhat faster than alloc/free, ebcause there's no cost for disposal unless you actually need destruction.)
no subject
Date: 2004-11-24 10:26 am (UTC)Arenas just like the Objective-C (which uses refcounting) auto-release pools, you mean? :-)
The trick with refcount is to remember that very few references are actually owning references. If you keep that in mind, you end up twiddling the refcount a whole lot less (you use scoped references for parameter passing, for example, and increase the refcount only when you actually save the reference for longer).
It is true that GC can have better overall throughput, but I like the bounded times of refcounting rather than the bursty random lags of GCing. Again, games and event-driven network servers, a bounded overhead is sometimes preferable...
no subject
Date: 2004-11-24 10:30 am (UTC)Perl 6 adds access to the AST in the same language, BTW, and cleans up many of the well-known ickyness of Perl. It should be something very interesting to watch for, even though it might still take a year or two to become truly available...
Yeah, I can understand your frustration working with C++ if your background is language design and implementation. You're that much more aware of what is possible, things that they missed and so on... I know a fair bit about this area, but I do not follow it really closely (I read "Lambda the Ultimate" and that's about it). I guess that keeps me "virgin" enough to avoid going completely mad... :-)