А вот сказать бы журналюгам из "Огонька", этак 77-го года, что их кондовая фотопропаганда не только пойдёт на ура 30 лет спустя, но и будет искренне восприниматься как "правда о жизни в СССР". В 77-м году население не было столь наивно, и красочные альбомы с приветствиями товарищу Сталину воспринимались вполне адекватно (за исключением горстки выживших из ума идиотов).
Oct. 26th, 2007
events, state machines, continuations
Oct. 26th, 2007 08:51 amThere are different ways to handle communications with reality in your code. I define reality as something that is beyond the code's control.
One method, popular in languages which names start with 'java', is events mechanism. A listener subscribes to events, and is called when an event happens. This can be done using the regular listener pattern, or via "callback" mechanism (inherited from c, where callbacks are functions, not "instances of callback class"), or via Java's wait/notify - this was popular probably around year 2000, and now nobody bothers to do this anymore.
This makes sense when your code either has listening/reacting as its main functionality, or there is a line of activitiy that it has to do in any circumstances, parallel to what it regularly does. But suppose you have a rather long method, and it has to do its work, and once you start communicating with reality, you are suggested to use events mechanism. "We'll call you". What are you supposed to do before they call you? Hibernate? Study Japanese? Work on improving your performance? Nothing makes sense; from the point of view of the code, it would be much more advantageous to just call immediately and get results.
That's where continuations come into our life. How continuations look, depends on the language and the tastes of the programmers. In Python, you just say 'yield', and the next player makes the move, etc, and you continue when someone yields to you. There's no such thing in Java. In more primitive languages, where you have direct access to your bytes (or bits, as is the case in c), you can implement coroutine mechanism. You and your s.o. (aka coroutine) call each other all the time and exchange news. Both are happy. Not so in Java. One of the suggestions is to use exceptions. Like this:
Java compilers will go crazy, seeing this trick, so you'll have to write something like
While this may look cute in a lab, you cannot seriously offer this to programmers in South Asia, they'll go crazy and will try to replace all function calls with exceptions - makes sense, this way you have access to the stack, and can return to any point in any method.
No, seriously. Continuations are still something Jave programmers better not touch.
But wait, there's more. Say, instead of just one request which requires some time to finish, you throw several requessts to the world outside? Send an mail to your girlfriend, called the plumber, call your manager that you are not coming today, called a liquor store ordering a pack of beer (that's assuming you did have time to study Japanese, and now you are in Japan, where ordering beer on the phone is possible); now you sit and wait. And your future actions depend on what happens next. Setting up parallel listeners does not make sense; your actions will depend on what happens first.
This is state machine. Finite automaton (or infinite, depending on your mental model). The previous example, continuations, can be easily implemented as a state machine - you just don't fork.
Now... what is the best (nonintrusive, readable, obvious, convincing, easy-to-explain-to-idiots-and-conservatives) way to implement state machine in regular Java classes? So that continuations would not require setting up listeners via callbacks?
One method, popular in languages which names start with 'java', is events mechanism. A listener subscribes to events, and is called when an event happens. This can be done using the regular listener pattern, or via "callback" mechanism (inherited from c, where callbacks are functions, not "instances of callback class"), or via Java's wait/notify - this was popular probably around year 2000, and now nobody bothers to do this anymore.
This makes sense when your code either has listening/reacting as its main functionality, or there is a line of activitiy that it has to do in any circumstances, parallel to what it regularly does. But suppose you have a rather long method, and it has to do its work, and once you start communicating with reality, you are suggested to use events mechanism. "We'll call you". What are you supposed to do before they call you? Hibernate? Study Japanese? Work on improving your performance? Nothing makes sense; from the point of view of the code, it would be much more advantageous to just call immediately and get results.
That's where continuations come into our life. How continuations look, depends on the language and the tastes of the programmers. In Python, you just say 'yield', and the next player makes the move, etc, and you continue when someone yields to you. There's no such thing in Java. In more primitive languages, where you have direct access to your bytes (or bits, as is the case in c), you can implement coroutine mechanism. You and your s.o. (aka coroutine) call each other all the time and exchange news. Both are happy. Not so in Java. One of the suggestions is to use exceptions. Like this:
int x = 1;
int y = 2;
throw new WaitingForYourCallException(x, y);
// continue from here
Java compilers will go crazy, seeing this trick, so you'll have to write something like
if (1 == 1) throw new WaitingForYourCallException(x, y);
While this may look cute in a lab, you cannot seriously offer this to programmers in South Asia, they'll go crazy and will try to replace all function calls with exceptions - makes sense, this way you have access to the stack, and can return to any point in any method.
No, seriously. Continuations are still something Jave programmers better not touch.
But wait, there's more. Say, instead of just one request which requires some time to finish, you throw several requessts to the world outside? Send an mail to your girlfriend, called the plumber, call your manager that you are not coming today, called a liquor store ordering a pack of beer (that's assuming you did have time to study Japanese, and now you are in Japan, where ordering beer on the phone is possible); now you sit and wait. And your future actions depend on what happens next. Setting up parallel listeners does not make sense; your actions will depend on what happens first.
This is state machine. Finite automaton (or infinite, depending on your mental model). The previous example, continuations, can be easily implemented as a state machine - you just don't fork.
Now... what is the best (nonintrusive, readable, obvious, convincing, easy-to-explain-to-idiots-and-conservatives) way to implement state machine in regular Java classes? So that continuations would not require setting up listeners via callbacks?