I have seen a few different documentations refer to the term "callbacks" (Flux.jl and some SciML packages) but it is not clear what that means in the context of Julia.
I know that a callback is a function passed as an argument to another function but is there more to it than that? What would the use case for such a paradigm be?
A classic example of use of a callback is the progress bar. A callback is supplied to the function that is doing work within some kind of sequence. At regular intervals during the sequence the callback is called with some kind of information about the work being done (the percent completed in the case of the progress bar, which updates a progress display).
Flux can call a callback each time it completes a segment of training, or in the example in the source code, every 10 seconds:
https://github.com/FluxML/Flux.jl/blob/b78a27b01c9629099adb059a98657b995760b617/src/optimise/train.jl#L80-L95
Related
I think the correct description for what I'm trying to do is be able to pass an expression or function/handler into another handler as a parameter/argument. Some code to be evaluated inside the receiving handler. Similar to Javascript callbacks, I think.
For example, something like this:
on waitFor(theConditionExpression)
timeout_start(5) -- start a 5 second timer
repeat until (theConditionExpression or timeout_isExpired())
delay 0.1
end repeat
return theConditionExpression
end waitFor
theConditionExpression should be some expression or function that evaluates to a boolean result.
not really relevant to the question, but just FYI, timeout_start(…) and timeout_isExpired() are two simple handlers I've written that do exactly what they say. (…start() doesn't return anything, …isExpired() returns a boolean).
Of course, typically if I pass in some boolean expression, it will evaluate that expression once, at the time I pass it in. But I want it to evaluate it every time it's referenced in the code inside the handler.
Some languages (not sure about AS) have some kind of eval() function that you can pass it some code as a string and it will execute that string as code. Theoretically that could solve this, but: (a) I don't know if AS has anything like that, but even if it does, (b) it's not desired for various reasons (performance, injection risks, etc.)
So I'm thinking something more like eg. JavaScript's ability to pass in a function (named or anonymous) as function parameter/argument that can be re-evaluated every iteration in a loop, etc. (eg. like the compareFn argument in JS's Array.sort(compareFn)).
Can AS do anything like this, and if so how?
Thanks!
I'm going to suggest (pro forma) that an AppleScript application with an on idle handler is generally a better solution for wait conditions than a repeat/delay loop. It's more efficient for the system, and doesn't freeze up the script. But that would involve reconceptualizing your script, and I'm not certain it would work in this case, given the way you formed the problem.
There's an old but good site called AppleScript Power Handlers that shows a bunch of nifty-neato tricks for sophisticated use of AppleScript handlers: passing handlers as values or parameters; creating Script Objects within handlers; making closures and constructors. I'm pretty sure the answer to your request is in there. aLikely you'll want to set up a bunch of handlers that serve as condition expressions, then pass them as parameters to the evaluating handler. Or maybe you'll want to set up a script object containing the condition handlers and call it as needed?
At any rate, see what you can do with it, and ask more specific questions if you run into problems.
Is there a way for a PLC program to know its own cycle time?
As a workaround, I can just add a persistent variable or a constant to tell it manually, but that's obviously error prone.
To add to Jakob's answer - you can also use GETCURTASKINDEXEX function (Infosys) instead of GETCURTASKINDEX FB. This way you don't have to instantiate it.
_TaskInfo[GETCURTASKINDEXEX()].CycleTime
Will return cycle time as multiples of 100ns (UDINT)
UDINT_TO_LREAL(_TaskInfo[GETCURTASKINDEXEX()].CycleTime) / 10_000_000
Will return cycle time as seconds (LREAL)
For TwinCAT3 this is available in PlcTaskSystemInfo (variable CycleTime).
Combine it with the FB GETCURTASKINDEX to get the data you want.
See one example (though not cycle-time, but still same FB) here at AllTwinCAT.
This is not directly an answer to your question, but can be used to determine the Cycle time.
I like to use the Time() function. It returns a value of data type TIME. It does not represent an absolute time, but can be used to calculate the time between two calls to Time(). In this way you can calculate the Cycle time.
I use it in function blocks (FB) where timing is critical. In this way the FB knows when it was lastly called instead of assuming that it is being run each scan. Even if I or another user of my FB "forgets" to call the FB each scan, the FB still delivers correct outputs.
You can find info on Time() using this link. There is also a function called LTime() which returns a value of data type LTIME, but it seems that Beckhoff did not bother to document this function.
I am new to GUIs and am learning FLTK in order to produce a multi platform application. In the application a user clicks a button and invokes a time consuming function through the callback. As it takes a long time I would like to update an output widget with the progress of the function. As such I pass the pointer to an Fl_Ouput widget and update using widget->value(x) and widget->redraw(). However, the widget only redraws when the entire callback function is completed making the whole thing pointless as it doesn't update the user in real time. The code is of the form:
void calculate(Fl_Widget* widget,Fl_Output* op){
/*function call to actual code but contains inside a loop:*/
stringstream progress;
progress<<p; //where p is some percentage calculated on the fly in the function
op->value(progress.str().c_str());
op->redraw();
}
int main(){
/*main and GUI code*/
Fl_Output* op = new Fl_Output(100,50,100,10,0);
Fl_Button* go = new Fl_Button(100,100,10,10,"Go");
go->callback((Fl_Callback*) calculate,op);
/*rest of GUI code and main*/
}
My problem is that the widget pointed to by op is not redrawing in sequence when I want it to, when op->redraw() is called, but only after the rest of the code in calculate has executed or, as I suspect, when control leaves the callback function when it is finished executing.
My question is: is there any way to update such a widget in real time when its value is changed and before executing any more code (which may be whilst control is passed to a function)? Or is there a better way?
Thanks,
R.
I assume you did not show us the actual C++ code where the problem you have actually appears, so my first guess is that you are doing a long-running processing in a GUI loop, which is always a bad idea.
To see an almost idiomatic FLTK solution, check the threads example in the test directory (you need to gram FLTK source code - it is good idea to go through all the FLTK examples there - that is how I learned FLTK nearly 2 decades ago).
FLTK Manual touches the topic of multi-threading on this page: http://www.fltk.org/doc-1.3/advanced.html .
By reading some text, especially the iOS document about delegate, all the protocol method are called hook that the custom delegate object need to implement. But some other books, name these hook as callback, what is the difference between them? Are they just different name but the same mechanism? In addition to Obj-C, some other programming languages, such as C, also got the hook, same situation with Obj-C?
The terminology here is a bit fuzzy. In general the two attempt to achieve similar results.
In general, a callback is a function (or delegate) that you register with the API to be called at the appropriate time in the flow of processing (e.g to notify you that the processing is at a certain stage)
A hook traditionally means something a bit more general that serves the purpose of modifying calls to the API (e.g. modify the passed parameters, monitor the called functions). In this meaning it is usually much lower level than what can be achieved by higher-level languages like Java.
In the context of iOS, the word hook means the exact same thing as callback above
Let me chime in with a Javascript answer. In Javascript, callbacks, hooks and events are all used. In this order, they are each higher level concepts than the other.
Unfortunately, they are often used improperly which leads to confusion.
Callbacks
From a control flow perspective, a callback is a function, usually given as an argument, that you execute before returning from your function.
This is usually used in asynchoronous situations when you need to wait for I/O (e.g. HTTP request, a file read, a database query etc.). You don't want to wait with a synchronous while loop, so other functions can be executed in the meantime.
When you get your data, you (permanently) relinquish control and call the callback with the result.
function myFunc(someArg, callback) {
// ...
callback(error, result);
}
Because the callback function may be some code that hasn't been executed yet, and you don't know what's above your function in the call stack, generally instead of throwing errors you pass on the error to the callback as an argument. There are error-first and result-first callback conventions.
Mostly callbacks have been replaced by Promises in the Javascript world and since ES2017+, you can natively use async/await to get rid of callback-rich spaghetti code and make asynchronous control flow look like it was synchronous.
Sometimes, in special cascading control flows you run callbacks in the middle of the function. E.g. in Koa (web server) middleware or Redux middleware you run next() which returns after all the other middlewares in the stack have been run.
Hooks
Hooks are not really a well-defined term, but in Javascript practice, you provide hooks when you want a client (API/library user, child classes etc.) to take optional actions at well-defined points in your control flow.
So a hook may be some function (given as e.g. an argument or a class method) that you call at a certain point e.g. during a database update:
data = beforeUpdate(data);
// ...update
afterUpdate(result);
Usually the point is that:
Hooks can be optional
Hooks usually are waited for i.e. they are there to modify some data
There is at most one function called per hook (contrary to events)
React makes use of hooks in its Hooks API, and they - quoting their definition - "are functions that let you “hook into” React state and lifecycle features", i.e. they let you change React state and also run custom functions each time when certain parts of the state change.
Events
In Javascript, events are emitted at certain points in time, and clients can subscribe to them. The functions that are called when an event happens are called listeners - or for added confusion, callbacks. I prefer to shun the term "callback" for this, and use the term "listener" instead.
This is also a generic OOP pattern.
In front-end there's a DOM interface for events, in node.js you have the EventEmitter interface. A sophisticated asynchronous version is implemented in ReactiveX.
Properties of events:
There may be multiple listeners/callbacks subscribed (to be executed) for the same event.
They usually don't receive a callback, only some event information and are run synchronously
Generally, and unlike hooks, they are not for modifying data inside the event emitter's control flow. The emitter doesn't care 'if there is anybody listening'. It just calls the listeners with the event data and then continues right away.
Examples: events happen when a data stream starts or ends, a user clicks on a button or modifies an input field.
The two term are very similar and are sometimes used interchangably. A hook is an option in a library were the user code can link a function to change the behavior of the library. The library function need not run concurrent with the user code; as in a destructor.
A callback is a specific type of hook where the user code is going to initiate the library call, usually an I/O call or GUI call, which gives contol over to the kernel or GUI subsystem. The controlling process then 'calls back' the user code on an interupt or signal so the user code can supply the handler.
Historically, I've seen hook used for interupt handlers and callback used for GUI event handlers. I also see hook used when the routine is to be static linked and callback used in dynamic code.
Two great answers already, but I wanted to throw in one more piece of evidence the terms "hook" and "callback" are the same, and can be used interchangeably: FreeRTOS favors the term "hook" but recognizes "callback" as an equivalent term, when they say:
The idle task can optionally call an application defined hook (or callback) function - the idle hook.
The tick interrupt can optionally call an application defined hook (or callback) function - the tick hook.
The memory allocation schemes implemented by heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c can optionally include a malloc() failure hook (or callback) function that can be configured to get called if pvPortMalloc() ever returns NULL.
Source: https://www.freertos.org/a00016.html
Is it a function?
Is it a function being called from the source?
Or, is it a function being returned from the destination?
Or, is it just executing a function at the destination?
Or, is it a value returned from a function passed to the destination?
A callback is the building block of asynchronous processing.
Think of it this way: when you call someone and they don't answer, you leave a message and your phone number. Later on, the person calls you back based on the phone number you left.
A callback works in a similar manner.
You ask an API for a long running operation and you provide a method from within your code to be called with the result of the operation. The API does its work and when the result is ready, it calls your callback method.
From the great Wikipedia:
In computer programming, a callback is
executable code that is passed as an
argument to other code. It allows a
lower-level software layer to call a
subroutine (or function) defined in a
higher-level layer.
Said another way, when you pass a callback to your method, it's as if you are providing additional instructions (e.g., what you should do next). An attempt at making a simple human example follows:
Paint this wall this shade of green (where "paint" is analagous to the method called, while "wall" and "green" are similar to arguments).
When you have finished painting, call me at this number to let me know that you're done and I'll tell you what to do next.
In terms of practical applications, one place where you will sometimes see callbacks is in situations with asynchronous message passing. You might want to register a particular message as an item of interest for class B.
However, without something like a callback, there's no obvious way for class A to know that class B has received the message. With a callback, you can tell class B, here's the message that I want you to listen for and this is the method in class A that I want you to call when you receive it.
Here is a Java example of a callback from a related question.