What carries over
From JavaScript: && || !, arrow functions x => x + 1, ?. and ??, // comments, optional semicolons, async/await. From TypeScript: interface, enum, class, generics <T>, type aliases, let x: Type = value, and x!. Closures infer parameter types from usage (double = x => x * 2). Async code works without Promise: an async fn returns the value directly.
double = x => x * 2 var user: String? = nil print([1, 2, 3].map(double)) print(user ?? "anonymous") print(user?.length)output
[2, 4, 6] anonymous nil
What is different
- First assignment declares variables (
x = 1);letbinds immutably, andvarbinds mutably. There is noconst. ==already compares values, so===and!==are not needed.print(x)replacesconsole.log(x);nilreplaces bothnullandundefined.- Strings interpolate with
f"a {x}", not backticks and${x}. fninstead offunction;selfinstead ofthis; nonew: writeFoo();matchinstead ofswitch;x += 1instead ofx++;pub fninstead ofexport function.- TypeScript's
numbersplits intoInt(whole) andFloat(decimal);stringandbooleanareStringandBool; lists are[Int], notnumber[];anyandunknownareAny. - Types are checked before the program runs. Mistakes are caught before code executes.
let n: number = 42compiler says
error [E0211]: `number` is TypeScript — Mycel has `Int` (whole) and `Float` (decimal) --> types.myc:1:8 | 1 | let n: number = 42 | ^^^^^^ why: no type named `number` exists in Mycel fix: see `mycel help habits` 1 error, 0 warnings
Every JS & TS 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 JavaScript and TypeScript is below; rows marked works are valid Mycel as you already write them.
function greet() {
console.log("hello")
}compiler sayserror [E0101]: `function` is JavaScript — Mycel writes `fn name(args) { ... }`
--> habit.myc:1:1
|
1 | function greet() {
| ^^^^^^^^
why: this word comes from another language
fix: see `mycel help habits`
1 error, 0 warnings| You write | Mycel says |
|---|---|
&& || ! | works: the same |
x => x + 1 | works: the same |
x?.y and x ?? y | works: the same |
// comments and ; at line end | works: the same (semicolons are optional) |
async / await | works: the same |
=== and !== | === is JavaScript — Mycel's == already compares values: write == |
function f() {} | function is JavaScript — Mycel writes fn f() { ... } |
const x = 1 | const is JavaScript — Mycel writes let (var for a value that changes) |
console.log(x) | console.log is JavaScript — Mycel writes print(x) |
null / undefined | undefined is JavaScript — Mycel writes nil |
this.x | this is JavaScript/Java — Mycel writes self.n |
new Foo() | new is JavaScript/Java — Mycel writes Foo() |
switch (x) { case 1: } | switch — Mycel writes match x { 1 => ... } |
x++ | x++ — Mycel writes x += 1 |
template ${x} | backticks are JavaScript — Mycel writes f"a {x}" |
import x from 'y' | import ... from is JavaScript — Mycel writes import std.fs |
interface / enum / class | works: the same keywords |
x! and x?.y | works: the same |
generics <T> | works: the same |
let x: Type = value | works: the same (types are Int, Float, String, Bool) |
type Alias = ... | works: the same |
async/await, Promise-style code | works: the same without Promise: async fn returns the value |
number | number is TypeScript — Mycel has Int (whole) and Float (decimal) |
string / boolean | string — Mycel writes String; boolean is Bool |
any / unknown | any is TypeScript — Mycel writes Any |
const / function | const is JavaScript/TypeScript — Mycel writes let |
number[] | number is TypeScript — Mycel writes [Int] for a list of whole numbers |
x as number | number is TypeScript — Mycel has Int and Float |
string[] | Mycel writes a list type as [String] |
export function | export is TypeScript — Mycel writes pub fn f() { ... } |
Every row is tested in the compiler, and mycel help habits prints the same list. See also the overview on the Mycel page.
Using npm packages: planned (coming in Phase B)
A compatibility engine so a Mycel program can use npm packages is planned, and the package manager ply already recognises the install flags. The planned forms are ply install --npm lodash and ply install --ts @types/node. 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.