Tired? Mag it! Down? Mag time! Liver damage? MAXIMUM MAG! You’re about to become a magnesium-based lifeform. The age of the primitive carbon-man is done. —DE
These features are the core of Mag, and need to be implemented to make it usable.
- Opt-in mutability
- Sound type checker for JS primitives
- Structs & traits
- Fat enums
- Compile-time functions
- Same-scope shadowing
These features are important and would make working with Mag much more pleasant.
- Pattern-matching (prior design: Kotlin's
when
, Rust'smatch
or Python's match) - Everything as a expression (
if
,return
,throw
, ...) - Collection if
- Extension methods
- Interfaces for structural typing
- Operator overloading
- Interop between signals (ie. Svelte's stores), events and promises
- Optional borrow checker
- Proper function overloading
These features are sexy af and would turn Mag into one of those languages CS students nerd out about.
- Declarative-reactive data types (modeled after Svelte's components but more general) with automatic signal wrapping & unwrapping
- Resumability (resume code on a different machine) and RPCs
- Type refinements (like C#'s contracts or LiquidHaskell's type predicates)
- Effects – a generalization of
throw
,await
andyield
(see the Effekt language) - Build to WASM
- Some kind of DSLs, maybe wrapped in
`
or```
- Pure and invertible functions for use in two-way data binding
These are random thoughts and ideas that might be cool to implement, but also maybe not.
- Named parameters (kwargs)
- Pipe operators, monadic operators
- Block-level return (return from a block, not from a function)
- Utf-8 strings with good utilities
- Lazy evaluation
- Trileans
- Cancellable async function
- Parametric modules, import stubs, import with
-
\
– anonymous type union, effects -
|>
– regular pipe,a |> b(%) === b(a)
-
.>
– pointwise pipe,a .> b(%) === a.map(b)
-
:>
– flatmap pipe,a :> b(%) === a.flatMap(b)
-
=>
– lambda function -
->
– function type,let f: number -> number = x => 2 * x
-
>
– block return -
|> case
– pattern-match over argument (map over type union),x |> case [1, n] => [n, 1]
-
|> handle
– handle effect in argument,x |> handle Yield(n) => 2 * n
-
match
,case
,handle
,rematch
– recursive matching -
do
vsraise
(there's conflict between Effekt'sdo
and a JS proposal) -
?
suffix for nullable-like types, for examplenumber?
fornumber \ NaN
- in TS it is impossible to do this:
<T extends A | B>(x: T, y: T): A[] | B[] => [x, y]
– both x and y can be a union, there is no way to force them to be concrete types