Much of what you type already works
These Python spellings are valid Mycel as they are: and / or / not, print(a, b), f-strings (with {x:.2f} and {x=}), for i, x in items, len(x), x ** 2, variable assignment x = 1 without let, tuple swaps a, b = b, a, list comprehensions [x * 2 for x in xs if x > 1], negative indexes xs[-1], dict lookup d.get(k, default), set operations & | - on Set([1, 2]), x if c else y expressions, and a file that is just statements with no main().
names = ["ana", "bo", "chen"]
for i, name in names {
print(f"{i}: {name}")
}
a, b = 1, 2
a, b = b, a
squares = [x ** 2 for x in [1, 2, 3, 4] if x > 1]
counts = {"a": 10}
tags = Set(["py", "myc"]) & Set(["myc", "fast"])
status = "ok" if "bo" in names else "missing"
print(len(names), "names", f"last={names[-1]}", f"swapped=({a}, {b})")
print(f"squares={squares}, get={counts.get(\"z\", 0)}, tags={tags.sorted()}, status={status}")output0: ana 1: bo 2: chen 3 names last=chen swapped=(2, 1) squares=[4, 9, 16], get=0, tags=["myc"], status=ok
What is different
- Blocks use braces
{ ... }, not a trailing colon and indentation. - Functions are
fn name(args) { ... };defis rejected with an error that says so. else ifinstead ofelif;nilinstead ofNone;true/falsein lower case;throwandcatch e { ... }instead ofraiseandexcept;x => x + 1instead oflambda.- Conditional expressions: both
if c { a } else { b }(Rust/Swift/Kotlin) and Python'sa if c else bwork. - Types are static and inferred. Mismatches are reported before anything runs, so a wrong type never reaches a half-finished program.
- Numbers mix like Python:
n * 1.5yields a Float,10 / 4produces2.5, and whole-number integer division is10.div(4).
n = 10 print(n / 4, n.div(4), n % 4) print(n * 1.5)output
2.5 2 2 15.0
let age: Int = "fifteen" print(age)compiler says
error [E0300]: type mismatch: expected Int, found String --> types.myc:1:16 | 1 | let age: Int = "fifteen" | ^^^^^^^^^ why: the initial value has type String, but Int is required here 1 error, 0 warnings
Every Python habit and what Mycel says
Mycel's compiler recognises words and symbols from other languages. Instead of a generic syntax error you get the language it came from and the Mycel spelling. The full list for Python is below; rows marked works are valid Mycel as you already write them.
def greet(name): print(name)compiler says
error [E0101]: `def` is Python — Mycel writes `fn name(args) { ... }`
--> habit.myc:1:1
|
1 | def greet(name):
| ^^^
why: this word comes from another language
fix: see `mycel help habits`
1 error, 0 warnings| You write | Mycel says |
|---|---|
and / or / not | works: and, or, not work (same as && || !) |
print(a, b) | works: prints the values with a space between |
f"hi {name}" | works: the same: f-strings with {x:.2f} and {x=} |
for i, x in items | works: the same |
len(x) | works: the same |
x ** 2 | works: the same |
no main(): statements at the top | works: the same: a file can just be statements |
x if c else y | works: the same |
x = 1 (no let) | works: the same: the first assignment creates the variable |
a, b = b, a | works: the same |
x in items / not in | works: the same |
[x * 2 for x in xs if x > 1] | works: the same |
xs[-1] | works: the same: negative indexes count from the end |
d.get(k, default) | works: the same |
a & b, a | b, a - b on sets | works: the same; sets are written Set([1, 2]) |
def f(x): | def is Python — Mycel writes fn f(x) { ... } |
elif | elif is Python — Mycel writes else if |
None | None is Python — Mycel writes nil |
True / False | True/False are Python — Mycel writes true / false |
if x: | a : block is Python — Mycel blocks use { ... } |
lambda x: x + 1 | lambda is Python — Mycel writes x => x + 1 |
raise | raise is Python — Mycel writes throw |
except | except is Python — Mycel writes catch e { ... } |
Every row is tested in the compiler, and mycel help habits prints the same list. See also the overview on the Mycel page.
Using Python packages: planned (coming in Phase B)
A compatibility engine so a Mycel program can use Python packages is planned, and the package manager ply already recognises the install flags. The planned form is ply install --py requests. Installing packages from other languages is marked as coming until Phase B lands, and Mycel itself is not released: there is nothing to download yet. The playground runs the real compiler in your browser with no packages.
Run the first example yourself
The Mycel playground opens in your browser. It runs the real compiler in a sandbox with no file, network or storage access, and nothing is sent to a server. For a guided walk through the language, read Learn Mycel.
Other starting points
Mycel is written so a program reads the same whichever language you learned first. Pick the guide closest to yours, or take the full tour.