RULES
<command> <ident> <pragma> <type> : <body>
<command> <ident>
<pragma> <type> :
<body>
<command>
<ident> <pragma> <type> :
<body>
<ident>
<pragma>
<type> :
<body>
...
:
- Required (possible use=
instead forvar
let
const
).<command>
- Keywords (type, proc, etc) or custom macro/templates who consume StmtLists. Gets invoke multiple times when no<ident>
is on it's line (ie, last example).<ident>
- Always first symbol after<command>
.<pragma>
- Optional. Any builtin like ref/pure/etc, but also any macro/template (just like now).<type>
- Optional. Always last before:
, eg after<pragma>
.<body>
- Always after:
CONSISTENT FOR TYPE & PROC
# current syntax..
type Foo*[T] {.pure.} = ref object ...
proc bar*[T](i:int): T {.inline.} = ...
# proposed syntax..
type Foo*[T] pure ref object: ...
proc bar*[T](i int) inline T: ...
CONSISTENT FOR MACROS
# current syntax..
macro init*(head:expr, body:stmt): stmt {.immediate.} =
## builds initializer
proc new*(this:T): T {.inline, noInit.} = ... # '=' enforced
init new*() T {.inline noInit.}: ... # ':' enforced (NOTE: currently {. .} causes ICE)
# proposed syntax..
macro init*(head expr, body stmt) immediate stmt:
## builds initilizer
proc new*(this T) inline noInit T: ... # identical to..
init new*() inline noInit T: ... # ..this macro
CONSISTENT MULTI-USE FOR ALL
# keywords, like 'type' here, can be used in two ways..
type Foo: ... # invokes keyword 'type(Foo, ...)'
type
Foo: ... # invokes keyword 'type(Foo, ...)'
Bar: ... # invokes keyword 'type(Bar, ...)'
# ..macros, like 'class' here, can be used the same ways..
class Foo: ... # invokes macro 'class(Foo, ...)'
class
Foo: ... # invokes macro 'class(Foo, ...)'
Bar: ... # invokes macro 'class(Bar, ...)'
- less noise in syntax (no
{. .}
or=
needed) means it's easier to read, type, and advertise - consistent across almost all idioms means it's easy to learn (better for adoption)
- consistent between builtins and user-defined macros means OOP macros feel like true first-class citizens (good for adoption especially among OOP fans)
# ..same for compiler built-ins, like types..
type Foo ref object:
a, b int
type
Foo ref object:
a, b int
Bar pure ref object:
x, y float
# .. and for procs too..
proc foo(a, b int) int:
a + b
proc
foo(a, b int) int:
a + b
bar(x, y float) float:
x + y
# ..and for all the rest..
var foo int
var
foo int
bar float
const foo float: 10
let foo float: 10
var foo float: 10
# QUESTION: should use '=' for these?
const foo float = 10
let foo float = 10
var foo float = 10
# .. even these!
import foo
import foo: bar
import
foo
bar: baz
if isFoo: foo()
else isBar: bar()
ADITIONAL THOUGHTS
- No "odd man out" means it's really easy to learn, and removes the need {. .} and '=' altogether.
- Could even use 'pub' instead of '*' for symbol exposure (though i have no problem with the later).
- Syntax is basically available today minus the universal-multi-call and ability to put on multiple lines.
- Could optionally use {} brackets for indent-insensitive block, and : for indent-sensitive block
macro init*(head expr, body stmt) immediate stmt:
## makes initializer procs with 'this' var
# ---
const
accDamp = 0.98
var
gavity = Vector.down(0.5)
deltaTime = 1.0
type Ship* inheritable ref object {
acc Vector
vel Vector
}
type
XWing* final Ship:
wingsOpen* bool
TieFighter* final Ship:
target* Ship
proc
acc*(this Ship) inline noInit Vector: this.acc
vel*(this Ship) inline noInit Vector: this.vel
proc update*(this Ship):
this.acc += gravity * deltaTime
this.acc *= accDamp
this.vel += this.acc
init XWing.new*(wingsOpen bool) inline:
this.wingsOpen = wingsOpen
init TieFighter.new*(target Ship) inline {
this.target = target
}
when isMainModule:
var
rebel = XWing.new(false)
enime = TieFighter.new(rebel)
update rebel
update enime
REF AS KEYWORD IDEA
- To help remove T/P prefix. Make 'ref' a keyword like var/let/const and always define objects as non-ref.
type Person:
name* string
age* int
when isMainModule:
var
andrew = Person(name:"Andrew", age:28)
philip = Person(name:"Philip", age:26)
ref
someone = andrew
andrew = philip # copy
echo someone.age # prints '26'