Er. Ok. The way you implement concrete components (that reify an interface) may indeed utilise inheritance; depends on the language. Not sure what you mean by "translation class" - a wrapper?
"Dependency Injection" doesn't really care about that. What it's concerned with is how particular components locate the other components they have to interact with.
Possibilities: hard-coded instantiation -
Foo foo = new Foo();// not DI
the same kind of thing, but using reflection
Foo foo = (Foo) Class.forName(fooClass).newInstance();// not really DI either
a factory object:
Foo foo = fooFactory.makeFoo();// might be ok. But how do we get hold of fooFactory?
or, an external framework that has instantiated this object gives it the collaborators it is after:
public void setFoo(Foo foo) { this.foo = foo; }
That's a DI approach: the burden of creating the dependency is on the instantiating framework. Details of the precise langauge mechanism used to inject these dependencies (using a constructor, using setter methods, etc) vary between frameworks. The article gives a approach expressed using AOP constructs.
Having said that, I'm still not sold on AOP. My concern, I realise, is that AOP is prone to the same problem that makes people denigrate operator overloading (a language feature that I find particularly appealing): it's easy to write absolutely unmaintainable code using AOP. My gut instinct is that AOP is more prone to this than (say) operator overloading, since aspects are rather more widely distributed through source than the latter.
I guess the conclusion (which is the one I also draw about operator overloading) is that AOP is a powerful technique and is more harmful than good in the hands of less than expert practitioners. That makes me nervous about it: I've heard amazing claims about the maintainability of codebases that use AOP, but I'm not sold. A little, in the right places? Perhaps. The approach in this article is interesting, but I'm not convinced it's really the right place for it.
Dependency injection: software is written by decomposing a problem into functionally distinct components. Those components might be self-contained, which makes things easy. In any case, each component fits a particular purpose. If you view that purpose as a contract, the component fulfuls the contract; what you'd like to do is to be able to interchange the implementation of a particular component simply. All you need to know is that a particualr implementation fulfills the demans of the contract for that component. ("Contract" here means the API, or interface, together with the semantics of that interface.)
There are patterns that let you select individual components with late binding - ie, at runtime. "Abstract Factory" is a good google term to look for.
Anyway, some components are not self-contained. They require other components to fulfil their contract. Again, they may not care about the _implementation_ of those components; only that those components exist. Those secondary components might be used solely by the component in question (a "resource") or might collaborate as a peer (a "collaborator"). In either case, the question you face is: this block of code requires a "Foo": how do I get an implementation of "Foo" into it?
That summarises the problem that Dependency Injection attempts to solve. The clue is in the name: the creation of required components is handled by an external framework (the components themselves are not responsible for the creation of their resources or collaborators): hence the phrase, "Inversion of Control" to describe this approach.
The article discusses the use of AOP to manage dependency injection: it's an IoC framework expressed using AOP constructs.
The best guesses as to why this is happening and what its implications are, however, are pretty disturbing. Perhaps you should at least read the whole of that article.
I'm aware of the work; I'm worried that despite their pretty solid recommendations, it might fall between the cracks. You'd hope that browser writers are pretty clued-up to I18N issues these days: certainly, it's not konqueror that is most likely to get this wrong first time around:-/
I'd like to see visual cues for IRIs containing chacracters not from my locale; and for characters not from the locale of the displayed document. "Different codepoints, similar glyph" is going to become another vector for phishing, I think.
"only that in any axiomatic system complex enough to formulate its own self-consistency there are statements which can neither be proved true nor untrue"
Right. Common example is the construction of a Goedel sentence for peano arithmetic, correct? And of the usual construction, you'll agree, we "know" the sentence to be true for the natural numbers - it just cannot be proved from the axioms. So, typically one might throw in the Goedel sentence and have a new axiom set, which will have its own goedel sentences, and so on. Alternaticely, one can throw in the negation of the goedel sentence as an axiom, and you wind up with an axiom set that's as consistent as it was before, just that (to use the term more accurately) the "real" natural numbers are no longer a model for.
So the conclusion is that there's no (complete enumerable) axiomatisation of the natural numbers.
However, the axioms for arithmetic we use are phenomenally successful: and we most certainly _do_ test them, all the time. Every time arithmetic makes a prediction about the things you count in the real world, it appears to stand up. In fact, no counterexamples have ever been discovered. The use of mathematics in every science is incredibly successful because of this fact.
But we've not actually demonstrated that the behaviour of things we count really work like our axiomatisation predicts, for arbitrarily large numbers. We just keep testing it (every time you count anything) and so far it appears to stand up.
_That_ is why mathematics is a science. _That_ is the testing, and it certainly does go on all the time. Ask any mathematician who knows what they're talking about, and they'll say "sure".
Since always. Mathematics is the most successful science there is.
Don't believe me? Science builds models of the world, and tests those models. What do you think N={0, 1, 2,...} is? Take the usual ZF construction. It gives you counting numbers. Those numbers appear to behave the same way that the numbers we really count in the physical universe do.
But the axiomatisations are incomplete (see Goedel 1&2). That is, our models of numbers _provably_ break down.
It gets worse. Have you ever seen a billion of anything? A trillion? A quadrillion? 10^90? These are "just" finite integers, and yet we've no way to tell if large counting numbers really do behave like our models. The "real" numbers aren't real. Hell, even the large integers aren't really "real".
The same goes for predicate logic. At one level, just symbol manipulation. At another, a model of the way we think the universe works.
If you read the epilogue to "Contact", you'll see that the idea, that mathematics and the real counting numbers are subtly different, expressed in a particularly beautiful and profound way (a message left behind in the digits of pi).
Anyway, that's why mathematics is a natural science; but this idea tends to crop up more in the philosophy of foundational mathematics rather than in day-to-day practice; but ask any mathematician about this and they'll say "sure".
Agreed; fetch/build/deploy as one-click or one-command operations are (usually, certainly here) a fundamental requirement before worrying about unit testing: because if the programmer can't do the former, then they're unlikely to be able to simply and trivially run their unit tests, either.
ps. Yes, we do this here: this isn't theoretical. Yes, decent build engineering takes time and talent. Programmer management takes other, political skills. It's hard work but absolutely worth it for our environment.
That rathole is a luxury you cannot afford yet. "Coding standards" are something that it's hard to enforce without a relatively uniform environment in the first place, and lots of things will get in the way of programmers adhering to these.
So, your principle goals should be to create uniformity in the development and deployment environments. That means build engineering and software layout, automation, etc. It doesn't necessarily mean mandating a particular IDE or toolset (although that can help) - it _does_ mean getting your infrastructure in place so that a programmer can shift to a project, get hold of the code, build and deploy to a test environment (their workstation or a testing box), look at the check-in history, look at the bug and feature lists, and so on. And they should be able to produce software that's laid out in a way that "just another project" can be deployed much like any other, wherever possible.
If you manage that, then worry about the coding standards!
As to this: a decent set of stock tools will help getting a programmer up to speed far better than coding practices which might not be adhered to. So, make it easy to test and check in code that works. Make it easy to run tests. Find a decent code comprehension tool and give your developers training with it. Find the most popular IDE and automate project layout and deployment in that IDE. Ensure that programmers can ask "what broke?", "what changed?" and fire up a debugger against different versions with minimal hassle. Keep your sysadmins happy, and ensure that these processes are scriptable.
Above all, involve the developers. Consult! Find out what tools they use, what they're lacking. Organise a regular informal technical get-together where people can show off tools; it's the best way of developing a consistent practice, and "consistency" is a key factor in local "best practice". Find your champions. Finally, don't be afraid to invest in developer training with the new tools.
Always measure the areas that your are about to address by some simple yardsticks: estimate the effort, the cost, the benefit, the likely takeup, the risks. Is it worth it?
Or if you're driving a pink car and they've got a large break whilst playing motorway snooker. This also happens.
Typical innumeracy you'd expect from a zoologist.
on
Cow Tipping is a Myth
·
· Score: 2, Interesting
Rather overaccurate numbers for the number of people you'd need (4.43), the calculations state things with a level of accuracy that indicates the calculator is the usual seminumerate soft scientist. I bet they quote the level of sodium they get in "half an average grapefruit" to three significant figures too.
However, the model assumes the cow is static, whilst later giving the lie to this. A single person can tip a cow (I've done it, I'm 5'7" and weigh little and had about a 50% hit rate - hey, there was little to do where I grew up). The cow _does_ react to a shove - the process is more like cow tripping than cow tipping, but they most certainly do go over.
Yes. It's repeatedly abused in the UK by authorities. If you email someone twice on the same subject they can file a harrassment case; this has been used by board members against "ethical protesters" in a few fairly-well-publicised "dirty borough" cases. Similarly arrests for "staring at a building" amongst other great charges.
Java's original design (the langauge, not the JVM) was centred around the monitor, but that's a long time ago. As others have pointed out, a synchronized(foo){... } block works well, and locks on foo (not the code).
The problem with attaching locking directives to members rather than wrapping code with blocks that lock on data members is that it's much harder for a compiler to determine when it can relax locking constraints. Mind you, Java developers get it wrong too (google for the double-checked locking idiom and why it's broken).
Incidentally the latest editions of Java include some more of the "usual suspects": reader/writer locks, semaphores, etc, which have relatively efficient implementations in terms of the underlying synchronized(){} primitive. Look for the java.util.concurrent and java.util.concurrent.locks packages for details.
A handful of soldiers? You're talking about institutionalised abuse sanctioned by Rumsfeld. But that misses the point; the question is not, "what is worse?" - I think, rather, that you should be asking: if the US holds itself up as the yardstick of freedom and democracy for the whole world, should we not expect higher standards of behaviour? The country is essentially a Christian one. You might ask yourself "what would Jesus do?"
As to blowing up crowds of people: Falujah.
My views, too, are leftist: liberal, to be precise - but over here, that's not an insult:-) And I don't think the world is black-and-white. I simply offer a reason why people might be concerned about Abu Ghraib, Gitmo, the recent reports from Afghanistan, etc.
The difference is that infinity isn't just a big number. If the prisoners start with only a finite number of visits, they're never going to manage to visit the king an infinite number of times.
It has relevance to the problem because the OP has stated accurately a constraint upon the king. Although it's still not clear whether the prisoners know the value of _k_ - as far as I can see, they must, in order to be able to formulate their protocol correctly.
Re:Not so sure about this - I stil "don't get it"
on
What is Ruby on Rails?
·
· Score: 1
The nuances of HTTP transactions to drive your app events (incl. dealing with "back", "refresh", etc) are neither intuitive nor simple. There's a lot of detail. If you use something low-level (eg, PHP) this will bite you at some point.
Similarly if you need to persist a complex object model (which you will unless you stop at writing trivial bloging apps): you're going to have to understand a great deal of detail.
Rails and the ilk offer an abstraction layer on top of this that actually means you get an opportunity to express your application logic in a fashion that is perhaps a little more comprehensible - the idiom is more natural to many programmers, unless they've been perverted by years of dealing with shoddy web frameworks:-)
(Similar tools and frameworks exist for many languages. That's because there is a need for them.)
It's a straightforward and common expression, familiar to anyone who's done any maths. Unlike yours, which is an inaccurate layperson's attempt to express the same idea.
Given an arbitrary finite number of visits, v, there's a finite number of calls the king makes, c, before every prisoner has been before him v times. The king gets to choose what the function c(v) is, but he's constrained to ensure it's well-defined for any value v.
Yup. Did something similar back in '91 - was inspired by lpmud, didn't like its threading model (calls ran to completion), invented something different to produce a timeslicing VM with interruptable operations. Very similar idea, but the call protocol passed the state to the operation as a parameter (the new state was returned as the result).
typedef int STATE;
STATE some_op(STATE current,/* other cruft */) {
switch (current) {
case...:/* something */
return next_state; }
It was actually a pretty speedy interpreter for the time. Great learning tool too - found out all about race conditions the hard way:-)
Er. Ok. The way you implement concrete components (that reify an interface) may indeed utilise inheritance; depends on the language. Not sure what you mean by "translation class" - a wrapper?
// not DI
// not really DI either
// might be ok. But how do we get hold of fooFactory?
"Dependency Injection" doesn't really care about that. What it's concerned with is how particular components locate the other components they have to interact with.
Possibilities: hard-coded instantiation -
Foo foo = new Foo();
the same kind of thing, but using reflection
Foo foo = (Foo) Class.forName(fooClass).newInstance();
a factory object:
Foo foo = fooFactory.makeFoo();
or, an external framework that has instantiated this object gives it the collaborators it is after:
public void setFoo(Foo foo) { this.foo = foo; }
That's a DI approach: the burden of creating the dependency is on the instantiating framework. Details of the precise langauge mechanism used to inject these dependencies (using a constructor, using setter methods, etc) vary between frameworks. The article gives a approach expressed using AOP constructs.
Having said that, I'm still not sold on AOP. My concern, I realise, is that AOP is prone to the same problem that makes people denigrate operator overloading (a language feature that I find particularly appealing): it's easy to write absolutely unmaintainable code using AOP. My gut instinct is that AOP is more prone to this than (say) operator overloading, since aspects are rather more widely distributed through source than the latter.
I guess the conclusion (which is the one I also draw about operator overloading) is that AOP is a powerful technique and is more harmful than good in the hands of less than expert practitioners. That makes me nervous about it: I've heard amazing claims about the maintainability of codebases that use AOP, but I'm not sold. A little, in the right places? Perhaps. The approach in this article is interesting, but I'm not convinced it's really the right place for it.
Dependency injection: software is written by decomposing a problem into functionally distinct components. Those components might be self-contained, which makes things easy. In any case, each component fits a particular purpose. If you view that purpose as a contract, the component fulfuls the contract; what you'd like to do is to be able to interchange the implementation of a particular component simply. All you need to know is that a particualr implementation fulfills the demans of the contract for that component. ("Contract" here means the API, or interface, together with the semantics of that interface.)
There are patterns that let you select individual components with late binding - ie, at runtime. "Abstract Factory" is a good google term to look for.
Anyway, some components are not self-contained. They require other components to fulfil their contract. Again, they may not care about the _implementation_ of those components; only that those components exist. Those secondary components might be used solely by the component in question (a "resource") or might collaborate as a peer (a "collaborator"). In either case, the question you face is: this block of code requires a "Foo": how do I get an implementation of "Foo" into it?
That summarises the problem that Dependency Injection attempts to solve. The clue is in the name: the creation of required components is handled by an external framework (the components themselves are not responsible for the creation of their resources or collaborators): hence the phrase, "Inversion of Control" to describe this approach.
The article discusses the use of AOP to manage dependency injection: it's an IoC framework expressed using AOP constructs.
You should read that paper rather than citing the abstract. This isn't good news.
The best guesses as to why this is happening and what its implications are, however, are pretty disturbing. Perhaps you should at least read the whole of that article.
I'm aware of the work; I'm worried that despite their pretty solid recommendations, it might fall between the cracks. You'd hope that browser writers are pretty clued-up to I18N issues these days: certainly, it's not konqueror that is most likely to get this wrong first time around :-/
I'd like to see visual cues for IRIs containing chacracters not from my locale; and for characters not from the locale of the displayed document. "Different codepoints, similar glyph" is going to become another vector for phishing, I think.
(PS. Lascowski is the chap to talk to about this.)
Then let me try again.
"only that in any axiomatic system complex enough to formulate its own self-consistency there are statements which can neither be proved true nor untrue"
Right. Common example is the construction of a Goedel sentence for peano arithmetic, correct? And of the usual construction, you'll agree, we "know" the sentence to be true for the natural numbers - it just cannot be proved from the axioms. So, typically one might throw in the Goedel sentence and have a new axiom set, which will have its own goedel sentences, and so on. Alternaticely, one can throw in the negation of the goedel sentence as an axiom, and you wind up with an axiom set that's as consistent as it was before, just that (to use the term more accurately) the "real" natural numbers are no longer a model for.
So the conclusion is that there's no (complete enumerable) axiomatisation of the natural numbers.
However, the axioms for arithmetic we use are phenomenally successful: and we most certainly _do_ test them, all the time. Every time arithmetic makes a prediction about the things you count in the real world, it appears to stand up. In fact, no counterexamples have ever been discovered. The use of mathematics in every science is incredibly successful because of this fact.
But we've not actually demonstrated that the behaviour of things we count really work like our axiomatisation predicts, for arbitrarily large numbers. We just keep testing it (every time you count anything) and so far it appears to stand up.
_That_ is why mathematics is a science. _That_ is the testing, and it certainly does go on all the time. Ask any mathematician who knows what they're talking about, and they'll say "sure".
Since always. Mathematics is the most successful science there is.
...} is? Take the usual ZF construction. It gives you counting numbers. Those numbers appear to behave the same way that the numbers we really count in the physical universe do.
Don't believe me? Science builds models of the world, and tests those models. What do you think N={0, 1, 2,
But the axiomatisations are incomplete (see Goedel 1&2). That is, our models of numbers _provably_ break down.
It gets worse. Have you ever seen a billion of anything? A trillion? A quadrillion? 10^90? These are "just" finite integers, and yet we've no way to tell if large counting numbers really do behave like our models. The "real" numbers aren't real. Hell, even the large integers aren't really "real".
The same goes for predicate logic. At one level, just symbol manipulation. At another, a model of the way we think the universe works.
If you read the epilogue to "Contact", you'll see that the idea, that mathematics and the real counting numbers are subtly different, expressed in a particularly beautiful and profound way (a message left behind in the digits of pi).
Anyway, that's why mathematics is a natural science; but this idea tends to crop up more in the philosophy of foundational mathematics rather than in day-to-day practice; but ask any mathematician about this and they'll say "sure".
Agreed; fetch/build/deploy as one-click or one-command operations are (usually, certainly here) a fundamental requirement before worrying about unit testing: because if the programmer can't do the former, then they're unlikely to be able to simply and trivially run their unit tests, either.
ps. Yes, we do this here: this isn't theoretical. Yes, decent build engineering takes time and talent. Programmer management takes other, political skills. It's hard work but absolutely worth it for our environment.
That rathole is a luxury you cannot afford yet. "Coding standards" are something that it's hard to enforce without a relatively uniform environment in the first place, and lots of things will get in the way of programmers adhering to these.
So, your principle goals should be to create uniformity in the development and deployment environments. That means build engineering and software layout, automation, etc. It doesn't necessarily mean mandating a particular IDE or toolset (although that can help) - it _does_ mean getting your infrastructure in place so that a programmer can shift to a project, get hold of the code, build and deploy to a test environment (their workstation or a testing box), look at the check-in history, look at the bug and feature lists, and so on. And they should be able to produce software that's laid out in a way that "just another project" can be deployed much like any other, wherever possible.
If you manage that, then worry about the coding standards!
As to this: a decent set of stock tools will help getting a programmer up to speed far better than coding practices which might not be adhered to. So, make it easy to test and check in code that works. Make it easy to run tests. Find a decent code comprehension tool and give your developers training with it. Find the most popular IDE and automate project layout and deployment in that IDE. Ensure that programmers can ask "what broke?", "what changed?" and fire up a debugger against different versions with minimal hassle. Keep your sysadmins happy, and ensure that these processes are scriptable.
Above all, involve the developers. Consult! Find out what tools they use, what they're lacking. Organise a regular informal technical get-together where people can show off tools; it's the best way of developing a consistent practice, and "consistency" is a key factor in local "best practice". Find your champions. Finally, don't be afraid to invest in developer training with the new tools.
Always measure the areas that your are about to address by some simple yardsticks: estimate the effort, the cost, the benefit, the likely takeup, the risks. Is it worth it?
Or if you're driving a pink car and they've got a large break whilst playing motorway snooker. This also happens.
Rather overaccurate numbers for the number of people you'd need (4.43), the calculations state things with a level of accuracy that indicates the calculator is the usual seminumerate soft scientist. I bet they quote the level of sodium they get in "half an average grapefruit" to three significant figures too.
However, the model assumes the cow is static, whilst later giving the lie to this. A single person can tip a cow (I've done it, I'm 5'7" and weigh little and had about a 50% hit rate - hey, there was little to do where I grew up). The cow _does_ react to a shove - the process is more like cow tripping than cow tipping, but they most certainly do go over.
Your estimate of the age of the universe is about an order of magnitude too high.
Yes. It's repeatedly abused in the UK by authorities. If you email someone twice on the same subject they can file a harrassment case; this has been used by board members against "ethical protesters" in a few fairly-well-publicised "dirty borough" cases. Similarly arrests for "staring at a building" amongst other great charges.
Java's original design (the langauge, not the JVM) was centred around the monitor, but that's a long time ago. As others have pointed out, a synchronized(foo){ ... } block works well, and locks on foo (not the code).
The problem with attaching locking directives to members rather than wrapping code with blocks that lock on data members is that it's much harder for a compiler to determine when it can relax locking constraints. Mind you, Java developers get it wrong too (google for the double-checked locking idiom and why it's broken).
Incidentally the latest editions of Java include some more of the "usual suspects": reader/writer locks, semaphores, etc, which have relatively efficient implementations in terms of the underlying synchronized(){} primitive. Look for the java.util.concurrent and java.util.concurrent.locks packages for details.
A handful of soldiers? You're talking about institutionalised abuse sanctioned by Rumsfeld. But that misses the point; the question is not, "what is worse?" - I think, rather, that you should be asking: if the US holds itself up as the yardstick of freedom and democracy for the whole world, should we not expect higher standards of behaviour? The country is essentially a Christian one. You might ask yourself "what would Jesus do?"
:-) And I don't think the world is black-and-white. I simply offer a reason why people might be concerned about Abu Ghraib, Gitmo, the recent reports from Afghanistan, etc.
As to blowing up crowds of people: Falujah.
My views, too, are leftist: liberal, to be precise - but over here, that's not an insult
"...or some idiot who thinks he should rule the world invades your country, who do you go to?"
And they say Americans have no notion of irony.
The difference is that infinity isn't just a big number. If the prisoners start with only a finite number of visits, they're never going to manage to visit the king an infinite number of times.
It has relevance to the problem because the OP has stated accurately a constraint upon the king. Although it's still not clear whether the prisoners know the value of _k_ - as far as I can see, they must, in order to be able to formulate their protocol correctly.
The nuances of HTTP transactions to drive your app events (incl. dealing with "back", "refresh", etc) are neither intuitive nor simple. There's a lot of detail. If you use something low-level (eg, PHP) this will bite you at some point.
:-)
Similarly if you need to persist a complex object model (which you will unless you stop at writing trivial bloging apps): you're going to have to understand a great deal of detail.
Rails and the ilk offer an abstraction layer on top of this that actually means you get an opportunity to express your application logic in a fashion that is perhaps a little more comprehensible - the idiom is more natural to many programmers, unless they've been perverted by years of dealing with shoddy web frameworks
(Similar tools and frameworks exist for many languages. That's because there is a need for them.)
It's a straightforward and common expression, familiar to anyone who's done any maths. Unlike yours, which is an inaccurate layperson's attempt to express the same idea.
Given an arbitrary finite number of visits, v, there's a finite number of calls the king makes, c, before every prisoner has been before him v times. The king gets to choose what the function c(v) is, but he's constrained to ensure it's well-defined for any value v.
"Finite but unbounded", not "infinite".
Have you _read_ the IRC RFC? I think it's the worst one I've ever seen.
Yup. Did something similar back in '91 - was inspired by lpmud, didn't like its threading model (calls ran to completion), invented something different to produce a timeslicing VM with interruptable operations. Very similar idea, but the call protocol passed the state to the operation as a parameter (the new state was returned as the result).
/* other cruft */) { ...: /* something */
:-)
typedef int STATE;
STATE some_op(STATE current,
switch (current) {
case
return next_state;
}
It was actually a pretty speedy interpreter for the time. Great learning tool too - found out all about race conditions the hard way