Could I say that the peek() method in java.util.stream.Stream should be idempotent - java-stream

My question is related to: What does idempotent method mean and what are the side effects in case of calling close method of java.lang.AutoCloseable?
As to the method in java.util.stream.Stream.peek(), in the book Oracle Certified Professional Java SE 8 Study Guide > chapter 4 Functional programming > Using Streams > Using Common Intermediate Operations, it was stated that peek() is intended to perform an operation without changing the result
My question is: can I say in practice, the action in peek(Consumer action) should be idempotent even though the stateful code in peek() can compile?

You shouldn't because that would imply that the operation can change the final result because an idempotent operation can mutate the object it operates on.
The following example uses an idempotent operation inside the peek() method but changes the result (which is not a good practice according to the documentation you pointed out)
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class SomeClass {
private String state = "some-value";
public void idempotent() {
state = "other-value";
}
#Override
public String toString() {
return "SomeClass{" +
"state='" + state + '\'' +
'}';
}
}
public class Idempotent {
public static void main(String[] args) {
Set<SomeClass> collect = Stream.of(new SomeClass(), new SomeClass())
.peek(SomeClass::idempotent)
.collect(Collectors.toSet());
System.out.println(collect);
}
}
Before the peek() operation the stream is composed of ["some-value", "some-value] and after the peek() with an idempotent operation it's composed of ["other-value", "other-value"].

The Javadoc says that it should be non-interfering, not idempotent, which is not the same thing.
In fact, since it must be non-interfering and can only operate via side-effects, it is likely that it is not idempotent.
The API note even clearly shows a non-idempotent usage example:
This method exists mainly to support debugging, where you want to see
the elements as they flow past a certain point in a pipeline:
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
As you know, System.out.println() is not idempotent since each call produces a new line of output.

Related

What exactly is a ReceivePort / RawReceivePort? And how to find external method implementations in Dart?

I'm currently experimenting with Isolates in dart.
I'm trying to create a wrapper around an Isolate to make it more pleasant to use.
The desired interface is something along the lines:
abstract class BgIsolateInterface {
Future<Response> send<Message, Response>(Message message);
}
I want to have a method that sends a message to the background interface and then return the response to the caller.
To achieve this I figured I have to create a new RawReceivePort or ReceivePort in the send function to reliably get the correct response.
But this would mean I'm essentially creating the port and discarding it. Going against the documentations which states
Opens a long-lived port for receiving messages.
So my questions are:
what exactly are ReceivePorts and RawReceivePorts?
would my use case be valid i.e. have them be created only to read a single response?
should I look at another way of doing things?
Note: Please don't suggest the Flutter compute function as an alternative. I'm looking to do this in a long running isolate so I can share services / state between function calls. I'm just not showing this here to keep the question short.
Thank you very much!!!
Edit #1:
When providing the answer I realised there was also an underling question about how to read the Dart source, more specifically how to find external methods' implementations. That question was added to the title. The original question was just: What exactly is a ReceivePort / RawReceivePort?.
Yesterday, I've searched across the source and I think, I now have the answers. If I'm wrong, anyone more involved with the engine please correct me. This is mostly my speculation.
TLDR:
ReceivePort/RawReceivePorts are essentially int ids with a registered message handler. The SendPort knows to which id i.e. ReceivePort/RawReceivePort it should send the data to.
Yes. But for another use case there is better way.
Change the interface, so we react to states / responses coming from the isolate i.e.
abstract class BgIsolateInterface<Message, Response> {
void send(Message message);
void listen(void Function(Response) onData);
}
Long
#1
I've looked at the implementation and I'm including my findings here also to put a note for my future self on how to actually do this if I ever need to.
First, if we look at the implementation of ReceivePort (comments removed):
abstract class ReceivePort implements Stream<dynamic> {
external factory ReceivePort([String debugName = '']);
external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);
StreamSubscription<dynamic> listen(void onData(var message)?,
{Function? onError, void onDone()?, bool? cancelOnError});
void close();
SendPort get sendPort;
}
We can see the external keyword. Now, this means implementation is defined somewhere else. Great! Where?
Let's open the SDK source and look. We are looking for a class definition of the same name i.e. ReceivePort with a #patch annotation. Also it seems the Dart team follows the convention of naming the implementation files for these external methods with the suffix _patch.dart.
We then find the three of these patch files. Two for the js runtime, one for development and one for production, and one file for the native? runtime. Since, I'm not using Dart for the web, the latter is the one I'm interested in.
In the file: sdk/lib/_internal/vm/lib/isolate_patch.dart we see:
#patch
class ReceivePort {
#patch
factory ReceivePort([String debugName = '']) =>
new _ReceivePortImpl(debugName);
#patch
factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
return new _ReceivePortImpl.fromRawReceivePort(rawPort);
}
}
Ok, so the implementation for ReceivePort is actually a library private _ReceivePortImpl class.
Note: As you can see factory methods don't have to return the same class the method is defined in. You just have to return an object that implements or extends it. i.e., has the same contract.
class _ReceivePortImpl extends Stream implements ReceivePort {
_ReceivePortImpl([String debugName = ''])
: this.fromRawReceivePort(new RawReceivePort(null, debugName));
_ReceivePortImpl.fromRawReceivePort(this._rawPort)
: _controller = new StreamController(sync: true) {
_controller.onCancel = close;
_rawPort.handler = _controller.add;
}
SendPort get sendPort {
return _rawPort.sendPort;
}
StreamSubscription listen(void onData(var message)?,
{Function? onError, void onDone()?, bool? cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
}
close() {
_rawPort.close();
_controller.close();
}
final RawReceivePort _rawPort;
final StreamController _controller;
}
Which as we can see is really just a wrapper around a RawReceivePort where the handler is a StreamController.add method. So, what about the RawReceivePort?
If we look at initial file where ReceivePort is defined we again see. It's just one external factory method and an interface for others.
abstract class RawReceivePort {
external factory RawReceivePort([Function? handler, String debugName = '']);
void set handler(Function? newHandler);
SendPort get sendPort;
}
Luckily, its #patch version can also be found in the same place as the ReceivePorts.
#patch
class RawReceivePort {
#patch
factory RawReceivePort([Function? handler, String debugName = '']) {
_RawReceivePortImpl result = new _RawReceivePortImpl(debugName);
result.handler = handler;
return result;
}
}
Ok, again the actual implementation is _RawReceivePortImpl class.
#pragma("vm:entry-point")
class _RawReceivePortImpl implements RawReceivePort {
factory _RawReceivePortImpl(String debugName) {
final port = _RawReceivePortImpl._(debugName);
_portMap[port._get_id()] = <String, dynamic>{
'port': port,
};
return port;
}
#pragma("vm:external-name", "RawReceivePortImpl_factory")
external factory _RawReceivePortImpl._(String debugName);
close() {
_portMap.remove(this._closeInternal());
}
SendPort get sendPort {
return _get_sendport();
}
bool operator ==(var other) {
return (other is _RawReceivePortImpl) &&
(this._get_id() == other._get_id());
}
int get hashCode {
return sendPort.hashCode;
}
#pragma("vm:external-name", "RawReceivePortImpl_get_id")
external int _get_id();
#pragma("vm:external-name", "RawReceivePortImpl_get_sendport")
external SendPort _get_sendport();
#pragma("vm:entry-point", "call")
static _lookupHandler(int id) {
var result = _portMap[id]?['handler'];
return result;
}
#pragma("vm:entry-point", "call")
static _lookupOpenPorts() {
return _portMap.values.map((e) => e['port']).toList();
}
#pragma("vm:entry-point", "call")
static _handleMessage(int id, var message) {
final handler = _portMap[id]?['handler'];
if (handler == null) {
return null;
}
handler(message);
_runPendingImmediateCallback();
return handler;
}
#pragma("vm:external-name", "RawReceivePortImpl_closeInternal")
external int _closeInternal();
#pragma("vm:external-name", "RawReceivePortImpl_setActive")
external _setActive(bool active);
void set handler(Function? value) {
final int id = this._get_id();
if (!_portMap.containsKey(id)) {
_portMap[id] = <String, dynamic>{
'port': this,
};
}
_portMap[id]!['handler'] = value;
}
static final _portMap = <int, Map<String, dynamic>>{};
}
OK, now we're getting somewhere. A lot is going on.
First thing to note are the: #pragma("vm:entry-point"), #pragma("vm:entry-point", "call") and #pragma("vm:external-name", "...") annotations. Docs can be found here.
Oversimplified:
vm:entry-point tells the compiler this class / method will be used from native code.
vm:external-name tells the compiler to invoke a native function which is registered to the name provided by the annotation.
For instance to know the implementation of:
#pragma("vm:external-name", "RawReceivePortImpl_factory")
external factory _RawReceivePortImpl._(String debugName);
We have to look for DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory. And we find the entry in: runtime/lib/isolate.cc.
DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 0, 2) {
ASSERT(TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
GET_NON_NULL_NATIVE_ARGUMENT(String, debug_name, arguments->NativeArgAt(1));
Dart_Port port_id = PortMap::CreatePort(isolate->message_handler());
return ReceivePort::New(port_id, debug_name, false /* not control port */);
}
We see the port_id is created by PortMap::CreatePort and is of type Dart_Port. Hmmm, and what is a the type definition for Dart_Port.
runtime/include/dart_api.h
typedef int64_t Dart_Port;
OK so the actual internal representation of a RawReceivePort is a signed int stored in 64 bits, and some additional information like the type, state, debug names etc.
Most of the work is then being done in PortMap::CreatePort and other of its methods. I won't go in depth, because quite honestly I don't understand everything.
But from the looks of it the PortMap uses the port_id to point to some additional information + objects. It generates it randomly and makes sure the id is not taken. It also does a lot of different things but let's move on.
When sending a message through SendPort.send, the method essentially calls the registered entry SendPortImpl_sendInternal_ which determines which port to send the information to.
Note: SendPort essentially just points to its ReceivePort and also stores the id of the Isolate where it was created. When posting a message this id is used to determine what kind of objects can be sent through.
The a message is created and passed to PortMap::PostMessage which in turn calls MessageHandler::PostMessage.
There the message is enqueued by a call to MessageQueue::Enqueue. Then a MessageHandlerTask is ran on the ThreadPool.
The MessageHandlerTask essentially just calls the MessageHandler::TaskCallback which eventually calls MessageHandler::HandleMessages.
There the MessageHandler::HandleMessage is called, but this function is implemented by a child class of MessageHandler.
Currently there are two:
IsolateMessageHandler and
NativeMessageHandler.
We are interested in the IsolateMessageHandler.
Looking there we see IsolateMessageHandler::HandleMessage eventually calls DartLibraryCalls::HandleMessage which calls object_store->handle_message_function(). full chain: Thread::Current()->isolate_group()->object_store()->handle_message_function()
The function handle_message_function is defined by the (dynamic?) macro LAZY_ISOLATE(Function, handle_message_function) in runtime/vm/object_store.h.
The property + stores created are used in: runtime/vm/object_store.cc by the: ObjectStore::LazyInitIsolateMembers.
_RawReceivePortImpl is registered to lazily load at the isolate_lib.LookupClassAllowPrivate(Symbols::_RawReceivePortImpl()) call.
As well as, the methods marked with #pragma("vm:entry-point", "call"), including static _handleMessage(int id, var message).
Which is the handler that ->handle_message_function() returns.
Later the DartLibraryCalls::HandleMessage invokes it through DartEntry::InvokeFunction with the parameters port_id and the message.
This calls the _handleMessage function which calls the registered _RawReceivePort.handler.
#2
If we compare the Flutter's compute method implementation. It spins up an Isolate and 3 ReceivePorts for every compute call. If I used compute, I would be spending more resources and loose context between multiple message calls I can have with a long-running Isolate. So for my use case I reason, creating a new ReceivePort everytime I pass a message shouldn't be a problem.
#3
I could use a different approache. But I still wish to have a long running Isolate so I have the flexibility to share context between different calls to the Isolate.
Alternative:
Would be following a bloc / stream style interface and have a method to assign a listener and a method to send or add a message event, and have the calling code listen to the responses received and act accordingly.
i.e. an interface like:
abstract class BgIsolateInterface<Message, Response> {
void send(Message message);
void addListener(void Function(Response) onData);
void removeListener(void Function(Response) onData);
}
the down side is the Message and Response have to be determined when creating the class rather than simply when using the send method like the interface in my question. Also now some other part of the code base has to handle the Response. I prefer to handle everything at the send call site.
Note: The source code of the Dart project is put here for presentation purposes. The live source may change with time. Its distribution and use are governed by their LICENSE.
Also: I'm not C/C++ developer so any interpretation of the C/C++ code may be wrong.
While this answer is long side-steps the questions a little bit, I find it useful to include the steps to search through the Dart source. Personally, I found it difficult initially to find where external functions are defined and what some of the annotation values mean. While these steps could be extracted into a separate question, I think it's useful to keep it here where there was a use case to actually dive deep.
Thank you for reading!

How to pass data down the reactive chain

Whenever I need to pass data down the reactive chain I end up doing something like this:
public Mono<String> doFooAndPassDtoAsMono(Dto dto) {
return Mono.just(dto)
.flatMap(dtoMono -> {
Mono<String> result = // remote call returning a Mono
return Mono.zip(Mono.just(dtoMono), result);
})
.flatMap(tup2 -> {
return doSomething(tup2.getT1().getFoo(), tup2.getT2()); // do something that requires foo and result and returns a Mono
});
}
Given the below sample Dto class:
class Dto {
private String foo;
public String getFoo() {
return this.foo;
}
}
Because it often gets tedious to zip the data all the time to pass it down the chain (especially a few levels down) I was wondering if it's ok to simply reference the dto directly like so:
public Mono<String> doFooAndReferenceParam(Dto dto) {
Mono<String> result = // remote call returning a Mono
return result.flatMap(result -> {
return doSomething(dto.getFoo(), result); // do something that requires foo and result and returns a Mono
});
}
My concern about the second approach is that assuming a subscriber subscribes to this Mono on a thread pool would I need to guarantee that Dto is thread safe (the above example is simple because it just carries a String but what if it's not)?
Also, which one is considered "best practice"?
Based on what you have shared, you can simply do following:
public Mono<String> doFooAndPassDtoAsMono(Dto dto) {
return Mono.just(dto.getFoo());
}
The way you are using zip in the first option doesn't solve any purpose. Similarly, the 2nd option will not work either as once the mono is empty then the next flat map will not be triggered.
The case is simple if
The reference data is available from the beginning (i.e. before the creation of the chain), and
The chain is created for processing at most one event (i.e. starts with a Mono), and
The reference data is immutable.
Then you can simple refer to the reference data in a parameter or local variable – just like in your second solution. This is completely okay, and there are no concurrency issues.
Using mutable data in reactive flows is strongly discouraged. If you had a mutable Dto class, you might still be able to use it (assuming proper synchronization) – but this will be very surprising to readers of your code.

Amazon SWF queries

Over the last couple of years, I have done a fair amount of work on Amazon SWF, but the following points are still unclear to me and I am not able to find any straight forward answers on any forums yet.
These are pretty basic requirements I suppose, sure others might have come across too. Would be great if someone can clarify these.
Is there a simple way to return a workflow execution result (maybe just something as simple as boolean) back to workflow starter?
Is there a way to catch Activity timeout exception, so that we can do run customised actions in such scenarios?
Why doesn't WorkflowExecutionHistory contains Activities, why just Events?
Why there is no simple way of restarting a workflow from the point it failed?
I am considering to use SWF for more business processes at my workplace, but these limitations/doubts are holding me back!
FINAL WORKING SOLUTION
public class ReturnResultActivityImpl implements ReturnResultActivity {
SettableFuture future;
public ReturnResultActivityImpl() {
}
public ReturnResultActivityImpl(SettableFuture future) {
this.future = future;
}
public void returnResult(WorkflowResult workflowResult) {
System.out.print("Marking future as Completed");
future.set(workflowResult);
}
}
public class WorkflowResult {
public WorkflowResult(boolean s, String n) {
this.success = s;
this.note = n;
}
private boolean success;
private String note;
}
public class WorkflowStarter {
#Autowired
ReturnResultActivityClient returnResultActivityClient;
#Autowired
DummyWorkflowClientExternalFactory dummyWorkflowClientExternalFactory;
#Autowired
AmazonSimpleWorkflowClient swfClient;
String domain = "test-domain;
boolean isRegister = true;
int days = 7;
int terminationTimeoutSeconds = 5000;
int threadPollCount = 2;
int taskExecutorThreadCount = 4;
public String testWorkflow() throws Exception {
SettableFuture<WorkflowResult> workflowResultFuture = SettableFuture.create();
String taskListName = "testTaskList-" + RandomStringUtils.randomAlphabetic(8);
ReturnResultActivity activity = new ReturnResultActivityImpl(workflowResultFuture);
SpringActivityWorker activityWorker = buildReturnResultActivityWorker(taskListName, Arrays.asList(activity));
DummyWorkflowClientExternalFactory factory = new DummyWorkflowClientExternalFactoryImpl(swfClient, domain);
factory.getClient().doSomething(taskListName)
WorkflowResult result = workflowResultSettableFuture.get(20, TimeUnit.SECONDS);
return "Call result note - " + result.getNote();
}
public SpringActivityWorker buildReturnResultActivityWorker(String taskListName, List activityImplementations)
throws Exception {
return setupActivityWorker(swfClient, domain, taskListName, isRegister, days, activityImplementations,
terminationTimeoutSeconds, threadPollCount, taskExecutorThreadCount);
}
}
public class Workflow {
#Autowired
private DummyActivityClient dummyActivityClient;
#Autowired
private ReturnResultActivityClient returnResultActivityClient;
#Override
public void doSomething(final String resultActivityTaskListName) {
Promise<Void> activityPromise = dummyActivityClient.dummyActivity();
returnResult(resultActivityTaskListName, activityPromise);
}
#Asynchronous
private void returnResult(final String taskListname, Promise waitFor) {
ActivitySchedulingOptions schedulingOptions = new ActivitySchedulingOptions();
schedulingOptions.setTaskList(taskListname);
WorkflowResult result = new WorkflowResult(true,"All successful");
returnResultActivityClient.returnResult(result, schedulingOptions);
}
}
The standard pattern is to host a special activity in the workflow starter process that is used to deliver the result. Use a process specific task list to make sure that it is routed to a correct instance of the starter. Here are the steps to implement it:
Define an activity to receive the result. For example "returnResultActivity". Make this activity implementation to complete the Future passed to its constructor upon execution.
When the workflow is started it receives "resultActivityTaskList" as an input argument. At the end the workflow calls this activity with a workflow result. The activity is scheduled on the passed task list.
The workflow starter creates an ActivityWorker and an instance of a Future. Then it creates an instance of "returnResultActivity" with that future as a constructor parameter.
Then it registers the activity instance with the activity worker and configures it to poll on a randomly generated task list name. Then it calls "start workflow execution" passing the generated task list name as an input argument.
Then it wait on the Future to complete. The future.get() is going to return the workflow result.
Yes, if you are using the AWS Flow Framework a timeout exception is thrown when activity is timed out. If you are not using the Flow framework than you are making your life 100 times harder. BTW the workflow timeout is thrown into a parent workflow as a timeout exception as well. It is not possible to catch a workflow timeout exception from within the timing out instance itself. In this case it is recommended to not rely on workflow timeout, but just create a timer that would fire and notify workflow logic that some business event has timed out.
Because a single activity execution has multiple events associated to it. It should be pretty easy to write code that converts history to whatever representation of activities you like. Such code would just match the events that relate to each activities. Each event always has a reference to the related events, so it is easy to roll them up into higher level representation.
Unfortunately there is no easy answer to this one. Ideally SWF would support restarting workflow by copying its history up to the failure point. But it is not supported. I personally believe that workflow should be written in a way that it never fails but always deals with failures without failing. Obviously it doesn't work in case of failures due to unexpected conditions. In this case writing workflow in a way that it can be restarted from the beginning is the simplest approach.

JNA: invalid memory access with callback function parameter (struct)

To lone travelers stumbling upon this: see comments for the answer.
...
Writing a Java wrapper for a native library. A device generates data samples and stores them as structs. Two native ways of accessing them: either you request one with a getSample(&sampleStruct) or you set a callback function. Now, here is what does work:
The polling method does fill the JNA Structure
The callback function is called after being set
In fact, I am currently getting the sample right from the callback function
The problem: trying to do anything with the callback argument, which should be a struct, causes an "invalid memory access". Declaring the argument as the Structure does this, so I declared it as a Pointer. Trying a Pointer.getInt(0) causes invalid memory access. So then I declared the argument as an int, and an int is delivered; in fact, it looks very much like the first field of the struct I am trying to get! So does it mean that the struct was at that address but disappeared before Java had time to access it?
This is what I am doing now:
public class SampleCallback implements Callback{
SampleStruct sample;
public int callback(Pointer refToSample) throws IOException{
lib.INSTANCE.GetSample(sample); // works no problem
adapter.handleSample(sample);
return 1;
} ...
But neither of these does:
public int callback(SampleStruct sample) throws IOException{
adapter.handleSample(sample);
return 1;
}
...
public int callback(Pointer refToSample) throws IOException{
SampleStruct sample = new SampleStruct();
sample.timestamp = refToSample.getInt(0);
...
adapter.handleSample(sample);
return 1;
}
Also, this does in fact deliver the timestamp,
public int callback(int timestamp) throws IOException{
System.out.println("It is " + timestamp + "o'clock");
return 1;
}
but I would really prefer the whole struct.
This is clearly not going to be a popular topic and I do have a working solution, so the description is not exactly full. Will copy anything else that might be helpful if requested. Gratitude prematurely extended.

How to map between push parser and pull parser

I have implemented a pull parser that reads a data stream and emits tokens on selected content via a callback handler. This abstract technique is also known as observer pattern (with the callback handler also known as observer) and used for instance in SAX for parsing XML.
The contrary design pattern (is there a name for it?) is to pull the next data token as used for instance in XML parsing with StAX.
One can easily map to a push parser by looping a pull parser:
// push
parser.parse( callback: handler );
// pull
while( token = parser.next ) {
handler(token)
}
But how do I map a push parser to a pull parser?
To adapt a push parser into a pull parser, you have to collect several (all ? depending on what is being parsed and the order of the elements being pushed) into Event objects. And then allow those Events to be pulled.
We can use XML as an example and adapt a SAXHandler into a StAX parser. We also have to implement the methods for XMLStreamReader for iterating over the StAX XMLEvents.
I've never used StAX but it looks like it stores the current state in the XMLStreamReader object. Each call to reader.next() updates the state and the returned values from reader.getName() and reader.getText() etc are updated accordingly.
We can do this several ways from parsing the entire thing in memory first, then iterating through what we've stored in memory, to more complicated techniques such as using multiple threads to parse the XML and block reading the next tag until the user calls next().
For simplicity, I'll just show storing everything in memory
class SAXHandler extends DefaultHandler implements XMLSTreamReader {
//Stax Event objects
List<XMLEvent> events = new ArrayList<>;
int counter=0;
//Stax current tag name and text data updated with calls to next()
private String name, text;
#Override
//Triggered when the start of tag is found.
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
//create a new XMLEvent for the start of the new tag
XMLEvent newEvent = ....
events.add(newEvent);
}
//other SAX methods implemented similarly
...
Now for the StAX methods:
#Override
public XMLEvent next(){
if( !hasNext() ){
throw NoSuchElementException();
}
counter++;
XMLEvent next =events(counter);
//update our content
this.name = next.name;
this.text = next.text;
...
return next;
}
#Override
public boolean hasNext(){
return counter < events.size();
}
...
#Override
public String getName(){
return name;
}
#Override
public String getText(){
return text;
}
}
Hope this helps
What I think you are looking for is Control Inversion, which is not easy in languages which are tied to a stacklike execution model.
C is not quite welded to execution stacks, so you could do this with the (deprecated) Posix getcontext/setcontext/makecontext, or slightly more portably with threads.
In other languages, it is easier, if no less mind-bending. See Scheme's call/cc primitive, this piece of Lua ancient history, or take a look at Python generators (although the latter is not able to invert control without help from the function whose control is to be inverted.)

Resources