TodePond / DreamBerd

perfect programming language
https://dreamberd.computer
Other
10.62k stars 299 forks source link

[RFC] Non deterministic computing #653

Open SkyaTura opened 1 week ago

SkyaTura commented 1 week ago

Non-deterministic computing

Many languages have complex strategies to deal with parallelism, DreamBerd actually solve this problem by leveraging the power of quantum physics. This also makes DreamBerd an optimal choice for developing extremely complex scientific projects as well.

Disclaimer

Over the years, the concept of "quantum physics" has gained a huge superposition of meanings, which wouldn't be intuitive for most users. For the sake of simplicity, DreamBerd uses well known concepts as keywords instead.

box function

The box function declaration creates a quantum realm of a new non-deterministic function to a given name. The schrödinger's and measure keywords are permitted within the function body, enabling superposition of values, parallel-based behavior to be written in a cleaner style and avoiding the need to explicitly configure non-deterministic chains.

schrödinger's variables

The special schrödinger's declaration declares superposition states. The value of a schrödinger's is all possible states declared at the same time.

schrödinger's const const isCatAlive = |true|false|!

This means isCatAlive is BOTH true and false at the same time.

In fact, you can actually use both as variable to achieve this behavior:

schrödinger's const const isCatAlive = both!

It's also possible to indicate the odds of each value being observed upon measurement:

schrödinger's const const isCatAlive = |33%>true|67%>false|! // make sure that the odds sum up to 100%

schrödinger's const const isCatAlive = |33%>true|66%>false|! // this has 1% chance of throwing `Paradox pointer exception`

Important: schrödinger's variables can only be declared inside box functions. And all box functions return schrödinger's values.

measure

You can measure a schrödinger's variable to get one of the possible values in it.

schrödinger's const const isCatAlive = both!
print measure isCatAlive // false

Be careful, measuring a schrödinger's variable will make it deterministic again. In the example above you just killed the cat by printing it.

You cannot measure a schrödinger's value outside of a box function.

entanglement

entanglement is a special variable type that allows you to split a variable into another with shared states:

schrödinger's const var foo = |"foo"|"bar"|!
schrödinger's const entanglement bar = foo!

if measure foo ==== measure bar
   print "true"

Performance

Unlike any other programming language, DreamBerd's box function does not rely on threads or multiple cores. Instead, it uses cutting edge science concepts to manipulate sub-atomic particles to evaluate the results almost instantly, regardless of size and complexity of the algorithm.

Limitations

Box functions relies on sits (schrödinger's bits), they are not supported by normal CPUs.

A new tool is being developed to build DreamBerd runtimes in a way that, if the code includes non-deterministic behavior, the CPU instructions are overwritten to support sits upon the first run, along with the RAM and storage as well.

Note: As of today, private beta users of this tool must agree that converted hardware cannot be reverted to normal CPU again, and can only run non-deterministic routines forever...

Bonus

This feature can be used to emulate the concept of loops on DreamBerd in a simple way:

// Define the box function to calculate Pi using superposition
box fuct calculatePi(pointsInsideCircle, totalPoints) {
    // Generate random points in the unit square
    schrödinger's const const x = both!
    schrödinger's const const y = both!

    // Check if the point is inside the unit circle
    schrödinger's const const isInsideCircle = (x * x + y * y <= 1.0)!

    // Update pointsInsideCircle based on the result
    schrödinger's const const updatedPointsInsideCircle = 
        if measure isInsideCircle 
        then measure pointsInsideCircle + 1 
        else measure pointsInsideCircle!

    // Increment total points
    schrödinger's const const updatedTotalPoints = measure totalPoints + 1!

    // Calculate the current value of Pi
    schrödinger's const const currentPi = (4.0 * measure updatedPointsInsideCircle / measure updatedTotalPoints)!

    // Return a superposition of currentPi and the recursive call to calculatePi
    schrödinger's const const nextPi = calculatePi(updatedPointsInsideCircle, updatedTotalPoints)!
    return |currentPi|nextPi|!
}

// Initial call to calculatePi with 0 points inside the circle and 0 total points
schrödinger's const const pointsInsideCircle = 0!
schrödinger's const const totalPoints = 0!

// Measure the result of the recursive function
schrödinger's const const result = calculatePi(pointsInsideCircle, totalPoints)!
print measure result

Ps: I am not a mathematician myself, so, I have no idea if the logic above is correct, but it compiled just fine on my tests

SkyaTura commented 1 week ago

This is heavily inspired by #117 #273 #582 and others