Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

A tomato pasta recipe (in programming languages)

cli345

Coder
Hi, I've already told you about FuncSug :)
Here is a tomato pasta recipe.

In a recipe, there are actions done together with other actions. For example, the sauce is prepared while the pasta is cooking.

I suggest to code it in your favorite language and give me your opinion about my code.

Code:
parallel ||
    heatWaterToBoilingPoint()
    putPastaIntoWater()
    waitSeconds(10*60)
    turnOffTheWaterHeat()
||
    turnOnTheOilHeat()
    putGarlicIntoOil()
    putTomatoesIntoOil()
    putBasilIntoOil()
    waitSeconds(3*60)
    turnOffTheOilHeat()
transferPastaFromWaterPanToOilPan()
season()
putCheese()

What is your version?
 
Originally Java didn't have anything so neat BUT the latest Java release includes new threading classes that work in much the same way. A StructuredTaskScope lets you fork multiple threads then wait for them all to complete before continuing
Java:
        var scope = new StructuredTaskScope();
        scope.fork(() -> {
            heatWaterToBoilingPoint();
            putPastaIntoWater();
            waitSeconds(10 * 60);
            turnOffTheWaterHeat();
        });
        scope.fork(() -> {
            turnOnTheOilHeat();
            putGarlicIntoOil();
            putTomatoesIntoOil();
            putBasilIntoOil();
            waitSeconds(3 * 60);
            turnOffTheOilHeat();
        });
        scope.join(); // wait for all forks to complete
        transferPastaFromWaterPanToOilPan();
        season();
        putCheese();

of course, being Java there's also a ton of stuff fo handing errors, timeouts etc
 
Last edited:
Thank you for your feedback :).
Yes, this is included in structured concurrency which, nowadays, is available for more and more programming languages (see this list). That's very good indeed :).
Few programming languages include structured concurrency natively: Apart from Java and Swift, I don't know of any others.
 
I could also have written:

Code:
parallel ||
    @heatWater_branch
    heatWater()
||
    waitBoiling()
    putPastaIntoWater()
    waitSeconds(10*60)
    break heatWater_branch
||
    @heatOil_branch
    heatOil()
||
    putGarlicIntoOil()
    putTomatoesIntoOil()
    putBasilIntoOil()
    waitSeconds(3*60)
    break heatOil_branch
transferPastaFromWaterPanToOilPan()
season()
putCheese()

This time, I need to be able to:
  • name a branch (example: @heatWater_branch),
  • interrupt (example: break heatWater_branch) a named branch from another branch.

What is your version?
 
Java:
The fork method returns an instance of Future that you can use to check its status, get any returned results, cancel it etc eg



Java:
var hwBranch = scope.fork( …
…
    hwBranch.cancel(true);
 
Yes, that's very good! :)

Now more detailed (waitBoiling and heatWater are explicitized):

Note: waitBoiling() is coded: awaitBool (waterTemperature = 100)

Code:
var waterTemperature := 20

def heatWater():
    while true:
        waitSeconds(2)
        if waterTemperature < 100:
            waterTemperature += 1

parallel ||
    @heatWater_branch
    heatWater()
||
    # --> waitBoiling() is explicitized
    awaitBool (waterTemperature = 100)
    
    putPastaIntoWater()
    waitSeconds(10*60)
    break heatWater_branch
||
    @heatOil_branch
    heatOil()
||
    putGarlicIntoOil()
    putTomatoesIntoOil()
    putBasilIntoOil()
    waitSeconds(3*60)
    break heatOil_branch
transferPastaFromWaterPanToOilPan()
season()
putCheese()

What is your version?
 
I think the problem with this model is the “break’. The idea that one thread can arbitrarily terminate/abort another thread sounds like a recipe for disaster. Who knows what state the aborted thread will be in - is the oil fully hot or not? And who’s going to deal with the InterruptedException or equivalent that it’s probably going to throw?
I think the first version was clearer and safer.
 
Thank you very much for your feedback :).

Yes, you're very right. No one can know what state the aborted thread will be in.
In Java (and many contemporary programming languages), the execution threads are, in fact, operating system threads.
These are managed by the operating system according to a non-deterministic scheduler. The consistency of the whole application is managed by means of locks supplied by the programming language. These make aborting a thread very dangerous.

Nevertheless, other languages exist where:
  • execution threads aren't OS threads,
  • and scheduling is supplied by the language and is deterministic.

An iconic instance of these is SugarCubes. In it, the consistency is ensured thanks to the notion of logical clock: the execution is made up of steps, each of which is guaranteed to finish regardless of branch aborting.
 
Ok. Just fyi recent versions of Java have “virtual threads” that exist just in the jvm. They are designed to handle server situations with thousands of threads. There’s a whole load of api enhancements to manage and synchronise them.
 

Buy us a coffee!

Back
Top Bottom