I am teaching a course that uses UML as the tool to model systems. In the course we teach sequence diagrams and while preparing the course I found that there is no clear definition of the semantics of an "execution occurrence".
For example. If an object makes a self call "wait for input" and this call is inside an execution occurrence, can the object receive messages? Obviously I think yes, because it is waiting for messages.
But this counters the idea that execution occurrences mean that the object is currently "busy" or "active".
Any help/ideas? My conclusion was to leave the subject and tell the students to disregard execution occurrences. Any better ideas?
Overall, note that Sequence Diagrams don't have precise semantics (and AFAIK, they're not included in the new base UML semantics) so therefore they're more or less "open to interpretation", to suit your specific sketching needs.
In general, what does a Sequence Diagram mean? Is it a universal specification ("this is how the system will always behave" therefore there are no other allowable behaviors)? Or is it an existential specification ("this is a scenario which the system should support" therefore a system that doesn't is incorrect)? Or is it merely a description ("this might happen"). There is no answer, because SDs don't have precise semantics like that.
(Granted, some formalizations do exist, but then it depends what you want to teach.)
Therefore, I don't think that this quesiton has a unique answer:
"If an object makes a self call "wait for input" and this call is inside an execution occurrence, can the object receive messages?"
That said:
According to this tutorial, execution occurence (EO) denotes:
the execution occurrence, or activation of a focus of control
Look also at the next diargam, about self-messaging, where you have nested execution occurences.
Moreover, here it is simply said that EOs are:
moments in time at which actions or behaviors start or finish
Finally, EOs reference execution specifications which represent:
a period in the participant's lifetime when it is (a) executing a unit of behavior or action within the lifeline, (b) sending a signal to another participant or (c) waiting for a reply message from another participant.
I hope it helps :)
Related
The topic of delimited continuations was barely discussed among programming language enthusiasts in the 1990s and 2000s. It has recently been re-emerging as a major thing in programming language discussions.
My hope is that someone can at least authoritatively say whether the continuations underlying Rakudo (as contrasted with Raku) do or don't have each of the six characteristics listed below. I say a bit more about the sort of answer I'm hoping for after the list.
Quoting verbatim (with a formatting touch up) from an online message[1] written by the person driving the work on adding continuations to the JVM:
Asymmetric: When the continuation suspends or yields, the execution returns to the caller (of Continuation.run()). Symmetric continuations don't have the notion of a caller. When they yield, they must specify another continuation to transfer the execution to. Neither symmetric nor asymetric continuations are more powerful than one another, and each could be used to simulate the other.
Stackful: The continuation can be suspended at any depth in the call-stack, rather than in the same subroutine where the delimited context begins when the continuation is stackless (as is the case in C#). I.e the continuation has its own stack rather than just a single subroutine frame. Stackful continuations are more powerful than stackless ones.
Delimited: The continuation captures the execution context that starts with a specific call (in our case, the body of a certain runnable) rather than the entire execution state all the way up to main(). Delimited continuations are strictly more powerful than undelimited ones (http://okmij.org/ftp/continuations/undelimited.html), the latter considered "not practically useful" (http://okmij.org/ftp/continuations/against-callcc.html).
Multi-prompt: Continuations can be nested, and anywhere in the call stack, any of the enclosing continutions can be suspended. This is similar to nesting of try/catch blocks, and throwing an exception of a certain type that unwinds the stack up to the nearest catch that handles it rather than just the nearest catch. An example of nested continuations can be using a Python-like generator inside a virtual thread. The generator code can do a blocking IO call, which will suspend the enclosing thread continuation, and not just the generator: https://youtu.be/9vupFNsND6o?t=2188
One-shot/non-reentrant: Every time we continue a suspended continuation its state is mutated, and we cannot continue it from the same suspension state multiple times (i.e we can't go back in time). This is unlike reentrant continuations where every time we suspend them, a new immutable continuation object that represents a particular suspension point is returned. I.e. the continuation is a single point in time, and every time we continue it we go back to that state. Reentrant continuations are strictly more powerful than non-reentrant ones; i.e. they can do things that are strictly impossible with just one-shot continuations.
Cloneable: If we are able to clone a one-shot continuation we can provide the same ability as reentrant continuations. Even though the continuation is mutated every time we continue it, we can clone its state before continuing to create a snapshot of that point in time that we can return to later.
Aiui continuations aren't directly exposed in Raku, so perhaps the correct answer related to Raku (as against Rakudo) would be "there are no continuations". But that's not clear to me so in the following, in which I describe what I'm hoping might be in an answer if I'm very lucky, I'll pretend it makes some sense to talk about them in the context of both Raku and Rakudo as two distinct realms.
Here's the sort of answer I'm imagining would be possible (though I'm just somewhat wildly guessing at what is actually true):
"As a "100 year" language design, Raku's current underlying semantic [execution?] model requires, at minimum, stackless one-shot multi prompt delimited continuations.
From a theoretic pov, Raku's design can never expand to require that continuations are cloneable but it could theoretically expand to require they are stackful.
Rakudo implements the currently required continuation semantics.
MoarVM has support for these semantics built in, and could realistically track the theoretically possible expansions of requirements if Raku's design ever so expands.
The JVM and JS backends have suitable shims that achieve the same thing, albeit at a cost to performance. It seems plausible that the JVM backend could switch to using continuations that are native to the JVM if it comes to pass that it gets them, provided of course that they meet requirements, but my current impression is that it would likely realistically be perhaps a decade away, or more, before we would need to consider crossing that bridge."
(Or something vaguely like that.)
If an answer also provided a bit more detail on something like the above, perhaps some code links, that would be a particularly awesome addition.
Similarly, if an answer included a couple brief examples of how this continuation power surfaces in current Raku features, and a speculation about how it might one day, say 10 years from now, surface in other features, that would make an answer an over-the-top brilliant one.
PS. Thank you to #Larry who understood things deeply enough to know continuations needed to be part of the picture; to Stefan O'Rear for his contributions, including the initial implementations of what I think are one-shot multi prompt delimited continuations; and to jnthn for making the dream come true.
Footnotes
1 There is work underway to introduce continuations as a first class construct to the JVM. A key driver of this effort is Ron Pressler. The above is based on a message he wrote in November.
Rakudo uses continuations as an implementation strategy for two features:
gather/take - for implementing lazy iterators
Making await on the thread pool non-blocking
The characteristics of the continuations implemented follow the requirements of these language features. I'll go through them in a slightly different order than above because it eases explaining.
Stackful - yes, because we need to be able to do the take or await at any depth in the callstack relative to the gather or the thread pool worker's work loop. For example, you could write a recursive graph traversal algorithm inside of a gather and then take each encountered node. For await, this is at the heart of the difference between Raku's await and await as seen in many other languages: you don't have to refactor all the way up the call stack.
Delimited - yes. The continuation reset operation installs a tag (or "prompt"), and when we do a continuation control operation, we slice the stack at this delimiter. I can't imagine how you'd implement the Raku features involved without them being delimited.
Multi-prompt - yes, this is required because you can be iterating one data source provided by a gather inside of another gather's implementation, or do an await inside of a gather.
Asymmetric - after the continuation has been taken, execution continues after the reset instruction. In the await case, we go and find another task in the worker task queue, and in the take case we're back in the pull-one method of the iterator and can return the taken value. I think this approach fits well in a language where only a few features use continuations.
One-shot/non-reentrant - yes, and at least in MoarVM the memory safety of the runtime depends on this property. It is enforced by an atomic compare and swap operation, so if two threads were to race to invoke the continuation, only one could ever succeed. No Raku features need the additional complexity that reentrant continuations would imply.
Cloneable - no, because no Raku features need it. In theory this isn't too awful to implement in MoarVM in terms of saying "yes, we can do it", but I suspect it raises a lot of questions like "how deep should be clone". If you just cloned all the invocation records and similar, you'd still share Scalar containers, Arrays, etc. between the clones.
As I understand it - though I follow from a distance - the JVM continuations are at least partly aimed at the same design space that the Raku await mechanism is in, and so I'd be surprised if they didn't end up providing what Raku needs. This would clearly simplify compilation of Raku code to the JVM (currently it does the global CPS transform as it does code generation, which curiously turned out simpler than I expected), and it'd almost certainly perform much better too, because the transform required probably obscures quite a few things from the perspective of the JIT compiler.
So far as code goes, you can see the current continuations implementation, which uses the continuation data structure which in turn has various bits of memory management. At the time of writing, these have all been significantly refactored as part of the new callstack representation required by ongoing dispatcher work; those changes do make working with continuations more efficient, but don't change the overall set of operations.
I just start to learn design patterns, one is the command pattern. After reading some materials and some documentations, such as
http://www.oodesign.com/command-pattern.html
https://www.tutorialspoint.com/design_pattern/command_pattern.htm
I got the idea of using command pattern for stock buying and selling. The client can first decide which stock he/she would like to sell or buy and then let the agent/broker to invoke the command's execute function. I think this makes sense.
While another 'classic' example is restaurant, which confuses me for quite a while. As a customer, how can a customer know which cook (receiver) will be able to cook the item (soup or grill in the example)? The cook shall be not decided by the customer I think. Can anyone point me out how I should approach this idea?
Thanks!
I believe you're not thinking about the restaurant example correctly. A customer doesn't give it's order directly to the cooks, a waitress takes the order to the kitchen and puts it in the queue where the cooks can take an order to make when they're available.
In code, this would look like a shared queue that the waitress adds to, and the cooks are in a continuous loop where they cook something then take the next order that they are able to cook. The command pattern in this example is simply the order that gets transferred from the customer to the kitchen.
Actually, your question is out of the scope of the problem what the command pattern actually tries to solve.
If you are familiar with Java, you can easy have an idea of Command Pattern from Java threads. Actually Thread.run() (not only run()) is command pattern in a nutshell.
The main idea is, if we have some group of objects (concrete Command objects which extends Command interface) which have an important functionality, implement that with a method which is not rigid with any method parameters or types. So that any invoker(CommandHandler) which wants to execute that functionality can actually execute that without knowing what the concrete class is. It can execute someCommandObject.execute();. Only requirement is to be an instance of Command interface.
In Java threads example, let's think about the JVM/Operating system. You know that any program goes to that level as a thread where the program in execution resides as that thread's process. So that thread executor can executes any threads process by anyThread.start(), anyThread.sleep() etc.
In the restaurant example the actual command objects are SoupOrder, GrillOrder etc. The CommandHandler is Waiter. Think about a situation where we introduce another command object called LunchOrder which is a child of Command class and implements void execute(){}. Now you don't have to make any change to the invoker (Waiter) since it still can call up lunchOrder.execute(). So the publishers(command objects) and client(invoker) implementation is decoupled. That's the beauty of Command pattern.
You may refer this also. :))
I'm including my own branching rule on SCIP and I'm using the SCIPincludeBranchruleMybranchingrule() function to initialize some branching rule data. One of the things I do is to call the SCIPgetNVars() function. When I run the code, I see that the function is called many times (not once, as I thought, before the B&B algorithm starts) and I get the following error triggered by the SCIPgetNVars() function:
[src/scip/scip.c:10048] ERROR: invalid SCIP stage <0>
I'm confused about the use of SCIPincludeBranchruleMybranchingrule(), since the documentation states that this function can be use to initialize branching rule data. I would like to initialize some data that can be used at every B&B node, maybe the branching rule data is not the right way of doing it.
I'll appreciate any help!
The important thing to note here is that there is no problem available yet for which you want to access the variables.
Branching rules of SCIP provide several callbacks for data initialization. The include-
callback is only called once when SCIP starts, aka in the SCIP_STAGE_INIT stage of SCIP.
At this stage, you want the branching rule to inform SCIP that it exists, and optionally introduce some user parameters that are problem-independent.
There are two more callback-functions that allow for storing data which are better suited for what you intend to do; SCIPbranchruleInitsolMybranchingrule which is called just before the (presolved)
problem is about to be solved via branch-and-bound, and SCIPbranchruleInitMybranchingrule, which is called after a newly read problem was transformed.
Since the execution of a branching-rule is restricted to within the branch-and-bound-process, your callback is SCIPbranchruleInitSolMybranchingrule which you should implement by moving all problem specific data initialization there. Don't forget to also implement SCIPbranchruleExitsolMybranchrule to free the stored data every time the branch-and-bound search is terminated, either if search was terminated, or if a time limit was hit, or SCIP decided that it wants another restart.
FYI: Data that is allocated during the include-callback can be freed with the SCIPbranchruleFreeMybranchingrule-callback, which is executed once when SCIP is about to exit and free all left system-memory.
I'm having trouble wrapping my head around state-based functionality for an invoicing system we are currently building. The system will support calculation, manual approval, printing, and archiving of invoices.
At first I thought we should use the State Pattern to model this. An invoice would be the context, which delegates printing, archiving, etc. to its currently assigned state.
But this is obviously a bad idea, because the different states (created, approved, printed, archived) should not support the same operations. E.g., you shouldn't be able to print an invoice, which hasn't been approved before. Throwing exceptions for unsupported operations would be a violation of LSP. I found a general description of this problem here.
Does anybody have an idea, how to implement this appropriately?
PS: I'm aware that this might sound like some lame-ass homework assignment, but it's not; I need this for a real world system.
You're basically creating a workflow of application states, where at each state the available operations on an invoice change. The state pattern doesn't seem appropriate, but you can still use it if you also create some operations like boolean canPrint() that would have to be used before calling print(). print() would have a contract that allows throwing exceptions if canPrint() returns false. This way, subclasses wouldn't break that contract. Another option is to have a boolean tryPrint(), that will only print if it can, and return whether it printed.
But, if the states support mostly non-overlapping operations, then maybe the state pattern is not the solution. Take a step back and look for better ways, without trying to fit a specific pattern to your problem. One way is to create a separate class with the necessary operations for each "state": like CreatedInvoice, ApprovedInvoice, etc. These classes would only have the operations they support.
Chain of Responsibility Pattern might help you here.
Adding the how part and fixing the link.
There can be Calculator, Approver, Printer and Archiver classes which are handler classes. These can have processRequest() overridden from a parent abstract class. Invoice can be a class which is passed to each handler's processRequest() method. The advantage with using the pattern here is newer handlers can be added dynamically and chain links with sequence of handlers can be changed easily.
Whether the State Pattern is really appropriate to your situation is not certain, but if it's not, Liskov is not the reason. Throwing some sort of "invalid operation in current state" exception can be defined as possible and valid in the state interface, and then subclasses doing this do not violate LSP.
The classic example used for the State Pattern in the GoF Design Patterns book is a TCPConnection, which definitely has operations not supported or sensible in all states. You can't transmit on a closed connection, for example.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
I'm looking for a definition of 'exceptional' in terms of unit testing or OOP principles. Several times on SO when talking about exception throwing, I've seen comments like, "Well, I wouldn't consider getting Foo from Bar to be exceptional." (Is there a trollface emoticon?)
I did some googling and an answer wasn't immediately forthcoming. Are there any good definitions, rules of thumb, or guidelines that are more objective than opinion or preference? If one person says "this is exceptional" and another says "no, it isn't", how does one resolve this dispute?
Edit: Wow, so there are a number of answers already, with comments that disagree, and they all seem to be the opinion of the answerers :P Nobody's referenced a wikipedia page or an article a snippet from a greybeard. The 'meta-answer' I'm taking from this is there is no agreed-upon rule of thumb for when to use exceptions. I feel more confident employing my own, personal, idiosyncratic rules when choosing to throw exceptions.
I disagree with the other answers about something needing to be "exceptional" to warrant an "exception". I say "exceptional" is any time you want to break the normal flow of control in the way you can by throwing an upward-propagating object.
Exceptions are a language feature. They're a means to an end. They aren't magical. Like any other feature, when you use them should be guided by when you need what they can provide, not by what they are called.
It's exceptional if:
It is a failure condition. AND
It happens infrequently and
unexpectedly. AND
There is no better mechanism for
reporting it.
edit
Stealing blatantly from Dan Weinreb's blog entry, which Ken posted about here, I'd like to offer the following summary of what exceptions are about.
The method's contract defines how
(and whether) unusual conditions
(ie. failures) are signaled. If the
method says something is an
exception, it just is. Of course,
this leaves open the question of how
we should design the contract.
Exceptions have the benefit of not
requiring any checking by the
caller, as well as naturally
bubbling up until they are caught by
something able to handle them. They
can also contain significant detail,
user-readable text and stack traces.
These features make them ideal for
failure cases that prevent further
processing but are not predictable
or common, or where explicit
error-handling would be disruptive
to code flow. They are especially
good for errors that "should never
happen" but are catastrophic in
effect (such as a stack overflow).
Flags, error codes, magic values
(NULL, nil, INVALID_HANDLE, etc.)
and other return-based mechanisms do
not commandeer flow, and are
therefore better suited for cases
that are common and best handled
locally, especially those where the
failure can be worked around. As
they operate by convention and not
fiat, you cannot count on them to be
detected and handled, except that an
invalid value may be designed to
cause an exception if actually used
(such as an INVALID_HANDLE being
used to read).
When using exceptions in robust
code, each method should catch
unexpected exceptions and wrap them
inside an exception from the
contract. In other words, if your
method does not promise to throw
NullReferenceException, you need to
catch it and rethrow it inside
something more general or specific.
They're called exceptions, not
surprises!
The general rule of thumb is:
Use exceptions for errors that you anticipate, and that could happen.
Use assertions to deal with errors that could never happen.
IMHO, an exception should be thrown, if the further execution of program would result in fatal error or unpredictable behaviour.
Personally, I think that this kind of discussion is a pure waste of time and that "what is exceptional" is the wrong question to ask.
Exceptions are just another flow control mechanism with certain advantages (flow of control can pass multiple levels up the call stack) and disadvantages (somewhat verbose, behaviour is less localized).
Whether it's the right choice should not be determined by its name. Would we have these discussions if exceptions were simply called "bubbleups" instead?
When someone rips out the power chord, that is exceptional, most of the other situations are expected.
Well, Exceptional programming case is one which deviates the program flow from normal stream and it might be due to:
::A h/w of s/w fault that programmer cannot handle in given situation. Programmer may be not sure what to do in those case and he left it to the user or tool/library which invokes this code.
::Even programmer might not be sure the exact environment in which his code will be used and hence it is better to leave the error handling to the one who uses the code.
So exceptional case with a program might be is to use it uncommon environment or with uncommon interactions.
Again uncommon interactions and unknown environments refers to the designers point of view.
So deviation from Normal is exceptional and again it is based on the point of view and context of the programmer.
Is it too round and round?:D
Exceptions are useful when something has gone wrong that's outside the immediate scope of the problem. They should almost never be caught close to where thrown, since if they can be satisfactorily handled there they can be satisfactorily handled without throwing anything.
One example is C++'s containers, which can throw bad_alloc if they can't get the memory they need. The people who wrote the container have no idea what should happen if the container can't get memory. Perhaps this is an expected thing, and the calling code has alternatives. Perhaps this is recoverable. Perhaps this is fatal, but how should it be logged?
Yes, it's possible to pass back error codes, but will they be used? I see lots of C memory allocations without tests for NULL, and printfs that just discard the return value. Moreover, lots of functions don't have a distinguishable error code, like negative for printf and NULL for memory allocation. Where any return value can be valid, it's necessary to find a way to return an error indication, and that leads to more complication than most programmers are willing to deal with. An exception cannot be ignored, and doesn't require lots of defensive code.
The best discussion of this that I've seen is in Dan Weinreb's blog: What Conditions (Exceptions) are Really About.
It's ostensibly about Common Lisp, whose condition system is like a more flexible form of exceptions, but there's almost no Lisp code and you don't need to be a Common Lisp programmer to follow the concepts.
And another good rule of thumb - never use exceptions to catch conditions that you can catch in code.
For example if you have a method divides 2 variables, don't use an exception to catch divide by zero errors, instead do the necessary checks beforehand.
Bad code example:
float x;
try {
x = a / b;
{
catch (System.DivideByZeoException) {
x = 0;
}
Good code example:
if (b == 0)
return 0;
Exceptions are generally expensive.
I'm not going to get into the holy war of whether exceptions ought to be used as flow control or not, but rather I'm going to focus on what an exceptional event is...
Oracle, in the context of Java, defines an exceptional event this way:
An exception is an event, which occurs
during the execution of a program,
that disrupts the normal flow of the
program's instructions.
Of course, this definition applies to exceptions in general, not just in Java.
The key here is "disrupts the normal flow". In other words, the program fails in such a way that it can't complete its instructions.
A program has a defined range of functionality. When all your program's functionality is accounted for (including handling of invalid input), anything that is left over is an exception and likely a bug.
I believe there are two kinds of exceptions:
Bugs, which are introduced into the program by the programmer.
Uncontrollable situations, like someone else said, pulling the power plug. Of course, the program wouldn't get to throw an exception in this case, but if it could, it would. Other exceptions might be some sort of failure within the OS or network that the program relies on.
For instance: A program ought to handle invalid input from users as part of its normal flow, because users will of course give you invalid input at some point. This isn't a disruption because the program's functionality should be able to parse input and see if it's valid.
However, if a programmer somehow allows null to be passed to a method that isn't supposed to accept null, then that's an exception. The method's behavior is undefined for values of null. While it's a gray area, the reason I don't necessarily consider this invalid input like the above example is because the method has a certain spec, and by coding something into the program that passes a value violating that spec, it's a bug.
Exception should be used for things you can't control within your program. Most of time, this means you are working with external files or an internet/database connection.
For user input, YOU should control it before you compute anything with it.
Of course there is a limit to what you can expect and you should stop before reaching the "armless person exception". We came up with this term when we were programming something with movement detector and one of our friend was over-protecting his code. So we told him: "Yeah so, did you control what happens if an armless person put his hand in front of the detector?". We got a good laugh with it :)
Two main cases:
When calling code has asked you to do something unreasonable.
When outside dependencies have left you with nothing reasonable to do.
In the first case consider a method int IntegerDivide(int dividend, int divisor). Now, we all know we should catch conditions like dividing by zero ourselves. However, if the calling code has asked this method to divide by zero, it's too late - it's not our code that is deciding to divide by zero, it's the calling code. The only reasonable thing to do here is to throw an exception.
In the second case, consider a component that reads a file and returns some sort of computed result, and what it should do when it fails to open the file. If we had access to the user interface, then we should catch this failure and present a useful and informative message to the user. However we don't, as we're writing a component for use by other code closer to the UI. Again, the only thing we can do is throw an exception (and hope that the calling code does the right thing when it comes to informing the user).