Start here¶
This page takes you from nothing to a running program in a couple of minutes. You will run Python in your browser, ask the user a question, open a window, and see what happens when you reach for something d/Python does not support yet. If you already write Python, you already write d/Python: the language is the same. What is new is the toolchain, meaning where a program runs, what it compiles to, and how the compiler tells you when it has reached a limit.
First contact¶
Open the browser playground, replace the editor contents with this, and choose Run (or press Cmd+Enter on macOS, Ctrl+Enter elsewhere):
The status line moves from Compiling… to Finished. What happened in between is the whole idea. The compiler, written in Rust and running as WebAssembly right in your browser tab, read your source, turned it into the compiled program file, .dbc, checked that file, and handed it to the d/OS runtime, the program that runs your compiled code. The runtime is WebAssembly too, and it ran your program in small, bounded steps. No Python interpreter was involved at any point.
A program with a little life in it¶
Now let the program ask you something.
# stdin: "7\n"
secret = 7
print("I am thinking of a number from 1 to 10.")
try:
guess = int(input("Your guess: "))
except EOFError:
guess = 0
except ValueError:
guess = 0
if guess == secret:
print("Exactly right.")
elif guess < secret:
print("Too low.")
else:
print("Too high.")
input() waits for you
In the playground, an answer row appears under the question; type and press Enter. End input raises EOFError inside the program, exactly as an exhausted pipe would; Cancel read instead stops the program with d/OS's standard cancellation message. The desktop command line reads the reply from the terminal. See Ask and Answer.
The number that does not overflow¶
def factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
print(factorial(50))
print(2 ** 100, -7 // 2, -7 % 2)
Integers are Python's integers: they grow as large as you need, floor division rounds toward negative infinity, and the remainder takes the sign of the divisor. Those rules are checked against a reference build of CPython, fixed in advance, by the conformance corpus, the collection of test programs every build must match. See Numbers for the one big limit, floats.
Meet the compiler's no¶
Paste this and run it:
The playground shows 1:9 call tofloatis not supported yet and compiles nothing. That one line is d/Python's promise in miniature: when you use something that is not supported, you get a clear message at the exact line and column, never a program that quietly does something slightly different. The compatibility table lists each of those limits with its reason. Diagnostics & Refusals explains the three different kinds of "no" you will meet.
Two faces¶
A d/Python program comes in two shapes. A module with top-level statements is a console program: it runs top to bottom, prints, maybe asks a question, and stops. A module that marks functions with @dos.on(...) is a window program: d/OS opens a window for it and calls your functions when the window opens, needs drawing, is resized, or receives a key or pointer event, each call in its own short, bounded turn. d/OS calls these the program's two faces.
import dos
count = 0
@dos.on("WINDOW_OPEN")
def opened():
dos.service("SET_TITLE", "My first window")
@dos.on("WINDOW_DRAW")
def draw():
dos.intent("GFX", "BEGIN_FRAME")
dos.intent("GFX", "FILL_RECT", 0, 0, 320, 200, 4226)
dos.intent("GFX", "DRAW_TEXT", 24, 40, "Hello from a window", 1, -1, 4226)
dos.intent("GFX", "DRAW_TEXT", 24, 80, "Keys pressed: " + str(count), 1, 2047, 4226)
dos.intent("GFX", "PRESENT")
@dos.on("ON_KEY")
def on_key(key):
global count
count += 1
dos.service("INVALIDATE")
@dos.on("WINDOW_CLOSE")
def closed():
pass
Run it, switch to the Graphics tab, click the canvas and press some keys. The same source, unchanged, opens a real macOS window from the command line. Console & GUI Faces explains the two shapes; Windows & Events explains the handlers.
The command line¶
On macOS, using the kit, the command-line toolset:
run compiles and executes; a source file that only has a window face opens the native window automatically. The other commands: check validates the compiled output without running it, build writes a .dbc file and a lib/ folder of libraries, each tied to its exact contents by a hash, inspect prints the compiled program's footprint (how big it is) as JSON, trace runs it against a scripted host whose behavior is fully predictable, bindings prints the official list of intents (the named requests your program can make), and package writes a DPK2 application package. Compiler & Artifacts covers each; The macOS Kit describes the self-contained directory the build script produces.
Where next¶
- Writing Python already? Skim Collections for the one-element-type rule, then Compatibility.
- Building something? Your First Game walks through tic-tac-toe.
- Wondering what is real today? Conformance and What Runs Today.