shithub: mc

Download patch

ref: 7aac15b2bfcc5eec279aa14f9f199685f9d7e0d9
parent: c96238b89583ed91e92ad909c507797d00015e95
author: Ori Bernstein <ori@eigenstate.org>
date: Tue May 17 18:00:50 EDT 2016

New syntax for casts.

--- a/bench/runbench.myr
+++ b/bench/runbench.myr
@@ -54,6 +54,6 @@
 		| `std.Wsuccess:	/* nothing */
 		;;
 	;;
-	-> (std.now() - tm castto(flt64)) / 1_000_000.0
+	-> (std.now() - (tm : flt64)) / 1_000_000.0
 }
 
--- a/lib/bio/bio.myr
+++ b/lib/bio/bio.myr
@@ -133,7 +133,7 @@
 
 /* open the file, and return it */
 const sysopen = {path, mode, openmode, perm
-	match std.openmode(path, openmode, perm castto(int64))
+	match std.openmode(path, openmode, (perm : int64))
 	| `std.Ok fd:	-> `std.Ok mkfile(fd, mode)
 	| `std.Fail e:	-> `std.Fail "could not open fd"
 	;;
@@ -352,7 +352,7 @@
 */
 generic putle = {f, v : @a::(numeric,integral)
 	for var i = 0; i < sizeof(@a); i++
-		putb(f, (v & 0xff) castto(byte))
+		putb(f, (v & 0xff : byte))
 		v >>= 8
 	;;
 	-> sizeof(@a)
@@ -364,7 +364,7 @@
 */
 generic putbe = {f, v : @a::(numeric,integral)
 	for var i = sizeof(@a); i != 0; i--
-		putb(f, ((v >> ((i-1)*8)) & 0xff) castto(byte))
+		putb(f, ((v >> ((i-1)*8)) & 0xff : byte))
 	;;
 	-> sizeof(@a)
 }
@@ -448,7 +448,7 @@
 		;;
 		/* scan for delimiter */
 		for var i = f.rstart; i < f.rend; i++
-			c = f.rbuf[i] castto(char)
+			c = (f.rbuf[i] : char)
 			if c == '\r' || c == '\n'
 				ret = readinto(f, ret, i - f.rstart)
 				f.rstart++
@@ -664,7 +664,7 @@
 const errtype : (e : std.errno -> ioerr )= {e : std.errno -> ioerr
 	var errno
 
-	errno = e castto(std.errno)
+	errno = (e : std.errno)
 	if errno == std.Ebadf
 		-> `Ebadfile
 	elif errno == std.Einval
--- a/lib/bio/geti.myr
+++ b/lib/bio/geti.myr
@@ -29,9 +29,9 @@
 	| `Err e :	-> `Err e
 	| `Ok _:
 		for i = 0; i < n; i++
-			v |= (f.rbuf[f.rstart++] castto(uint64)) << (8*(i castto(uint64)))
+			v |= (f.rbuf[f.rstart++] : uint64) << (8*(i : uint64))
 		;;
-		-> `Ok v castto(@a::(numeric,integral))
+		-> `Ok (v : @a::(numeric,integral))
 	;;
 }
 
@@ -49,9 +49,9 @@
 	| `Ok _:
 		for i = 0; i < n; i++
 			v <<= 8
-			v |= (f.rbuf[f.rstart++] castto(uint64))
+			v |= (f.rbuf[f.rstart++] : uint64)
 		;;
-		-> `Ok v castto(@a::(numeric,integral))
+		-> `Ok (v : @a::(numeric,integral))
 	;;
 }
 
--- a/lib/bio/iter.myr
+++ b/lib/bio/iter.myr
@@ -9,12 +9,12 @@
 ;;
 
 const byline = {f
-	-> f castto(lineiter)
+	-> (f : lineiter)
 }
 
 impl iterable lineiter -> byte[:] =
 	__iternext__ = {itp, outp
-		match bio.readln(itp# castto(file#))
+		match bio.readln((itp# : file#))
 		| `Ok ln:
 			outp# = ln
 			-> true
--- a/lib/bio/puti.myr
+++ b/lib/bio/puti.myr
@@ -16,15 +16,15 @@
 	generic putle64	: (f : file#, v : @a::(numeric,integral) -> status(std.size))
 ;;
 
-generic putbe8  = {f, v; -> putbe(f, v castto(uint64), 1)}
-generic putbe16 = {f, v; -> putbe(f, v castto(uint64), 2)}
-generic putbe32 = {f, v; -> putbe(f, v castto(uint64), 4)}
-generic putbe64 = {f, v; -> putbe(f, v castto(uint64), 8)}
+generic putbe8  = {f, v; -> putbe(f, (v : uint64), 1)}
+generic putbe16 = {f, v; -> putbe(f, (v : uint64), 2)}
+generic putbe32 = {f, v; -> putbe(f, (v : uint64), 4)}
+generic putbe64 = {f, v; -> putbe(f, (v : uint64), 8)}
 
-generic putle8  = {f, v; -> putle(f, v castto(uint64), 1)}
-generic putle16 = {f, v; -> putle(f, v castto(uint64), 2)}
-generic putle32 = {f, v; -> putle(f, v castto(uint64), 4)}
-generic putle64 = {f, v; -> putle(f, v castto(uint64), 8)}
+generic putle8  = {f, v; -> putle(f, (v : uint64), 1)}
+generic putle16 = {f, v; -> putle(f, (v : uint64), 2)}
+generic putle32 = {f, v; -> putle(f, (v : uint64), 4)}
+generic putle64 = {f, v; -> putle(f, (v : uint64), 8)}
 
 const putle = {f, v, n
 	var buf : byte[8]
@@ -33,14 +33,14 @@
 	| `Eof:	-> `Eof
 	| `Err e:	-> `Err e
 	| `Ok _:
-		buf[0] = (v >> 0) & 0xff castto(byte)
-		buf[1] = (v >> 8) & 0xff castto(byte)
-		buf[2] = (v >> 16) & 0xff castto(byte)
-		buf[3] = (v >> 24) & 0xff castto(byte)
-		buf[4] = (v >> 32) & 0xff castto(byte)
-		buf[5] = (v >> 40) & 0xff castto(byte)
-		buf[6] = (v >> 48) & 0xff castto(byte)
-		buf[7] = (v >> 56) & 0xff castto(byte)
+		buf[0] = ((v >> 0) & 0xff : byte)
+		buf[1] = ((v >> 8) & 0xff : byte)
+		buf[2] = ((v >> 16) & 0xff : byte)
+		buf[3] = ((v >> 24) & 0xff : byte)
+		buf[4] = ((v >> 32) & 0xff : byte)
+		buf[5] = ((v >> 40) & 0xff : byte)
+		buf[6] = ((v >> 48) & 0xff : byte)
+		buf[7] = ((v >> 56) & 0xff : byte)
 		-> write(f, buf[:n])
 	;;
 }
@@ -52,14 +52,14 @@
 	| `Eof:	-> `Eof
 	| `Err e:	-> `Err e
 	| `Ok _:
-		buf[0] = (v >> 56) & 0xff castto(byte)
-		buf[1] = (v >> 48) & 0xff castto(byte)
-		buf[2] = (v >> 40) & 0xff castto(byte)
-		buf[3] = (v >> 32) & 0xff castto(byte)
-		buf[4] = (v >> 24) & 0xff castto(byte)
-		buf[5] = (v >> 16) & 0xff castto(byte)
-		buf[6] = (v >> 8) & 0xff castto(byte)
-		buf[7] = (v >> 0) & 0xff castto(byte)
+		buf[0] = ((v >> 56) & 0xff : byte)
+		buf[1] = ((v >> 48) & 0xff : byte)
+		buf[2] = ((v >> 40) & 0xff : byte)
+		buf[3] = ((v >> 32) & 0xff : byte)
+		buf[4] = ((v >> 24) & 0xff : byte)
+		buf[5] = ((v >> 16) & 0xff : byte)
+		buf[6] = ((v >> 8) & 0xff : byte)
+		buf[7] = ((v >> 0) & 0xff : byte)
 		-> write(f, buf[8-n:])
 	;;
 }
--- a/lib/bio/test/bio-endianrd.myr
+++ b/lib/bio/test/bio-endianrd.myr
@@ -40,7 +40,7 @@
 	std.assert(try(bio.getbe32(f)) == l, "be long broken\n")
 
 	/* quad */
-	q = 0x11223344aabbccdd castto(uint64)
+	q = (0x11223344aabbccdd : uint64)
 	std.assert(try(bio.getle64(f)) == q, "le quad broken\n")
 	std.assert(try(bio.getbe64(f)) == q, "be quad broken\n")
 
--- a/lib/bio/test/bio-endianwr.myr
+++ b/lib/bio/test/bio-endianwr.myr
@@ -33,7 +33,7 @@
 	bio.putbe32(f, l)
 
 	/* quad */
-	q = 0x11223344aabbccdd castto(uint64)
+	q = (0x11223344aabbccdd : uint64)
 	bio.putle64(f, q)
 	bio.putbe64(f, q)
 
--- a/lib/bld.sub
+++ b/lib/bld.sub
@@ -1,5 +1,6 @@
 sub =
 	bio
+	date
 	cryptohash
 	inifile
 	regex
--- a/lib/cryptohash/md5.myr
+++ b/lib/cryptohash/md5.myr
@@ -70,32 +70,32 @@
 	;;
 
         /* append size block */
-	st.tail[56] = ((st.msglen * 8) >> 0)    castto(byte)
-	st.tail[57] = ((st.msglen * 8) >> 8)	castto(byte)
-	st.tail[58] = ((st.msglen * 8) >> 16)	castto(byte)
-	st.tail[59] = ((st.msglen * 8) >> 24)	castto(byte)
-	st.tail[60] = ((st.msglen * 8) >> 32)	castto(byte)
-	st.tail[61] = ((st.msglen * 8) >> 40)	castto(byte)
-	st.tail[62] = ((st.msglen * 8) >> 48)	castto(byte)
-	st.tail[63] = ((st.msglen * 8) >> 56)	castto(byte)
+	st.tail[56] = ((st.msglen * 8) >> 0	: byte)
+	st.tail[57] = ((st.msglen * 8) >> 8	: byte)
+	st.tail[58] = ((st.msglen * 8) >> 16	: byte)
+	st.tail[59] = ((st.msglen * 8) >> 24	: byte)
+	st.tail[60] = ((st.msglen * 8) >> 32	: byte)
+	st.tail[61] = ((st.msglen * 8) >> 40	: byte)
+	st.tail[62] = ((st.msglen * 8) >> 48	: byte)
+	st.tail[63] = ((st.msglen * 8) >> 56	: byte)
         step(st, st.tail[:])
 
-	r[0] = (st.a >> 0)	castto(byte)
-	r[1] = (st.a >> 8)	castto(byte)
-	r[2] = (st.a >> 16)	castto(byte)
-	r[3] = (st.a >> 24)	castto(byte)
-	r[4] = (st.b >> 0)	castto(byte)
-	r[5] = (st.b >> 8)	castto(byte)
-	r[6] = (st.b >> 16)	castto(byte)
-	r[7] = (st.b >> 24)	castto(byte)
-	r[8] = (st.c >> 0)	castto(byte)
-	r[9] = (st.c >> 8)	castto(byte)
-	r[10] = (st.c >> 16)	castto(byte)
-	r[11] = (st.c >> 24)	castto(byte)
-	r[12] = (st.d >> 0)	castto(byte)
-	r[13] = (st.d >> 8)	castto(byte)
-	r[14] = (st.d >> 16)	castto(byte)
-	r[15] = (st.d >> 24)	castto(byte)
+	r[0] = (st.a >> 0	: byte)
+	r[1] = (st.a >> 8	: byte)
+	r[2] = (st.a >> 16	: byte)
+	r[3] = (st.a >> 24	: byte)
+	r[4] = (st.b >> 0	: byte)
+	r[5] = (st.b >> 8	: byte)
+	r[6] = (st.b >> 16	: byte)
+	r[7] = (st.b >> 24	: byte)
+	r[8] = (st.c >> 0	: byte)
+	r[9] = (st.c >> 8	: byte)
+	r[10] = (st.c >> 16	: byte)
+	r[11] = (st.c >> 24	: byte)
+	r[12] = (st.d >> 0	: byte)
+	r[13] = (st.d >> 8	: byte)
+	r[14] = (st.d >> 16	: byte)
+	r[15] = (st.d >> 24	: byte)
 	-> r
 }
 
@@ -207,9 +207,10 @@
 const unpack = {b
 	var v : uint32
 
-	v = ((b[0] castto(uint32)) << 0)
-	v |= ((b[1] castto(uint32)) << 8)
-	v |= ((b[2] castto(uint32)) << 16)
-	v |= ((b[3] castto(uint32)) << 24)
+	v = 0
+	v |= (b[0] : uint32) << 0
+	v |= (b[1] : uint32) << 8
+	v |= (b[2] : uint32) << 16
+	v |= (b[3] : uint32) << 24
 	-> v
 }
--- a/lib/cryptohash/sha1.myr
+++ b/lib/cryptohash/sha1.myr
@@ -74,36 +74,36 @@
 
 
         /* append size block */
-	st.tail[56] = ((st.msglen * 8) >> 56)   castto(byte)
-	st.tail[57] = ((st.msglen * 8) >> 48)	castto(byte)
-	st.tail[58] = ((st.msglen * 8) >> 40)	castto(byte)
-	st.tail[59] = ((st.msglen * 8) >> 32)	castto(byte)
-	st.tail[60] = ((st.msglen * 8) >> 24)	castto(byte)
-	st.tail[61] = ((st.msglen * 8) >> 16)	castto(byte)
-	st.tail[62] = ((st.msglen * 8) >> 8)	castto(byte)
-	st.tail[63] = ((st.msglen * 8) >> 0)	castto(byte)
+	st.tail[56] = ((st.msglen * 8) >> 56	: byte)
+	st.tail[57] = ((st.msglen * 8) >> 48	: byte)
+	st.tail[58] = ((st.msglen * 8) >> 40	: byte)
+	st.tail[59] = ((st.msglen * 8) >> 32	: byte)
+	st.tail[60] = ((st.msglen * 8) >> 24	: byte)
+	st.tail[61] = ((st.msglen * 8) >> 16	: byte)
+	st.tail[62] = ((st.msglen * 8) >> 8	: byte)
+	st.tail[63] = ((st.msglen * 8) >> 0	: byte)
         step(st, st.tail[:])
 
-	r[0]  = (st.a >> 24)	castto(byte)
-	r[1]  = (st.a >> 16)	castto(byte)
-	r[2]  = (st.a >> 8)	castto(byte)
-	r[3]  = (st.a >> 0)	castto(byte)
-	r[4]  = (st.b >> 24)	castto(byte)
-	r[5]  = (st.b >> 16)	castto(byte)
-	r[6]  = (st.b >> 8)	castto(byte)
-	r[7]  = (st.b >> 0)	castto(byte)
-	r[8]  = (st.c >> 24)	castto(byte)
-	r[9]  = (st.c >> 16)	castto(byte)
-	r[10] = (st.c >> 8)	castto(byte)
-	r[11] = (st.c >> 0)	castto(byte)
-	r[12] = (st.d >> 16)	castto(byte)
-	r[13] = (st.d >> 24)	castto(byte)
-	r[14] = (st.d >> 8)	castto(byte)
-	r[15] = (st.d >> 0)	castto(byte)
-	r[16] = (st.e >> 16)	castto(byte)
-	r[17] = (st.e >> 24)	castto(byte)
-	r[18] = (st.e >> 8)	castto(byte)
-	r[19] = (st.e >> 0)	castto(byte)
+	r[0]  = (st.a >> 24	: byte)
+	r[1]  = (st.a >> 16	: byte)
+	r[2]  = (st.a >> 8	: byte)
+	r[3]  = (st.a >> 0	: byte)
+	r[4]  = (st.b >> 24	: byte)
+	r[5]  = (st.b >> 16	: byte)
+	r[6]  = (st.b >> 8	: byte)
+	r[7]  = (st.b >> 0	: byte)
+	r[8]  = (st.c >> 24	: byte)
+	r[9]  = (st.c >> 16	: byte)
+	r[10] = (st.c >> 8	: byte)
+	r[11] = (st.c >> 0	: byte)
+	r[12] = (st.d >> 16	: byte)
+	r[13] = (st.d >> 24	: byte)
+	r[14] = (st.d >> 8	: byte)
+	r[15] = (st.d >> 0	: byte)
+	r[16] = (st.e >> 16	: byte)
+	r[17] = (st.e >> 24	: byte)
+	r[18] = (st.e >> 8	: byte)
+	r[19] = (st.e >> 0	: byte)
 	-> r
 }
 
@@ -235,9 +235,10 @@
 const unpack = {b
 	var v : uint32
 
-	v = ((b[0] castto(uint32)) << 24)
-	v |= ((b[1] castto(uint32)) << 16)
-	v |= ((b[2] castto(uint32)) << 8)
-	v |= ((b[3] castto(uint32)) << 0)
+	v = 0
+	v |= (b[0] : uint32) << 24
+	v |= (b[1] : uint32) << 16
+	v |= (b[2] : uint32) << 8
+	v |= (b[3] : uint32) << 0
 	-> v
 }
--- a/lib/cryptohash/sha256.myr
+++ b/lib/cryptohash/sha256.myr
@@ -160,14 +160,14 @@
 	;;
 
 	/* append size block */
-	tail[56] = ((msglen * 8) >> 56)   castto(byte)
-	tail[57] = ((msglen * 8) >> 48)	castto(byte)
-	tail[58] = ((msglen * 8) >> 40)	castto(byte)
-	tail[59] = ((msglen * 8) >> 32)	castto(byte)
-	tail[60] = ((msglen * 8) >> 24)	castto(byte)
-	tail[61] = ((msglen * 8) >> 16)	castto(byte)
-	tail[62] = ((msglen * 8) >> 8)	castto(byte)
-	tail[63] = ((msglen * 8) >> 0)	castto(byte)
+	tail[56] = ((msglen * 8) >> 56	: byte)
+	tail[57] = ((msglen * 8) >> 48	: byte)
+	tail[58] = ((msglen * 8) >> 40	: byte)
+	tail[59] = ((msglen * 8) >> 32	: byte)
+	tail[60] = ((msglen * 8) >> 24	: byte)
+	tail[61] = ((msglen * 8) >> 16	: byte)
+	tail[62] = ((msglen * 8) >> 8	: byte)
+	tail[63] = ((msglen * 8) >> 0	: byte)
 	step(x, tail)
 }
 
@@ -400,16 +400,17 @@
 const unpack = {b
 	var v : uint32
 
-	v = ((b[0] castto(uint32)) << 24)
-	v |= ((b[1] castto(uint32)) << 16)
-	v |= ((b[2] castto(uint32)) << 8)
-	v |= ((b[3] castto(uint32)) << 0)
+	v = 0
+	v |= (b[0]	: uint32) << 24
+	v |= (b[1]	: uint32) << 16
+	v |= (b[2]	: uint32) << 8
+	v |= (b[3]	: uint32) << 0
 	-> v
 }
 
 const pack = {out, v
-	out[0]  = (v >> 24)	castto(byte)
-	out[1]  = (v >> 16)	castto(byte)
-	out[2]  = (v >> 8)	castto(byte)
-	out[3]  = (v >> 0)	castto(byte)
+	out[0]  = (v >> 24	: byte)
+	out[1]  = (v >> 16	: byte)
+	out[2]  = (v >> 8	: byte)
+	out[3]  = (v >> 0	: byte)
 }
--- a/lib/cryptohash/sha512.myr
+++ b/lib/cryptohash/sha512.myr
@@ -160,14 +160,14 @@
 	;;
 
 	/* append size block */
-	tail[120] = ((msglen * 8) >> 56)	castto(byte)
-	tail[121] = ((msglen * 8) >> 48)	castto(byte)
-	tail[122] = ((msglen * 8) >> 40)	castto(byte)
-	tail[123] = ((msglen * 8) >> 32)	castto(byte)
-	tail[124] = ((msglen * 8) >> 24)	castto(byte)
-	tail[125] = ((msglen * 8) >> 16)	castto(byte)
-	tail[126] = ((msglen * 8) >> 8)	castto(byte)
-	tail[127] = ((msglen * 8) >> 0)	castto(byte)
+	tail[120] = ((msglen * 8) >> 56	: byte)
+	tail[121] = ((msglen * 8) >> 48	: byte)
+	tail[122] = ((msglen * 8) >> 40	: byte)
+	tail[123] = ((msglen * 8) >> 32	: byte)
+	tail[124] = ((msglen * 8) >> 24	: byte)
+	tail[125] = ((msglen * 8) >> 16	: byte)
+	tail[126] = ((msglen * 8) >> 8	: byte)
+	tail[127] = ((msglen * 8) >> 0	: byte)
 	step(x, tail)
 }
 
@@ -450,25 +450,26 @@
 const unpack = {b
 	var v : uint64
 
-	v = ((b[0] castto(uint64)) << 56)
-	v |= ((b[1] castto(uint64)) << 48)
-	v |= ((b[2] castto(uint64)) << 40)
-	v |= ((b[3] castto(uint64)) << 32)
-	v |= ((b[4] castto(uint64)) << 24)
-	v |= ((b[5] castto(uint64)) << 16)
-	v |= ((b[6] castto(uint64)) << 8)
-	v |= ((b[7] castto(uint64)) << 0)
+	v = 0
+	v |= (b[0]	: uint64) << 56
+	v |= (b[1]	: uint64) << 48
+	v |= (b[2]	: uint64) << 40
+	v |= (b[3]	: uint64) << 32
+	v |= (b[4]	: uint64) << 24
+	v |= (b[5]	: uint64) << 16
+	v |= (b[6]	: uint64) << 8
+	v |= (b[7]	: uint64) << 0
 	-> v
 }
 
 const pack = {out, v
-	out[0]  = (v >> 56)	castto(byte)
-	out[1]  = (v >> 48)	castto(byte)
-	out[2]  = (v >> 40)	castto(byte)
-	out[3]  = (v >> 32)	castto(byte)
-	out[4]  = (v >> 24)	castto(byte)
-	out[5]  = (v >> 16)	castto(byte)
-	out[6]  = (v >> 8)	castto(byte)
-	out[7]  = (v >> 0)	castto(byte)
+	out[0]  = (v >> 56	: byte)
+	out[1]  = (v >> 48	: byte)
+	out[2]  = (v >> 40	: byte)
+	out[3]  = (v >> 32	: byte)
+	out[4]  = (v >> 24	: byte)
+	out[5]  = (v >> 16	: byte)
+	out[6]  = (v >> 8	: byte)
+	out[7]  = (v >> 0	: byte)
 }
 
--- a/lib/date/date.myr
+++ b/lib/date/date.myr
@@ -14,7 +14,6 @@
 
 	const localoff	: (tm : std.time -> duration)
 	const tzoff	: (tzname : byte[:], tm : std.time	-> duration)
-	const tzname	: (tzoff : int -> byte[:])
 	const isleap	: (d : instant	-> bool)
 
 	/* date differences */
@@ -84,7 +83,7 @@
 	std.slcp(inst._tzbuf[:tz.len], tz)
 	inst.tzname = inst._tzbuf[:tz.len]
 	inst.tzoff = tzoff
-	tm += inst.tzoff castto(std.time)
+	tm += (inst.tzoff : std.time)
 
 	/* break up time */
 	t = tm % DayUsec	/* time */
@@ -96,16 +95,16 @@
 	;;
 
 	/* microseconds, seconds, minutes, hours */
-	inst.us  = (t % 1_000_000) castto(int)
+	inst.us  = (t % 1_000_000 : int)
 	t /= 1_000_000
-	inst.s = (t % 60) castto(int)
+	inst.s = (t % 60 : int)
 	t /= 60
-	inst.m = (t % 60) castto(int)
+	inst.m = (t % 60 : int)
 	t /= 60
-	inst.h = t castto(int)
+	inst.h = (t : int)
 
 	/* weekday */
-	inst.wday = ((e + 4) % 7) castto(int)	/* the world started on Thursday */
+	inst.wday = ((e + 4) % 7 : int)	/* the world started on Thursday */
 
 	/*
 	split up year, month, day.
@@ -151,9 +150,9 @@
 		d += Mdays[m - 1] 
 	;;
 
-	inst.year = y castto(int)
-	inst.mon = m castto(int)
-	inst.day = d castto(int)
+	inst.year = (y : int)
+	inst.mon = (m : int)
+	inst.day = (d : int)
 	-> inst
 }
 
@@ -173,11 +172,11 @@
 }
 
 const add  = {d, dt
-	-> mkinstantoff(d.actual + (dt castto(std.time)), d.tzname, d.tzoff)
+	-> mkinstantoff(d.actual + (dt : std.time), d.tzname, d.tzoff)
 }
 
 const sub  = {d, dt
-	-> mkinstantoff(d.actual - (dt castto(std.time)), d.tzname, d.tzoff)
+	-> mkinstantoff(d.actual - (dt : std.time), d.tzname, d.tzoff)
 }
 
 const addperiod = {inst, p
@@ -205,7 +204,7 @@
 }
 
 const duration = {a, b
-	-> (b.actual - a.actual) castto(duration)
+	-> (b.actual - a.actual : duration)
 }
 
 const recalc = {inst
@@ -214,13 +213,13 @@
 
 
 	if inst.mon > 2
-		m = (inst.mon - 3) castto(std.time)
-		y = inst.year castto(std.time)
+		m = (inst.mon - 3 : std.time)
+		y = (inst.year : std.time)
 	else
-		m = (inst.mon + 9) castto(std.time)
-		y = (inst.year - 1) castto(std.time)
+		m = (inst.mon + 9 : std.time)
+		y = (inst.year - 1 : std.time)
 	;;
-	d = inst.day castto(std.time)
+	d = (inst.day : std.time)
 
 	c = y / 100
 	ya = y - 100 * c
@@ -229,10 +228,10 @@
 		(153 * m + 2)/5 + d - \
 		719469
 	tm = j * DayUsec
-	tm += (inst.h castto(std.time)) * 3600*1_000_000
-	tm += (inst.m castto(std.time)) * 60*1_000_000
-	tm += (inst.s castto(std.time)) * 1_000_000
-	tm += (inst.us castto(std.time))
+	tm += (inst.h : std.time) * 3600*1_000_000
+	tm += (inst.m : std.time) * 60*1_000_000
+	tm += (inst.s : std.time) * 1_000_000
+	tm += (inst.us : std.time)
 	-> tm
 }
 
--- a/lib/date/fmt.myr
+++ b/lib/date/fmt.myr
@@ -40,9 +40,9 @@
 const datefmt = {sb, fmt, d
 	var c
 	while fmt.len != 0
-		(c, fmt) = std.striter(fmt)
+		(c, fmt) = std.strstep(fmt)
 		if c == '%'
-			(c, fmt) = std.striter(fmt)
+			(c, fmt) = std.strstep(fmt)
 			match c
 			| 'a':	std.sbfmt(sb, "{}", _names.abbrevday[d.day])
 			| 'A':	std.sbfmt(sb, "{}", _names.fullday[d.day])
--- a/lib/date/parse.myr
+++ b/lib/date/parse.myr
@@ -51,7 +51,7 @@
 	s = filldate(&d, f, s, seen, &err)
 	std.bsfree(seen)
 
-	d.actual -= d.tzoff castto(std.time)
+	d.actual -= (d.tzoff : std.time)
 	match err
 	| `std.Some e:	-> `std.Fail e
 	| `std.None:	/* no error, we're ok */
@@ -70,9 +70,9 @@
 	z = ""
 	am = `std.None
 	while f.len != 0
-		(fc, f) = std.striter(f)
+		(fc, f) = std.strstep(f)
 		if fc == '%'
-			(fc, f) = std.striter(f)
+			(fc, f) = std.strstep(f)
 			if std.bshas(seen, fc)
 				err# = `std.Some `Doublefmt fc
 				-> s
@@ -80,10 +80,10 @@
 			std.bsput(seen, fc)
 			match fc
 			/* named things */
-			| 'a':	s = indexof(&d.day, s, _names.abbrevday, err)
-			| 'A':	s = indexof(&d.day, s, _names.fullday, err)
-			| 'b':	s = indexof(&d.mon, s, _names.abbrevmon, err)
-			| 'B':	s = indexof(&d.mon, s, _names.fullmon, err)
+			| 'a':	s = indexof(&d.day, s, _names.abbrevday[:], err)
+			| 'A':	s = indexof(&d.day, s, _names.fullday[:], err)
+			| 'b':	s = indexof(&d.mon, s, _names.abbrevmon[:], err)
+			| 'B':	s = indexof(&d.mon, s, _names.fullmon[:], err)
 			| 'c':	s = filldate(d, "%Y-%m-%d", s, seen, err)
 			| 'C':	
 				s = intval(&d.year, s, 2, 2, err)
@@ -92,7 +92,7 @@
 			| 'D':	s = filldate(d, "%m/%d/%y", s, seen, err)
 			| 'e':	s = intval(&d.day, s, 1, 2, err)
 			| 'F':	s = filldate(d, "%y-%m-%d", s, seen, err)
-			| 'h':	s = indexof(&d.day, s, _names.abbrevmon, err)
+			| 'h':	s = indexof(&d.day, s, _names.abbrevmon[:], err)
 			| 'H':	s = intval(&d.h, s, 1, 2, err)
 			| 'I':	s = intval(&d.h, s, 1, 2, err)
 			| 'k':	s = intval(&d.h, s, 1, 2, err)
@@ -120,7 +120,7 @@
 			| _:	std.fatal("unknown format character %c\n", fc)
 			;;
 		else
-			(sc, s) = std.striter(s)
+			(sc, s) = std.strstep(s)
 			if std.isspace(fc) && std.isspace(sc)
 				s = eatspace(s)
 			elif sc != fc
@@ -157,7 +157,7 @@
 	var c
 
 	while std.isspace(std.decode(s))
-		(c, s) = std.striter(s)
+		(c, s) = std.strstep(s)
 	;;
 	-> s
 }
@@ -198,6 +198,7 @@
 const tzstring = {d, s, err
 	var c, n
 
+	n = 0
 	while true
 		c = std.decode(s[n:])
 		if c != '/' && !std.isalnum(c)
@@ -245,7 +246,7 @@
 
 	num = s
 	for i = 0; i < min; i++
-		(c, s) = std.striter(s)
+		(c, s) = std.strstep(s)
 		if !std.isdigit(c)
 			err# = `std.Some `Shortint
 			-> s
--- a/lib/date/zoneinfo+posixy.myr
+++ b/lib/date/zoneinfo+posixy.myr
@@ -46,6 +46,7 @@
 	elif std.sleq(tz, "local")
 		path = std.sldup("/etc/localtime")
 	else
+		path = ""
 		for z in zonepath
 			path = std.pathcat(z, tz)
 			if sys.stat(path, &sb) == 0
@@ -61,7 +62,7 @@
 	std.slfree(path)
 
 	/* find applicable gmt offset */
-	cur = (tm / 1_000_000) castto(int32)
+	cur = (tm / 1_000_000 : int32)
 	if zone.time.len == 0
 		-> `std.None
 	;;
@@ -70,7 +71,7 @@
 	;;
 	ds = zone.ttinfo[zone.timetype[i]].gmtoff
 	free(zone)
-	->  `std.Some (ds castto(date.duration)) * 1_000_000
+	->  `std.Some (ds : date.duration) * 1_000_000
 }
 
 const load = {file
@@ -100,38 +101,38 @@
 
 
 	f = std.alloc()
-	f.time = std.slalloc(ntime castto(std.size))
+	f.time = std.slalloc((ntime : std.size))
 	for i = 0; i < ntime; i++
 		(f.time[i], p) = fetchbe32(p)
 	;;
 
-	f.timetype = std.slalloc(ntime castto(std.size))
+	f.timetype = std.slalloc((ntime : std.size))
 	for i = 0; i < ntime; i++
 		(f.timetype[i], p) = fetchbe8(p)
 	;;
 
-	f.ttinfo = std.slalloc(ntype castto(std.size))
+	f.ttinfo = std.slalloc((ntype : std.size))
 	for i = 0; i < ntype; i++
 		p = fetchttinfo(p, &f.ttinfo[i])
 	;;
 
-	f.abbrev = std.slalloc(nchar castto(std.size))
+	f.abbrev = std.slalloc((nchar : std.size))
 	for i = 0; i < nchar; i++
 		(f.abbrev[i], p) = fetchbe8(p)
 	;;
 
-	f.leap = std.slalloc(nleap castto(std.size))
+	f.leap = std.slalloc((nleap : std.size))
 	for i = 0; i < nleap; i++
 		(f.leap[i][0], p) = fetchbe32(p)
 		(f.leap[i][1], p) = fetchbe32(p)
 	;;
 
-	f.isstd = std.slalloc(nisstd castto(std.size))
+	f.isstd = std.slalloc((nisstd : std.size))
 	for i = 0; i < nisstd; i++
 		(f.isstd[i], p) = fetchbe8(p)
 	;;
 
-	f.isgmt = std.slalloc(nisgmt castto(std.size))
+	f.isgmt = std.slalloc((nisgmt : std.size))
 	for i = 0; i < nisgmt; i++
 		(f.isgmt[i], p) = fetchbe8(p)
 	;;
@@ -154,10 +155,7 @@
 	var v
 
 	std.assert(sl.len >= 4, "Slice too small to fetch int32 from")
-	v = 	(sl[0] castto(int32)) << 24 | \
-		(sl[1] castto(int32)) << 16 | \
-		(sl[2] castto(int32)) << 8  | \
-		(sl[3] castto(int32)) << 0  
+	v = std.getbe32(sl[:4])
 	-> (v, sl[4:])
 }
 
--- a/lib/inifile/parse.myr
+++ b/lib/inifile/parse.myr
@@ -90,7 +90,7 @@
 		-> true
 	;;
 
-	match ln[0] castto(char)
+	match (ln[0] : char)
 	| '[':	-> parsesection(p, ini, ln)
 	| _:	-> parsekvp(p, ini, ln)
 	;;
--- a/lib/regex/compile.myr
+++ b/lib/regex/compile.myr
@@ -157,7 +157,7 @@
 	if len == 1
 		buf[0] = 0x7f
 	else
-		s = len castto(byte)
+		s = (len : byte)
 		buf[0] = (0xff << (8 - s)) | (fill >> (s + 1))
 		for var i = 1; i < len; i++
 			buf[i] = 0x80 | (fill >> 2)
@@ -388,11 +388,11 @@
 		std.put("{}@{}:\t", i, re.pcidx[i])
 		match re.prog[i]
 		/* Char matching. Consume exactly one byte from the string. */
-		| `Ibyte b:		std.put("`Ibyte {} ({})\n", b, b castto(char)) 
+		| `Ibyte b:		std.put("`Ibyte {} ({})\n", b, (b : char)) 
 		| `Irange (start, end):	
 			std.put("`Irange ({},{})", start, end) 
-			if std.isalnum(start castto(char)) && std.isalnum(end castto(char))
-				std.put("\t/* {}-{} */", start castto(char), end castto(char))
+			if std.isalnum((start : char)) && std.isalnum((end : char))
+				std.put("\t/* {}-{} */", (start : char), (end : char))
 			;;
 			std.put("\n")
 		/* capture groups */
--- a/lib/regex/interp.myr
+++ b/lib/regex/interp.myr
@@ -9,7 +9,7 @@
 ;;
 
 /* Ugly: for performance. std.option() should be used instead when unions get faster. */
-const Zthr = 0 castto(rethread#)
+const Zthr = (0 : rethread#)
 
 const exec = {re, str
 	var thr
@@ -168,7 +168,7 @@
 	match re.prog[thr.ip]
 	/* Char matching. Consume exactly one byte from the string. */
 	| `Ibyte b:
-		trace(re, thr, "\t{}:\tByte {} ({})\n", thr.ip, b, b castto(char))
+		trace(re, thr, "\t{}:\tByte {} ({})\n", thr.ip, b, (b : char))
 		if !within(re, str)
 			die(re, thr, "end of string")
 		elif b != str[re.strp]
@@ -178,7 +178,7 @@
 			trace(re, thr, "\t\tmatched {} with {}\n", b, str[re.strp])
 		;;
 	| `Irange (start, end):
-		trace(re, thr, "\t{}:\tRange ({}, {}) /* {} - {} */\n", thr.ip, start, end, start castto(char), end castto(char))
+		trace(re, thr, "\t{}:\tRange ({}, {}) /* {} - {} */\n", thr.ip, start, end, (start : char), (end : char))
 		if !within(re, str) || start > str[re.strp] || end < str[re.strp]
 			die(re, thr, "bad range")
 		else
@@ -190,7 +190,7 @@
 	 */
 	| `Ibol:
 		trace(re, thr, "\t{}:\tBol\n", thr.ip)
-		if re.strp == 0 || str[re.strp - 1] == '\n' castto(byte)
+		if re.strp == 0 || str[re.strp - 1] == ('\n' : byte)
 			thr.ip++
 			-> false
 		else
@@ -198,7 +198,7 @@
 		;;
 	| `Ieol:
 		trace(re, thr, "\t{}:\tEol\n", thr.ip)
-		if re.strp == str.len || str[re.strp] == '\n' castto(byte)
+		if re.strp == str.len || str[re.strp] == ('\n' : byte)
 			thr.ip++
 			-> false
 		else
--- a/lib/std/alloc.myr
+++ b/lib/std/alloc.myr
@@ -46,9 +46,9 @@
 ;;
 
 /* null pointers. only used internally. */
-const Zslab	= 0 castto(slab#)
-const Zchunk	= 0 castto(chunk#)
-const Zsliceptr	= 0 castto(byte#)
+const Zslab	= (0 : slab#)
+const Zchunk	= (0 : chunk#)
+const Zsliceptr	= (0 : byte#)
 
 const Slabsz 	= 1*MiB	/* 1 meg slabs */
 const Cachemax	= 16	/* maximum number of slabs in the cache */
@@ -92,16 +92,16 @@
 
 /* Allocates an object of type @a, returning a pointer to it. */
 generic alloc = {-> @a#
-	-> bytealloc(sizeof(@a)) castto(@a#)
+	-> (bytealloc(sizeof(@a)) : @a#)
 }
 
 generic zalloc = {-> @a#
-	-> zbytealloc(sizeof(@a)) castto(@a#)
+	-> (zbytealloc(sizeof(@a)) : @a#)
 }
 
 /* Frees a value of type @a */
 generic free = {v:@a# -> void
-	bytefree(v castto(byte#), sizeof(@a))
+	bytefree((v : byte#), sizeof(@a))
 }
 
 /* allocates a slice of 'len' elements. */
@@ -114,7 +114,7 @@
 	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
 	p = bytealloc(sz)
 	p = inithdr(p, sz)
-	-> (p castto(@a#))[0:len]
+	-> (p : @a#)[0:len]
 }
 
 generic slzalloc = {len
@@ -126,27 +126,27 @@
 	sz = len*sizeof(@a) + align(sizeof(slheader), Align)
 	p = zbytealloc(sz)
 	p = inithdr(p, sz)
-	-> (p castto(@a#))[0:len]
+	-> (p : @a#)[0:len]
 }
 
 const inithdr = {p, sz
 	var phdr, prest
 
-	phdr = p castto(slheader#)
+	phdr = (p : slheader#)
 	phdr.cap = allocsz(sz) - align(sizeof(slheader), Align)
-	phdr.magic = (0xdeadbeefbadf00d castto(size))
+	phdr.magic = (0xdeadbeefbadf00d : size)
 
-	prest = (p castto(size)) + align(sizeof(slheader), Align)
-	-> prest castto(byte#)
+	prest = (p : size) + align(sizeof(slheader), Align)
+	-> (prest : byte#)
 }
 
 const checkhdr = {p
 	var phdr, addr
 
-	addr = p castto(size)
+	addr = (p : size)
 	addr -= align(sizeof(slheader), Align)
-	phdr = addr castto(slheader#)
-	iassert(phdr.magic == (0xdeadbeefbadf00d castto(size)), "corrupt memory\n")
+	phdr = (addr : slheader#)
+	iassert(phdr.magic == (0xdeadbeefbadf00d : size), "corrupt memory\n")
 }
 
 /* Frees a slice */
@@ -153,14 +153,14 @@
 generic slfree	 = {sl
 	var head
 
-	if sl castto(byte#) == Zsliceptr
+	if (sl : byte#) == Zsliceptr
 		-> void
 	;;
 
-	checkhdr(sl castto(byte#))
-	head = (sl castto(byte#)) castto(size)
+	checkhdr((sl : byte#))
+	head = ((sl : byte#) : size)
 	head -= align(sizeof(slheader), Align)
-	bytefree(head castto(byte#), slcap(sl castto(byte#)))
+	bytefree((head : byte#), slcap((sl : byte#)))
 }
 
 /* Grows a slice */
@@ -171,11 +171,11 @@
 
 	/* if the slice doesn't need a bigger bucket, we don't need to realloc. */
 	cap = 0
-	if sl# castto(byte#) != Zsliceptr
-		cap = slcap(sl# castto(byte#))
+	if (sl# : byte#) != Zsliceptr
+		cap = slcap((sl# : byte#))
 	;;
 	if cap >= allocsz(len*sizeof(@a))
-		sl# = (sl# castto(@a#))[:len]
+		sl# = (sl# : @a#)[:len]
 		-> sl#
 	;;
 
@@ -204,9 +204,9 @@
 
 	oldlen = sl#.len
 	slgrow(sl, len)
-	base = sl# castto(byte#) castto(intptr)
+	base = ((sl# : byte#) : intptr)
 	if oldlen < len
-		memfill(sl#[oldlen:] castto(byte#), 0, (len - oldlen)*sizeof(@a))
+		memfill((sl#[oldlen:] : byte#), 0, (len - oldlen)*sizeof(@a))
 	;;
 	-> sl#
 }
@@ -214,7 +214,7 @@
 const slcap = {p
 	var phdr
 
-	phdr = (p castto(size)) - align(sizeof(slheader), Align) castto(slheader#)
+	phdr = ((p : size) - align(sizeof(slheader), Align) : slheader#)
 	-> phdr.cap
 }
 
@@ -292,12 +292,12 @@
 		die("Unable to get memory")
 	;;
 
-	s = align(p castto(size), Slabsz) castto(slab#)
+	s = (align((p : size), Slabsz) : slab#)
 	s.head = p
 	s.nfree = bkt.nper
 	/* skip past the slab header */
 	off = align(sizeof(slab), Align)
-	bnext = nextchunk(s castto(chunk#), off)
+	bnext = nextchunk((s : chunk#), off)
 	s.freehd = bnext
 	for var i = 0; i < bkt.nper; i++
 		b = bnext
@@ -336,7 +336,7 @@
 		s.next = Zslab
 	;;
 
-	-> b castto(byte#)
+	-> (b : byte#)
 }
 
 /*
@@ -348,8 +348,8 @@
 const bktfree = {bkt, m
 	var s, b
 
-	s = mtrunc(m, Slabsz) castto(slab#)
-	b = m castto(chunk#)
+	s = (mtrunc(m, Slabsz) : slab#)
+	b = (m : chunk#)
 	if s.nfree == 0
 		s.next = bkt.slabs
 		bkt.slabs = s
@@ -423,7 +423,7 @@
 index to get to the next one
 */
 const nextchunk = {b, sz : size
-	-> ((b castto(intptr)) + (sz castto(intptr))) castto(chunk#)
+	-> ((b : intptr) + (sz : intptr) : chunk#)
 }
 
 /*
@@ -431,5 +431,5 @@
 be a power of two.
 */
 const mtrunc = {m, align
-	-> ((m castto(intptr)) & ~((align castto(intptr)) - 1)) castto(byte#)
+	-> ((m : intptr) & ~((align : intptr) - 1) : byte#)
 }
--- a/lib/std/bigint.myr
+++ b/lib/std/bigint.myr
@@ -79,10 +79,10 @@
 	elif v > 0
 		a.sign = 1
 	;;
-	val = v castto(uint64)
-	slpush(&a.dig, val castto(uint32))
+	val = (v : uint64)
+	slpush(&a.dig, (val : uint32))
 	if val > Base
-		slpush(&a.dig, (val/Base) castto(uint32))
+		slpush(&a.dig, (val/Base : uint32))
 	;;
 	-> trim(a)
 }
@@ -212,7 +212,7 @@
 			bigfree(v)
 			-> `None
 		;;
-		v.dig[0] = val castto(uint32)
+		v.dig[0] = (val : uint32)
 		if val == 0
 			v.sign = 0
 		else
@@ -245,7 +245,7 @@
 	var v
 	var dig : uint32[2]
 
-	bigdigit(&v, b < 0, b castto(uint64), dig[:])
+	bigdigit(&v, b < 0, (b : uint64), dig[:])
 	-> bigeq(a, &v)
 }
 
@@ -252,8 +252,8 @@
 const bigcmp = {a, b
 	var da, db, sa, sb
 
-	sa = a.sign castto(int64)
-	sb = b.sign castto(int64)
+	sa = (a.sign : int64)
+	sb = (b.sign : int64)
 	if sa < sb
 		-> `Before
 	elif sa > sb
@@ -265,8 +265,8 @@
 	else
 		/* otherwise, the one with the first larger digit is bigger */
 		for var i = a.dig.len; i > 0; i--
-			da = a.dig[i - 1] castto(int64)
-			db = b.dig[i - 1] castto(int64)
+			da = (a.dig[i - 1]  : int64)
+			db = (b.dig[i - 1]  : int64)
 			if da != db
 				-> signedorder(sa * (da - db))
 			;;
@@ -316,9 +316,9 @@
 	/* guaranteed to carry no more than one value */
 	slzgrow(&a.dig, n + 1)
 	for i = 0; i < n; i++
-		v = (a.dig[i] castto(uint64)) + carry;
+		v = (a.dig[i] : uint64) + carry;
 		if i < b.dig.len
-			v += (b.dig[i] castto(uint64))
+			v += ((b.dig[i]  : uint64))
 		;;
 
 		if v >= Base
@@ -326,9 +326,9 @@
 		else
 			carry = 0
 		;;
-		a.dig[i] = v castto(uint32)
+		a.dig[i] = (v  : uint32)
 	;;
-	a.dig[i] += carry castto(uint32)
+	a.dig[i] += (carry  : uint32)
 	-> trim(a)
 }
 
@@ -365,9 +365,9 @@
 
 	carry = 0
 	for i = 0; i < a.dig.len; i++
-		v = (a.dig[i] castto(int64)) - carry
+		v = (a.dig[i] : int64) - carry
 		if i < b.dig.len
-			v -= (b.dig[i] castto(int64)) 
+			v -= (b.dig[i] : int64)
 		;;
 		if v < 0
 			carry = 1
@@ -374,7 +374,7 @@
 		else
 			carry = 0
 		;;
-		a.dig[i] = v castto(uint32)
+		a.dig[i] = (v  : uint32)
 	;;
 	-> trim(a)
 }
@@ -400,14 +400,14 @@
 	for j = 0; j < b.dig.len; j++
 		carry = 0
 		for i = 0; i < a.dig.len; i++
-			ai = a.dig[i] castto(uint64)
-			bj = b.dig[j] castto(uint64)
-			wij = w[i+j] castto(uint64)
+			ai = (a.dig[i]  : uint64)
+			bj = (b.dig[j]  : uint64)
+			wij = (w[i+j]  : uint64)
 			t = ai * bj + wij + carry
-			w[i + j] = (t castto(uint32))
+			w[i + j] = ((t  : uint32))
 			carry = t >> 32
 		;;
-		w[i+j] = carry castto(uint32)
+		w[i+j] = (carry  : uint32)
 	;;
 	slfree(a.dig)
 	a.dig = w
@@ -462,14 +462,14 @@
 	/* handle single digit divisor separately: the knuth algorithm needs at least 2 digits. */
 	if b.dig.len == 1
 		carry = 0
-		b0 = (b.dig[0] castto(uint64))
+		b0 = ((b.dig[0]  : uint64))
 		for j = a.dig.len; j > 0; j--
-			aj = (a.dig[j - 1] castto(uint64))
-			q.dig[j - 1] = (((carry << 32) + aj)/b0) castto(uint32)
-			carry = (carry << 32) + aj - (q.dig[j-1] castto(uint64))*b0
+			aj = ((a.dig[j - 1]  : uint64))
+			q.dig[j - 1] = ((((carry << 32) + aj)/b0)  : uint32)
+			carry = (carry << 32) + aj - (q.dig[j-1] : uint64)*b0
 		;;
 		q = trim(q)
-		-> (q, trim(mkbigint(carry castto(int32))))
+		-> (q, trim(mkbigint((carry : int32))))
 	;;
 
 	u = bigdup(a)
@@ -484,11 +484,11 @@
 
 	for j = m - n; j >= 0; j--
 		/* load a few temps */
-		x = u.dig[j + n] castto(uint64)
-		y = u.dig[j + n - 1] castto(uint64)
-		z = v.dig[n - 1] castto(uint64)
-		w = v.dig[n - 2] castto(uint64)
-		t = u.dig[j + n - 2] castto(uint64)
+		x = (u.dig[j + n]  : uint64)
+		y = (u.dig[j + n - 1]  : uint64)
+		z = (v.dig[n - 1]  : uint64)
+		w = (v.dig[n - 2]  : uint64)
+		t = (u.dig[j + n - 2]  : uint64)
 
 		/* estimate qhat */
 		qhat = (x*Base + y)/z
@@ -505,26 +505,25 @@
 		/* multiply and subtract */
 		carry = 0
 		for i = 0; i < n; i++
-			p = qhat * (v.dig[i] castto(uint64))
+			p = (qhat * (v.dig[i]  : uint64))
 
-			t = (u.dig[i+j] castto(uint64)) - carry - (p % Base)
-			u.dig[i+j] = t castto(uint32)
-
-			carry = (((p castto(int64)) >> 32) - ((t castto(int64)) >> 32)) castto(uint64);
+			t = ((u.dig[i+j]  : uint64)) - carry - (p % Base)
+			u.dig[i+j] = (t  : uint32)
+			carry = (((p : int64) >> 32) - ((t : int64) >> 32) : uint64)
 		;;
-		t = (u.dig[j + n] castto(uint64)) - carry
-		u.dig[j + n] = t castto(uint32)
-		q.dig[j] = qhat castto(uint32)
+		t = (u.dig[j + n] : uint64) - carry
+		u.dig[j + n] = (t  : uint32)
+		q.dig[j] = (qhat  : uint32)
 		/* adjust */
-		if t castto(int64) < 0
+		if (t : int64) < 0
 			q.dig[j]--
 			carry = 0
 			for i = 0; i < n; i++
-				t = (u.dig[i+j] castto(uint64)) + (v.dig[i] castto(uint64)) + carry
-				u.dig[i+j] = t castto(uint32)
+				t = (u.dig[i+j] : uint64) + (v.dig[i] : uint64) + carry
+				u.dig[i+j] = (t  : uint32)
 				carry = t >> 32
 			;;
-			u.dig[j+n] = u.dig[j+n] + (carry castto(uint32));
+			u.dig[j+n] = u.dig[j+n] + (carry : uint32)
 		;;
 
 	;;
@@ -587,7 +586,7 @@
 const bigshl = {a, b
 	match b.dig.len
 	| 0:	-> a
-	| 1:	-> bigshli(a, b.dig[0] castto(uint64))
+	| 1:	-> bigshli(a, (b.dig[0] : uint64))
 	| n:	die("shift by way too much\n")
 	;;
 }
@@ -596,7 +595,7 @@
 const bigshr = {a, b
 	match b.dig.len
 	| 0:	-> a
-	| 1:	-> bigshri(a, b.dig[0] castto(uint64))
+	| 1:	-> bigshri(a, (b.dig[0]:  uint64))
 	| n:	die("shift by way too much\n")
 	;;
 }
@@ -608,7 +607,7 @@
 	var bigb : bigint
 	var dig : uint32[2]
 
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigdigit(&bigb, b < 0, (b : uint64), dig[:])
 	bigadd(a, &bigb)
 	-> a
 }
@@ -617,7 +616,7 @@
 	var bigb : bigint
 	var dig : uint32[2]
 
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigdigit(&bigb, b < 0, (b : uint64), dig[:])
 	bigsub(a, &bigb)
 	-> a
 }
@@ -626,7 +625,7 @@
 	var bigb : bigint
 	var dig : uint32[2]
 
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigdigit(&bigb, b < 0, (b : uint64), dig[:])
 	bigmul(a, &bigb)
 	-> a
 }
@@ -635,7 +634,7 @@
 	var bigb : bigint
 	var dig : uint32[2]
 
-	bigdigit(&bigb, b < 0, b castto(uint64), dig[:])
+	bigdigit(&bigb, b < 0, (b : uint64), dig[:])
 	bigdiv(a, &bigb)
 	-> a
 }
@@ -649,14 +648,14 @@
 	var t, carry
 
 	iassert(s >= 0, "shift amount must be positive")
-	off = (s castto(uint64)) / 32
-	shift = (s castto(uint64)) % 32
+	off = (s : uint64) / 32
+	shift = (s : uint64) % 32
 
 	/* zero shifted by anything is zero */
 	if a.sign == 0
 		-> a
 	;;
-	slzgrow(&a.dig, 1 + a.dig.len + off castto(size))
+	slzgrow(&a.dig, (1 + a.dig.len + off : size))
 	/* blit over the base values */
 	for var i = a.dig.len; i > off; i--
 		a.dig[i - 1] = a.dig[i - 1 - off]
@@ -667,8 +666,8 @@
 	/* and shift over by the remainder */
 	carry = 0
 	for var i = 0; i < a.dig.len; i++
-		t = (a.dig[i] castto(uint64)) << shift
-		a.dig[i] = (t | carry) castto(uint32) 
+		t = (a.dig[i] : uint64) << shift
+		a.dig[i] = (t | carry: uint32) 
 		carry = t >> 32
 	;;
 	-> trim(a)
@@ -680,8 +679,8 @@
 	var t, carry
 
 	iassert(s >= 0, "shift amount must be positive")
-	off = (s castto(uint64)) / 32
-	shift = (s castto(uint64)) % 32
+	off = (s : uint64) / 32
+	shift = (s : uint64) % 32
 
 	/* blit over the base values */
 	for var i = 0; i < a.dig.len - off; i++
@@ -693,8 +692,8 @@
 	/* and shift over by the remainder */
 	carry = 0
 	for var i = a.dig.len; i > 0; i--
-		t = (a.dig[i - 1] castto(uint64))
-		a.dig[i - 1] = (carry | (t >> shift)) castto(uint32) 
+		t = ((a.dig[i - 1]  : uint64))
+		a.dig[i - 1] = (carry | (t >> shift): uint32)
 		carry = t << (32 - shift)
 	;;
 	-> trim(a)
@@ -712,11 +711,11 @@
 		v.dig = [][:]
 	elif val < Base
 		v.dig = dig[:1]
-		v.dig[0] = val castto(uint32)
+		v.dig[0] = (val  : uint32)
 	else
 		v.dig = dig
-		v.dig[0] = val castto(uint32)
-		v.dig[1] = (val >> 32) castto(uint32)
+		v.dig[0] = (val  : uint32)
+		v.dig[1] = ((val >> 32)  : uint32)
 	;;
 }
 
--- a/lib/std/bitset.myr
+++ b/lib/std/bitset.myr
@@ -57,8 +57,8 @@
 generic bsput = {bs, v
 	var idx, off, changed
 
-	idx = (v castto(size)) / (8*sizeof(size))
-	off = (v castto(size)) % (8*sizeof(size))
+	idx = (v : size) / (8*sizeof(size))
+	off = (v : size) % (8*sizeof(size))
 	ensurelen(bs, idx)
 
 	changed = (bs.bits[idx] & (1 << off)) == 0
@@ -70,8 +70,8 @@
 	var idx, off, changed
 
 	changed = false
-	idx = (v castto(size)) / (8*sizeof(size))
-	off = (v castto(size)) % (8*sizeof(size))
+	idx = (v : size) / (8*sizeof(size))
+	off = (v : size) % (8*sizeof(size))
 	if idx < bs.bits.len
 		changed = (bs.bits[idx] & (1 << off)) != 0
 		bs.bits[idx] &= ~(1 << off)
@@ -83,8 +83,8 @@
 	var idx
 	var off
 
-	idx = (v castto(size)) / (8*sizeof(size))
-	off = (v castto(size)) % (8*sizeof(size))
+	idx = (v : size) / (8*sizeof(size))
+	off = (v : size) % (8*sizeof(size))
 	if idx >= bs.bits.len
 		-> false
 	;;
--- a/lib/std/chartype.myr
+++ b/lib/std/chartype.myr
@@ -1228,14 +1228,14 @@
 	var v = -1
 
 	if c >= '0' && c <= '9'
-		v =  (c - '0') castto(@a::(integral,numeric))
+		v =  (c - '0' : @a::(integral,numeric))
 	elif c >= 'a' && c <= 'z'
-		v =  (c - 'a' + 10) castto(@a::(integral,numeric))
+		v =  (c - 'a' + 10 : @a::(integral,numeric))
 	elif c >= 'A' && c <= 'Z'
-		v =  (c - 'A' + 10) castto(@a::(integral,numeric))
+		v =  (c - 'A' + 10 : @a::(integral,numeric))
 	;;
 
-	if v < 0 || v >= (base castto(@a::(integral,numeric)))
+	if v < 0 || v >= (base : @a::(integral,numeric))
 		-> -1
 	;;
 	-> v
--- a/lib/std/clear.myr
+++ b/lib/std/clear.myr
@@ -6,7 +6,7 @@
 generic clear = {p : @a#
 	var bp
 
-	bp = p castto(byte#)
+	bp = (p : byte#)
 	slfill(bp[:sizeof(@a)], 0)
 }
 
--- a/lib/std/cstrconv.myr
+++ b/lib/std/cstrconv.myr
@@ -19,8 +19,8 @@
 	var i, base
 
 	i = 0
-	base = p castto(intptr)
-	while ((base + i) castto(byte#))# != 0
+	base = (p : intptr)
+	while (base + i : byte#)# != 0
 		i++
 	;;
 	-> p[:i]
--- a/lib/std/dial+posixy.myr
+++ b/lib/std/dial+posixy.myr
@@ -61,11 +61,11 @@
 	match getaddr(hoststr)
 	| `Ok `Ipv4 bits:
 		sa4=[.fam=sys.Afinet, .addr=bits, .port=hosttonet(port)]
-		sa = &sa4 castto(sys.sockaddr#)
+		sa = (&sa4 : sys.sockaddr#)
 		sz = sizeof(sys.sockaddr_in)
 	| `Ok `Ipv6 bits:
 		sa6=[.fam=sys.Afinet6, .addr=bits, .port=hosttonet(port)]
-		sa = &sa6 castto(sys.sockaddr#)
+		sa = (&sa6 : sys.sockaddr#)
 		sz = sizeof(sys.sockaddr_in6)
 	| `Fail m:
 		-> `Fail m
@@ -81,7 +81,7 @@
 		-> `Fail "Failed to bind socket"
 	;;
 
-	-> `Ok (sock castto(fd))
+	-> `Ok (sock : fd)
 }
 
 const dialunix = {path
@@ -98,8 +98,8 @@
 		-> `Fail "failed to create socket"
 	;;
 	slcp(sa.path[:path.len], path)
-	if sys.connect(sock, &sa castto(sys.sockaddr#), sizeof(sys.sockaddr_un)) < 0
+	if sys.connect(sock, (&sa : sys.sockaddr#), sizeof(sys.sockaddr_un)) < 0
 		-> `Fail "failed to bind address"
 	;;
-	-> `Ok (sock castto(fd))
+	-> `Ok (sock : fd)
 }
--- a/lib/std/dir+freebsd.myr
+++ b/lib/std/dir+freebsd.myr
@@ -48,8 +48,8 @@
 		d.off = 0
 	;;
 
-	dent = &d.buf[d.off] castto(sys.dirent#)
-	d.off += dent.reclen castto(int64)
+	dent = (&d.buf[d.off] : sys.dirent#)
+	d.off += (dent.reclen : int64)
 	-> `Some sldup(dent.name[:dent.namelen])
 }
 
--- a/lib/std/dir+linux.myr
+++ b/lib/std/dir+linux.myr
@@ -51,9 +51,9 @@
 		d.off = 0
 	;;
 
-	dent = &d.buf[d.off] castto(sys.dirent64#)
+	dent = (&d.buf[d.off] : sys.dirent64#)
 	namelen = 0
-	d.off += dent.reclen castto(int64)
+	d.off += (dent.reclen : int64)
 	while dent.name[namelen] != 0
 		namelen++
 	;;
--- a/lib/std/dir+openbsd.myr
+++ b/lib/std/dir+openbsd.myr
@@ -49,9 +49,9 @@
 		d.off = 0
 	;;
 
-	dent = &d.buf[d.off] castto(sys.dirent#)
+	dent = (&d.buf[d.off] : sys.dirent#)
 	namelen = 0
-	d.off += dent.reclen castto(int64)
+	d.off += (dent.reclen : int64)
 	while dent.name[namelen] != 0
 		namelen++
 	;;
--- a/lib/std/dir+osx.myr
+++ b/lib/std/dir+osx.myr
@@ -48,8 +48,8 @@
 		d.off = 0
 	;;
 
-	dent = &d.buf[d.off] castto(sys.dirent64#)
-	d.off += dent.reclen castto(int64)
+	dent = (&d.buf[d.off] : sys.dirent64#)
+	d.off += (dent.reclen : int64)
 	-> `Some sldup(dent.name[:dent.namlen])
 }
 
--- a/lib/std/dir+plan9.myr
+++ b/lib/std/dir+plan9.myr
@@ -48,16 +48,16 @@
 		| `Fail e:
 			-> `None
 		| `Ok len:
-			d.len = len castto(int64)
+			d.len = (len : int64)
 			d.off = 0
 		;;
 	;;
 
-	namelen = (d.buf[d.off + Stringsoff] castto(int64)) | \
-		((d.buf[d.off + Stringsoff + 1] castto(int64)) << 8)
+	namelen = (d.buf[d.off + Stringsoff] : int64) | \
+		((d.buf[d.off + Stringsoff + 1] : int64) << 8)
 	base = d.off + Stringsoff + 2
-	dirlen = (d.buf[d.off] castto(int64)) | \
-		((d.buf[d.off + 1] castto(int64)) << 8)
+	dirlen = (d.buf[d.off] : int64) | \
+		((d.buf[d.off + 1] : int64) << 8)
 	name = d.buf[base:base + namelen]
 	d.off += dirlen + 2
 	-> `Some std.sldup(name)
--- a/lib/std/diriter.myr
+++ b/lib/std/diriter.myr
@@ -10,13 +10,13 @@
 ;;
 
 const byentry = {d
-	-> d castto(diriter)
+	-> (d : diriter)
 }
 
 impl iterable diriter -> byte[:] =
 	__iternext__ = {itp, valp
 :nextfile
-		match dirread(itp# castto(dir#))
+		match dirread((itp# : dir#))
 		| `Some ".":	goto nextfile
 		| `Some "..":	goto nextfile
 		| `Some ent:
--- a/lib/std/dirname.myr
+++ b/lib/std/dirname.myr
@@ -18,7 +18,7 @@
 	var end
 
 	for end = p.len; end > 1; end--
-		if p[end-1] != '/' castto(byte)
+		if p[end-1] != ('/' : byte)
 			break
 		;;
 	;;
@@ -34,7 +34,7 @@
 	var end
 
 	for end = p.len; end > 1; end--
-		if p[end-1] != '/' castto(byte)
+		if p[end-1] != ('/' : byte)
 			break
 		;;
 	;;
--- a/lib/std/errno.myr
+++ b/lib/std/errno.myr
@@ -4,38 +4,38 @@
 	type errno = int
 
 	const Enone	: errno = 0
-	const Eperm	: errno = sys.Eperm	castto(errno)
-	const Enoent	: errno = sys.Enoent	castto(errno)
-	const Esrch	: errno = sys.Esrch	castto(errno)
-	const Eintr	: errno = sys.Eintr	castto(errno)
-	const Eio	: errno = sys.Eio	castto(errno)
-	const Enxio	: errno = sys.Enxio	castto(errno)
-	const E2big	: errno = sys.E2big	castto(errno)
-	const Enoexec	: errno = sys.Enoexec	castto(errno)
-	const Ebadf	: errno = sys.Ebadf	castto(errno)
-	const Echild	: errno = sys.Echild	castto(errno)
-	const Eagain	: errno = sys.Eagain	castto(errno)
-	const Enomem	: errno = sys.Enomem	castto(errno)
-	const Eacces	: errno = sys.Eacces	castto(errno)
-	const Efault	: errno = sys.Efault	castto(errno)
-	const Enotblk	: errno = sys.Enotblk	castto(errno)
-	const Ebusy	: errno = sys.Ebusy	castto(errno)
-	const Eexist	: errno = sys.Eexist	castto(errno)
-	const Exdev	: errno = sys.Exdev	castto(errno)
-	const Enodev	: errno = sys.Enodev	castto(errno)
-	const Enotdir	: errno = sys.Enotdir	castto(errno)
-	const Eisdir	: errno = sys.Eisdir	castto(errno)
-	const Einval	: errno = sys.Einval	castto(errno)
-	const Enfile	: errno = sys.Enfile	castto(errno)
-	const Emfile	: errno = sys.Emfile	castto(errno)
-	const Enotty	: errno = sys.Enotty	castto(errno)
-	const Etxtbsy	: errno = sys.Etxtbsy	castto(errno)
-	const Efbig	: errno = sys.Efbig	castto(errno)
-	const Enospc	: errno = sys.Enospc	castto(errno)
-	const Espipe	: errno = sys.Espipe	castto(errno)
-	const Erofs	: errno = sys.Erofs	castto(errno)
-	const Emlink	: errno = sys.Emlink	castto(errno)
-	const Epipe	: errno = sys.Epipe	castto(errno)
-	const Edom	: errno = sys.Edom	castto(errno)
-	const Erange	: errno = sys.Erange	castto(errno)
+	const Eperm	: errno = (sys.Eperm	: errno)
+	const Enoent	: errno = (sys.Enoent	: errno)
+	const Esrch	: errno = (sys.Esrch	: errno)
+	const Eintr	: errno = (sys.Eintr	: errno)
+	const Eio	: errno = (sys.Eio	: errno)
+	const Enxio	: errno = (sys.Enxio	: errno)
+	const E2big	: errno = (sys.E2big	: errno)
+	const Enoexec	: errno = (sys.Enoexec	: errno)
+	const Ebadf	: errno = (sys.Ebadf	: errno)
+	const Echild	: errno = (sys.Echild	: errno)
+	const Eagain	: errno = (sys.Eagain	: errno)
+	const Enomem	: errno = (sys.Enomem	: errno)
+	const Eacces	: errno = (sys.Eacces	: errno)
+	const Efault	: errno = (sys.Efault	: errno)
+	const Enotblk	: errno = (sys.Enotblk	: errno)
+	const Ebusy	: errno = (sys.Ebusy	: errno)
+	const Eexist	: errno = (sys.Eexist	: errno)
+	const Exdev	: errno = (sys.Exdev	: errno)
+	const Enodev	: errno = (sys.Enodev	: errno)
+	const Enotdir	: errno = (sys.Enotdir	: errno)
+	const Eisdir	: errno = (sys.Eisdir	: errno)
+	const Einval	: errno = (sys.Einval	: errno)
+	const Enfile	: errno = (sys.Enfile	: errno)
+	const Emfile	: errno = (sys.Emfile	: errno)
+	const Enotty	: errno = (sys.Enotty	: errno)
+	const Etxtbsy	: errno = (sys.Etxtbsy	: errno)
+	const Efbig	: errno = (sys.Efbig	: errno)
+	const Enospc	: errno = (sys.Enospc	: errno)
+	const Espipe	: errno = (sys.Espipe	: errno)
+	const Erofs	: errno = (sys.Erofs	: errno)
+	const Emlink	: errno = (sys.Emlink	: errno)
+	const Epipe	: errno = (sys.Epipe	: errno)
+	const Edom	: errno = (sys.Edom	: errno)
+	const Erange	: errno = (sys.Erange	: errno)
 ;;
--- a/lib/std/extremum.myr
+++ b/lib/std/extremum.myr
@@ -32,7 +32,7 @@
 }
 
 generic abs = {a : @a::numeric
-	if a < (0 castto(@a::numeric))
+	if a < (0 : @a::numeric)
 		-> -a
 	else
 		-> a
--- a/lib/std/fltbits.myr
+++ b/lib/std/fltbits.myr
@@ -7,10 +7,10 @@
 	const flt32explode	: (flt : flt32 -> (bool, int32, int32))
 ;;
 
-const flt64bits	= {flt;	-> (&flt castto(int64#))#}
-const flt32bits	= {flt;	-> (&flt castto(int32#))#}
-const flt64frombits	= {bits;	-> (&bits castto(flt64#))#}
-const flt32frombits	= {bits;	-> (&bits castto(flt32#))#}
+const flt64bits	= {flt;	-> (&flt : int64#)#}
+const flt32bits	= {flt;	-> (&flt : int32#)#}
+const flt64frombits	= {bits;	-> (&bits : flt64#)#}
+const flt32frombits	= {bits;	-> (&bits : flt32#)#}
 
 const flt64explode = {flt
 	var bits, isneg, mant, exp
--- a/lib/std/fltfmt.myr
+++ b/lib/std/fltfmt.myr
@@ -25,7 +25,7 @@
 	var isneg, exp, mant
 
 	(isneg, mant, exp) = flt64explode(val)
-	dragon4(sb, isneg, mant, (exp - 52) castto(int64), Dblbias, mode, precision)
+	dragon4(sb, isneg, mant, (exp - 52 : int64), Dblbias, mode, precision)
 }
 
 const flt32bfmt = {sb, val, mode, precision
@@ -32,7 +32,7 @@
 	var isneg, exp, mant
 
 	(isneg, mant, exp) = flt32explode(val)
-	dragon4(sb, isneg, mant castto(int64), (exp - 52) castto(int64), Fltbias, mode, precision)
+	dragon4(sb, isneg, (mant : int64), (exp - 52 : int64), Fltbias, mode, precision)
 }
 
 /*
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -325,7 +325,7 @@
 		sbputs(sb, "0x")
 		intfmt(sb, \
 			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
-			false, p_val castto(intptr))
+			false, (p_val : intptr))
 	| `Tyslice desc:
 		match typedesc(desc)
 		| `Tybyte:
@@ -348,7 +348,7 @@
 		sbputs(sb, "func{")
 		intfmt(sb, \
 			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
-			false, p_val castto(intptr))
+			false, (p_val : intptr))
 		sbputs(sb, "}")
 		vabytes(ap)
 	| `Tyarray (sz, desc):
@@ -393,9 +393,9 @@
 		vabytes(ap)
 	| `Tyunion nc:
 		inf = typeinfo(tcpeek(&ap.tc))
-		p = ap.args castto(size)
+		p = (ap.args : size)
 		p = (p + inf.align - 1) & ~(inf.align - 1)
-		i_val = (p castto(int32#))#
+		i_val = (p : int32#)#
 		subap = vaenterunion(ap, i_val)
 		for var i = 0; i < i_val; i++
 			ncnext(&nc)
@@ -415,7 +415,7 @@
 	var i
 
 	for i = 0; i < fmt.len; i++
-		if fmt[i] == '}' castto(byte)
+		if fmt[i] == ('}' : byte)
 			goto foundparams
 		;;
 	;;
@@ -508,7 +508,7 @@
 }
 
 const isprint = {b
-	-> (b >= ' ' castto(byte)) && (b < '~' castto(byte))
+	-> b >= (' ' : byte) && b < ('~' : byte)
 }
 
 /*
@@ -531,12 +531,12 @@
 	var i, j, npad
 	var base
 
-	base = opts.base castto(uint64)
+	base = (opts.base : uint64)
 	if signed && bits < 0
-		val = -bits castto(uint64)
+		val = (-bits : uint64)
 		isneg = true
 	else
-		val = bits castto(uint64)
+		val = (bits : uint64)
 		val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a)))
 		isneg = false
 	;;
--- a/lib/std/fndup.myr
+++ b/lib/std/fndup.myr
@@ -11,15 +11,15 @@
 generic fndup = {fn
 	var repr : intptr[2]
 
-	repr = (&fn castto(intptr[2]#))#
-	repr[0] = sldup(envslice(repr[0])) castto(intptr)
-	-> (&repr castto(@fn::function#))#
+	repr = (&fn : intptr[2]#)#
+	repr[0] = (sldup(envslice(repr[0])) : intptr)
+	-> (&repr : @fn::function#)#
 }
 
 generic fnfree = {fn
 	var repr : intptr[2]
 
-	repr = (&fn castto(intptr[2]#))#
+	repr = (&fn : intptr[2]#)#
 	std.slfree(envslice(repr[0]))
 }
 
@@ -27,8 +27,8 @@
 	var env : byte#
 	var szp : intptr#
 
-	env = ep castto(byte#)
-	szp = env castto(intptr#)
+	env = (ep : byte#)
+	szp = (env : intptr#)
 	-> env[:szp#]
 }
 
--- a/lib/std/getint.myr
+++ b/lib/std/getint.myr
@@ -10,55 +10,55 @@
 ;;
 
 generic getbe64 = {buf -> @a::(numeric,integral)
-	-> ((buf[0] castto(@a::(numeric,integral))) << 56) | \
-		((buf[1] castto(@a::(numeric,integral))) << 48) | \
-		((buf[2] castto(@a::(numeric,integral))) << 40) | \
-		((buf[3] castto(@a::(numeric,integral))) << 32) | \
-		((buf[4] castto(@a::(numeric,integral))) << 24) | \
-		((buf[5] castto(@a::(numeric,integral))) << 16) | \
-		((buf[6] castto(@a::(numeric,integral))) << 8) | \
-		((buf[7] castto(@a::(numeric,integral))) << 0)
+	-> ((buf[0] : @a::(numeric,integral)) << 56) | \
+		((buf[1] : @a::(numeric,integral)) << 48) | \
+		((buf[2] : @a::(numeric,integral)) << 40) | \
+		((buf[3] : @a::(numeric,integral)) << 32) | \
+		((buf[4] : @a::(numeric,integral)) << 24) | \
+		((buf[5] : @a::(numeric,integral)) << 16) | \
+		((buf[6] : @a::(numeric,integral)) << 8) | \
+		((buf[7] : @a::(numeric,integral)) << 0)
 }
 
 generic getle64 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral)))  << 0) | \
-		((buf[1] castto(@a::(numeric,integral)))  << 8) | \
-		((buf[2] castto(@a::(numeric,integral)))  << 16) | \
-		((buf[3] castto(@a::(numeric,integral)))  << 24) | \
-		((buf[4] castto(@a::(numeric,integral)))  << 32) | \
-		((buf[5] castto(@a::(numeric,integral)))  << 40) | \
-		((buf[6] castto(@a::(numeric,integral)))  << 48) | \
-		((buf[7] castto(@a::(numeric,integral)))  << 56)
+	-> ((buf[0] : @a::(numeric,integral))  << 0) | \
+		((buf[1] : @a::(numeric,integral))  << 8) | \
+		((buf[2] : @a::(numeric,integral))  << 16) | \
+		((buf[3] : @a::(numeric,integral))  << 24) | \
+		((buf[4] : @a::(numeric,integral))  << 32) | \
+		((buf[5] : @a::(numeric,integral))  << 40) | \
+		((buf[6] : @a::(numeric,integral))  << 48) | \
+		((buf[7] : @a::(numeric,integral))  << 56)
 }
 
 generic getbe32 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 24) | \
-		((buf[1] castto(@a::(numeric,integral))) << 16) | \
-		((buf[2] castto(@a::(numeric,integral))) << 8) | \
-		((buf[3] castto(@a::(numeric,integral))) << 0)
+	-> ((buf[0] : @a::(numeric,integral)) << 24) | \
+		((buf[1] : @a::(numeric,integral)) << 16) | \
+		((buf[2] : @a::(numeric,integral)) << 8) | \
+		((buf[3] : @a::(numeric,integral)) << 0)
 }
 
 generic getle32 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 0) | \
-		((buf[1] castto(@a::(numeric,integral))) << 8) | \
-		((buf[2] castto(@a::(numeric,integral))) << 16) | \
-		((buf[3] castto(@a::(numeric,integral))) << 24)
+	-> ((buf[0] : @a::(numeric,integral)) << 0) | \
+		((buf[1] : @a::(numeric,integral)) << 8) | \
+		((buf[2] : @a::(numeric,integral)) << 16) | \
+		((buf[3] : @a::(numeric,integral)) << 24)
 }
 
 generic getbe16 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 8) | \
-		((buf[1] castto(@a::(numeric,integral))) << 0)
+	-> ((buf[0] : @a::(numeric,integral)) << 8) | \
+		((buf[1] : @a::(numeric,integral)) << 0)
 }
 
 generic getle16 = {buf
-	-> ((buf[0] castto(@a::(numeric,integral))) << 0) | \
-		((buf[1] castto(@a::(numeric,integral))) << 8)
+	-> ((buf[0] : @a::(numeric,integral)) << 0) | \
+		((buf[1] : @a::(numeric,integral)) << 8)
 }
 
 generic getbe8 = {buf
-	-> (buf[0] castto(@a::(numeric,integral))) << 0
+	-> (buf[0] : @a::(numeric,integral)) << 0
 }
 
 generic getle8 = {buf
-	-> (buf[0] castto(@a::(numeric,integral))) << 0
+	-> (buf[0] : @a::(numeric,integral)) << 0
 }
--- a/lib/std/hashfuncs.myr
+++ b/lib/std/hashfuncs.myr
@@ -34,7 +34,7 @@
 	var n
 
 	n = data.len * sizeof(@a)
-	-> (data castto(byte#))[:n]
+	-> (data : byte#)[:n]
 }
 
 const strhash = {s
@@ -78,7 +78,7 @@
 generic ptrhash = {p : @a#
 	var x
 
-	x = &p castto(byte#)
+	x = (&p : byte#)
 	-> murmurhash2(x[0:sizeof(@a#)], Seed)
 }
 
@@ -89,7 +89,7 @@
 generic inthash = {v : @a::(integral,numeric)
 	var p
 
-	p = &v castto(byte#)
+	p = (&v : byte#)
 	-> murmurhash2(p[0:sizeof(@a)], Seed)
 }
 
@@ -104,10 +104,10 @@
 	
 	h = seed ^ data.len
 	while data.len >= 4
-		k = (data[0] castto(uint32))
-		k |= (data[1] castto(uint32)) << 8
-		k |= (data[2] castto(uint32)) << 16
-		k |= (data[3] castto(uint32)) << 24
+		k = (data[0] : uint32)
+		k |= (data[1] : uint32) << 8
+		k |= (data[2] : uint32) << 16
+		k |= (data[3] : uint32) << 24
 
 		k *= m
 		k ^= k >> r
@@ -120,14 +120,14 @@
 
 	match data.len
 	| 3:
-		h ^= (data[2] castto(uint32)) << 16
-		h ^= (data[1] castto(uint32)) <<8
-		h ^= (data[0] castto(uint32))
+		h ^= (data[2] : uint32) << 16
+		h ^= (data[1] : uint32) <<8
+		h ^= (data[0] : uint32)
 	| 2:
-		h ^= (data[1] castto(uint32)) <<8
-		h ^= (data[0] castto(uint32))
+		h ^= (data[1] : uint32) <<8
+		h ^= (data[0] : uint32)
 	| 1:
-		h ^= (data[0] castto(uint32))
+		h ^= (data[0] : uint32)
 	| 0:	/* nothing */
 	| _:	die("0 < len < 4 must be true")
 	;;
--- a/lib/std/intparse.myr
+++ b/lib/std/intparse.myr
@@ -54,8 +54,8 @@
 		;;
 		cv = charval(c, base)
 		if cv >= 0
-			v *= (base castto(@a::(integral,numeric)))
-			v += cv castto(@a::(integral,numeric))
+			v *= (base : @a::(integral,numeric))
+			v += (cv : @a::(integral,numeric))
 		else
 			-> `None
 		;;
--- a/lib/std/introspect.myr
+++ b/lib/std/introspect.myr
@@ -110,7 +110,7 @@
 const typeenc = {ap : ...#
 	var e
 
-	e = getenc(ap castto(byte##))
+	e = getenc((ap : byte##))
 	e = skiptypeinfo(e[1:])
 	-> lentypecursor(e)
 }
@@ -197,7 +197,7 @@
 	var val, sz, x
 
 	(val, sz) = getipacked(p#[:8])
-	x = &sz castto(byte#)
+	x = (&sz : byte#)
 	-> p#[sz:sz+val]
 }
 
@@ -254,7 +254,7 @@
 		value, so if we cast it to a byte##, we can
 		pull the indirect value out of the pointer.
 		*/
-		p = ti[1:] castto(byte##)
+		p = (ti[1:] : byte##)
 		-> typedesc(getenc(p))
 	| _:
 		std.die("unknown type encoding")
@@ -297,7 +297,7 @@
 	| Encunion:	-> gettypeinfo(ti[1:])
 	| Encname:	-> getnameinfo(ti[1:])
 	| Encindname:
-		p = ti[1:] castto(byte##)
+		p = (ti[1:] : byte##)
 		-> typeinfo(getenc(p))
 	| _:
 		std.die("unknown type encoding")
@@ -381,9 +381,9 @@
 	;;
 
 	shift = 8 - len
-	val = (p[0] castto(std.size))  & ~(~0 << shift)
+	val = (p[0] : size)  & ~(~0 << shift)
 	for i = 1; i < len; i++
-		val |= (p[i] castto(std.size)) << (i*8 - len)
+		val |= (p[i] : size) << (i*8 - len)
 	;;
 	-> (val, len)
 }
--- a/lib/std/ipparse.myr
+++ b/lib/std/ipparse.myr
@@ -75,7 +75,7 @@
 		;;
 		(ip, ok) = delim(ip, ':', ok)
 		/* only one '::' allowed once */
-		if ip.len > 0 && ip[0] == ':'castto(byte) && !expand
+		if ip.len > 0 && ip[0] == (':' : byte) && !expand
 			expand = true
 			split = i
 			(ip, ok) = delim(ip, ':', ok)
@@ -82,8 +82,8 @@
 		;;
 
 		/* pack it into the bytes */
-		val[i*2] = ((v & 0xff00) >> 8) castto(byte)
-		val[i*2 + 1] = (v & 0xff) castto(byte)
+		val[i*2] = ((v & 0xff00) >> 8 : byte)
+		val[i*2 + 1] = (v & 0xff : byte)
 	;;
 
 	if ok && ip.len == 0
@@ -108,7 +108,7 @@
 }
 
 const delim = {ip, sep, ok
-	if ip.len > 0 && ip[0] == sep castto(byte)
+	if ip.len > 0 && ip[0] == (sep : byte)
 		-> (ip[1:], ok)
 	else
 		-> ("", false)
@@ -123,7 +123,7 @@
 	;;
 
 	for len = 0; len < ip.len; len++
-		if ip[len] == sep castto(byte)
+		if ip[len] == (sep : byte)
 			break
 		;;
 	;;
@@ -132,7 +132,7 @@
 		if v < lo || v > hi
 			-> (0, "", false)
 		;;
-		-> (v castto(@a::(numeric,integral)), ip[len:], true)
+		-> ((v : @a::(numeric,integral)), ip[len:], true)
 	| `std.None:
 		-> (0, "", false)
 	;;
--- a/lib/std/listen+posixy.myr
+++ b/lib/std/listen+posixy.myr
@@ -53,17 +53,17 @@
 
 	if std.sleq(hoststr, "*")
 		sa6=[.fam=sys.Afinet6, .port=hosttonet(port)]
-		sa = &sa6 castto(sys.sockaddr#)
+		sa = (&sa6 : sys.sockaddr#)
 		sz = sizeof(sys.sockaddr_in6)
 	else
 		match getaddr(hoststr)
 		| `Ok `Ipv4 bits:
 			sa4=[.fam=sys.Afinet, .addr=bits, .port=hosttonet(port)]
-			sa = &sa4 castto(sys.sockaddr#)
+			sa = (&sa4 : sys.sockaddr#)
 			sz = sizeof(sys.sockaddr_in)
 		| `Ok `Ipv6 bits:
 			sa6=[.fam=sys.Afinet6, .addr=bits, .port=hosttonet(port)]
-			sa = &sa6 castto(sys.sockaddr#)
+			sa = (&sa6 : sys.sockaddr#)
 			sz = sizeof(sys.sockaddr_in6)
 		| `Fail m:
 			-> `Fail m
@@ -74,13 +74,13 @@
 		-> `Fail "failed to create socket"
 	;;
 	yes = 1
-	if sys.setsockopt(sock, sys.Solsock, sys.Soreuseaddr, &yes castto(void#), sizeof(int)) < 0
+	if sys.setsockopt(sock, sys.Solsock, sys.Soreuseaddr, (&yes : void#), sizeof(int)) < 0
 		-> `Fail "failed to set sock opts"
 	;;
 	if sys.bind(sock, sa, sz) < 0
 		-> `Fail "failed to bind socket"
 	;;
-	-> `Ok sock castto(fd)
+	-> `Ok (sock : fd)
 }
 
 const announceunix = {path
@@ -99,22 +99,22 @@
 		-> `Fail "failed to create socket"
 	;;
 	yes = 1
-	if sys.setsockopt(sock, sys.Solsock, sys.Soreuseaddr, &yes castto(void#), sizeof(int)) < 0
+	if sys.setsockopt(sock, sys.Solsock, sys.Soreuseaddr, (&yes : void#), sizeof(int)) < 0
 		-> `Fail "failed to set sock opts"
 	;;
 	sys.unlink(path)
-	if sys.bind(sock, &sa castto(sys.sockaddr#), sizeof(sys.sockaddr_un)) < 0
+	if sys.bind(sock, (&sa : sys.sockaddr#), sizeof(sys.sockaddr_un)) < 0
 		-> `Fail "failed to bind address"
 	;;
-	-> `Ok (sock castto(fd))
+	-> `Ok (sock : fd)
 
 }
 
 const listen = {sock : std.fd -> result(fd, byte[:])
-	if sys.listen(sock castto(sys.fd), 10) < 0
+	if sys.listen((sock : sys.fd), 10) < 0
 		-> `Fail "unable to listen on socket"
 	;;
-	-> `Ok (sys.dup(sock castto(sys.fd)) castto(fd))
+	-> `Ok (sys.dup((sock : sys.fd)) : fd)
 }
 
 const accept = {lfd
@@ -122,10 +122,10 @@
 	var len : sys.size
 	var fd
 
-	fd = sys.accept(lfd castto(sys.fd), 0 castto(sys.sockaddr#), 0 castto(sys.size#))
+	fd = sys.accept((lfd : sys.fd), (0 : sys.sockaddr#), (0 : sys.size#))
 	if fd < 0
 		-> `Fail "unable to accept socket"
 	;;
-	-> `Ok (fd castto(fd))
+	-> `Ok (fd : fd)
 }
 
--- a/lib/std/memops-impl.myr
+++ b/lib/std/memops-impl.myr
@@ -10,8 +10,8 @@
 	var sa, da
 	var s, d
 
-	da = dst castto(intptr)
-	sa = src castto(intptr)
+	da = (dst : intptr)
+	sa = (src : intptr)
 	d = dst[:len]
 	s = src[:len]
 
--- a/lib/std/mkpath.myr
+++ b/lib/std/mkpath.myr
@@ -9,7 +9,7 @@
 	var st
 
 	for var i = 0; i < p.len; i++
-		if p[i] == '/' castto(byte) && i != 0
+		if p[i] == ('/' : byte) && i != 0
 			st = mkdir(p[:i], mode)
 			if st != 0 && st != Eexist
 				-> st
--- a/lib/std/putint.myr
+++ b/lib/std/putint.myr
@@ -12,14 +12,14 @@
 	generic putbe8	: (buf : byte[:], v :  @a::(numeric,integral) -> size)
 ;;
 
-generic putle64	= {buf, v;	-> putle(buf, v castto(uint64), 8)}
-generic putbe64	= {buf, v;	-> putbe(buf, v castto(uint64), 8)}
-generic putle32	= {buf, v;	-> putle(buf, v castto(uint64), 4)}
-generic putbe32	= {buf, v;	-> putbe(buf, v castto(uint64), 4)}
-generic putle16	= {buf, v;	-> putle(buf, v castto(uint64), 2)}
-generic putbe16	= {buf, v;	-> putbe(buf, v castto(uint64), 2)}
-generic putle8	= {buf, v;	-> putle(buf, v castto(uint64), 1)}
-generic putbe8	= {buf, v;	-> putbe(buf, v castto(uint64), 1)}
+generic putle64	= {buf, v;	-> putle(buf, (v : uint64), 8)}
+generic putbe64	= {buf, v;	-> putbe(buf, (v : uint64), 8)}
+generic putle32	= {buf, v;	-> putle(buf, (v : uint64), 4)}
+generic putbe32	= {buf, v;	-> putbe(buf, (v : uint64), 4)}
+generic putle16	= {buf, v;	-> putle(buf, (v : uint64), 2)}
+generic putbe16	= {buf, v;	-> putbe(buf, (v : uint64), 2)}
+generic putle8	= {buf, v;	-> putle(buf, (v : uint64), 1)}
+generic putbe8	= {buf, v;	-> putbe(buf, (v : uint64), 1)}
 
 const putbe = {buf, val, n
 	var k
@@ -27,16 +27,16 @@
 	assert(buf.len >= n, "buffer too small")
 	for var i = 0; i < n; i++
 		k = val >> (8*(n-i-1))
-		buf[i] = (k & 0xff) castto(byte)
+		buf[i] = (k & 0xff: byte)
 	;;
-	-> n castto(size)
+	-> (n : size)
 }
 
 const putle = {buf, val, n
 	assert(buf.len >= n, "buffer too small")
 	for var i = 0; i < n; i++
-		buf[i] = (val & 0xff) castto(byte)
+		buf[i] = (val & 0xff : byte)
 		val >>= 8
 	;;
-	-> n castto(size)
+	-> (n : size)
 }
--- a/lib/std/rand.myr
+++ b/lib/std/rand.myr
@@ -71,7 +71,7 @@
 var _rng : rng#
 
 const __init__ = {
-	_rng = mksrng(now() castto(uint32))
+	_rng = mksrng((now() : uint32))
 }
 
 /* allocates and initializes a random number generator */
@@ -146,7 +146,7 @@
 	val = 0
 	for var i = 0; i < sizeof(@a)/4; i++
 		val <<= 8*sizeof(@a)
-		val |= rand32(rng) castto(@a::(integral,numeric))
+		val |= (rand32(rng)  : @a::(integral,numeric))
 	;;
 	-> val
 }
@@ -176,14 +176,14 @@
 	n = 0
 	for var i = 0; i < buf.len/4; i++
 		r = rand32(rng)
-		buf[n++] = (r >>  0 & 0xff) castto(byte)
-		buf[n++] = (r >>  8 & 0xff) castto(byte)
-		buf[n++] = (r >> 16 & 0xff) castto(byte)
-		buf[n++] = (r >> 32 & 0xff) castto(byte)
+		buf[n++] = (r >>  0 & 0xff : byte)
+		buf[n++] = (r >>  8 & 0xff : byte)
+		buf[n++] = (r >> 16 & 0xff : byte)
+		buf[n++] = (r >> 32 & 0xff : byte)
 	;;
 	r = rand32(rng)
 	for ; n != buf.len; n++
-		buf[n] = (r & 0xff) castto(byte)
+		buf[n] = (r & 0xff : byte)
 		r >>= 8
 	;;
 	-> n
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -265,7 +265,7 @@
 		.port = hosttonet(53),
 		.addr = addr,
 	]
-	status = sys.connect(s, (&sa) castto(sys.sockaddr#), sizeof(sys.sockaddr_in))
+	status = sys.connect(s, (&sa : sys.sockaddr#), sizeof(sys.sockaddr_in))
 	if status < 0
 		-> -1
 	;;
@@ -304,7 +304,7 @@
 
 	/* query */
 	off += packname(pkt[:], off, host)	/* host */
-	off += pack16(pkt[:], off, t castto(uint16)) /* qtype: a record */
+	off += pack16(pkt[:], off, (t : uint16)) /* qtype: a record */
 	off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
 
 	sys.write(srv, pkt[:off])
@@ -349,7 +349,7 @@
 	;;
 
 	/* parse answer records */
-	hinf = slalloc(a castto(size))
+	hinf = slalloc((a : size))
 	for var i = 0; i < a; i++
 		off = skipname(pkt, off)	/* name */
 		(v, off) = unpack16(pkt, off)	/* type */
@@ -367,7 +367,7 @@
 const skipname = {pkt, off
 	var sz
 
-	for sz = pkt[off] castto(size); sz != 0; sz = pkt[off] castto(size)
+	for sz = (pkt[off] : size); sz != 0; sz = (pkt[off] : size)
 		/* ptr is 2 bytes */
 		if sz & 0xC0 == 0xC0
 			-> off + 2
@@ -380,8 +380,8 @@
 
 
 const pack16 = {buf, off, v
-	buf[off]	= (v & 0xff00) >> 8 castto(byte)
-	buf[off+1]	= (v & 0x00ff) castto(byte)
+	buf[off]	= ((v & 0xff00) >> 8 : byte)
+	buf[off+1]	= ((v & 0x00ff) >> 0 : byte)
 	-> sizeof(uint16) /* we always write one uint16 */
 }
 
@@ -388,8 +388,9 @@
 const unpack16 = {buf, off
 	var v
 
-	v = (buf[off] castto(uint16)) << 8
-	v |= (buf[off + 1] castto(uint16))
+	v = 0
+	v |= (buf[off + 0] : uint16) << 8
+	v |= (buf[off + 1] : uint16) << 0
 	-> (v, off+sizeof(uint16))
 }
 
@@ -396,10 +397,10 @@
 const unpack32 = {buf, off
 	var v
 
-	v = (buf[off] castto(uint32)) << 24
-	v |= (buf[off+1] castto(uint32)) << 32
-	v |= (buf[off+2] castto(uint32)) << 8
-	v |= (buf[off+3] castto(uint32))
+	v = (buf[off] : uint32) << 24
+	v |= (buf[off+1] : uint32) << 32
+	v |= (buf[off+2] : uint32) << 8
+	v |= (buf[off+3] : uint32)
 	-> (v, off+sizeof(uint32))
 }
 
@@ -410,12 +411,12 @@
 	start = off
 	last = 0
 	for var i = 0; i < host.len; i++
-		if host[i] == ('.' castto(byte))
+		if host[i] == ('.' : byte)
 			off += addseg(buf, off, host[last:i])
 			last = i + 1
 		;;
 	;;
-	if host[host.len - 1] != ('.' castto(byte))
+	if host[host.len - 1] != ('.' : byte)
 		off += addseg(buf, off, host[last:])
 	;;
 	off += addseg(buf, off, "") /* null terminating segment */
@@ -423,7 +424,7 @@
 }
 
 const addseg = {buf, off, str
-	buf[off] = str.len castto(byte)
+	buf[off] = (str.len : byte)
 	slcp(buf[off + 1 : off + str.len + 1], str)
 	-> str.len + 1
 }
@@ -439,7 +440,7 @@
 
 	seglen = 0
 	for i = 0; i < host.len; i++
-		if host[i] == ('.' castto(byte))
+		if host[i] == ('.' : byte)
 			seglen = 0
 		;;
 		if seglen > 63
--- a/lib/std/slcp.myr
+++ b/lib/std/slcp.myr
@@ -8,5 +8,5 @@
 
 generic slcp = {a : @a[:], b : @a[:]
 	iassert(a.len == b.len, "arguments to slcp() must be of equal length\n")
-	memblit(a castto(byte#), b castto(byte#), a.len * sizeof(@a))
+	memblit((a : byte#), (b : byte#), a.len * sizeof(@a))
 }
--- a/lib/std/spork.myr
+++ b/lib/std/spork.myr
@@ -24,7 +24,7 @@
 		-> `Fail err
 	;;
 
-	match sporkfd(cmd, infds[0] castto(fd), outfds[1] castto(fd))
+	match sporkfd(cmd, infds[0], outfds[1])
 	| `Ok pid:
 		/* close unused fd ends */
 		close(infds[0]);
@@ -41,15 +41,15 @@
 	pid = fork()
 	/* error  */
 	if pid < 0
-		-> `Fail pid castto(errno)
+		-> `Fail (pid : errno)
 	/* child */
 	elif pid == 0
 		/* stdin/stdout for our communication. */
-		match dup2(infd castto(fd), 0)
+		match dup2(infd, 0)
 		| `Ok _:	/* nothing */
 		| `Fail e:	-> `Fail e
 		;;
-		match dup2(outfd castto(fd), 1)
+		match dup2(outfd, 1)
 		| `Ok _:	/* nothing */
 		| `Fail e:	-> `Fail e
 		;;
--- a/lib/std/syswrap+plan9-x6.myr
+++ /dev/null
@@ -1,104 +1,0 @@
-use sys
-use "types"
-
-pkg std =
-	type fd		= sys.fd
-	type pid	= sys.pid
-	type fdopt	= sys.fdopt
-
-	const Failmem	: byte#	= -1 castto(byte#)
-
-	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
-	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
-	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
-	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
-	const Ocreat   	: fdopt = 0x1000000	/* emulated by redirecting to creat(). */
-	const Oappend  	: fdopt = 0x2000000	/* emulated by seeking to EOF */
-	const Odir	: fdopt = 0x0	/* no-op on plan9 */
-
-	/* fd stuff */
-	const open	: (path : byte[:], opts : fdopt -> fd)
-	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
-	const close	: (fd : fd -> int64)
-	const creat	: (path : byte[:], mode : int64 -> fd)
-	const read	: (fd : fd, buf : byte[:] -> size)
-	const write	: (fd : fd, buf : byte[:] -> size)
-	const pipe	: (fds : fd[2]# -> int64)
-
-	/* path manipulation */
-	const mkdir	: (path : byte[:], mode : int64 -> int64)
-	const unlink	: (path : byte[:] -> int)
-
-	/* process stuff */
-	const getpid	: ( -> pid)
-	const suicide	: ( -> void)
-	const fork	: (-> pid)
-	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
-	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
-	const exit	: (status:int -> void)
-	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
-	const getmem	: (sz : size -> byte#)
-	const freemem	: (p : byte#, sz : size -> void)
-;;
-
-/* fd stuff */
-const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
-const openmode	= {path, opts, mode;
-	var fd
-
-
-	if opts & Ocreat != 0
-		fd = sys.create(path, opts castto(sys.fdopt), mode castto(int))
-	else
-		fd = sys.open(path, opts castto(sys.fdopt))
-	;;
-	if opts & Oappend != 0
-		sys.seek(fd, 0, 2)
-	;;
-	-> fd castto(fd)
-}
-
-const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(int64)}
-const read	= {fd, buf;	-> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
-const write	= {fd, buf;	-> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
-const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
-
-/* path manipulation */
-const unlink	= {path;	-> sys.remove(path)}
-const mkdir	= {path, mode;
-	var fd
-
-	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
-	if fd < 0
-		-> -1
-	;;
-	sys.close(fd)
-	-> 0
-}
-
-/* process stuff */
-const getpid	= {;	-> sys.gettos().pid castto(pid)}
-const suicide	= {;	(0 castto(byte#))#}	/* let's happy segfault!! t */
-const fork	= {;		-> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
-const execv	= {cmd, args;	-> sys.exec(cmd, args) castto(int64)}
-const execve	= {cmd, args, env;	-> sys.exec(cmd, args) castto(int64)}
-const exit	= {status;
-	if status == 0
-		sys.exits("")
-	else
-		sys.exits("failure")
-	;;
-}
-
-/* FIXME: horribly broken. We wait for a pid to exit, and lie about which one. */
-const waitpid	= {pid, loc, opt;
-	var buf : byte[512]
-	var n
-
-	n = sys.await(buf[:])
-	-> pid
-}
-
-/* memory stuff */
-const getmem	= {sz;		-> sys.mmap(0 castto(byte#), sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)}
-const freemem	= {p, sz;	sys.munmap(p, sz castto(sys.size))}
--- a/lib/std/syswrap+plan9.myr
+++ b/lib/std/syswrap+plan9.myr
@@ -25,12 +25,12 @@
 	const Seekcur	: whence = 1
 	const Seekend	: whence = 2
 
-	const Failmem	: byte#	= -1 castto(byte#)
+	const Failmem	: byte#	= (-1 : byte#)
 
-	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
-	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
-	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
-	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
+	const Ordonly  	: fdopt = (sys.Ordonly	: fdopt)
+	const Owronly  	: fdopt = (sys.Owronly	: fdopt)
+	const Ordwr    	: fdopt = (sys.Ordwr	: fdopt)
+	const Otrunc   	: fdopt = (sys.Otrunc	: fdopt)
 	const Ocreat   	: fdopt = 0x1000000	/* emulated by redirecting to creat(). */
 	const Oappend  	: fdopt = 0x2000000	/* emulated by seeking to EOF */
 	const Odir	: fdopt = 0x0	/* no-op on plan9 */
@@ -92,15 +92,15 @@
 extern const getenvv : (name : byte[:], default : byte[:] -> byte[:])
 
 /* fd stuff */
-const open	= {path, opts;	-> check(sys.open(path, opts castto(sys.fdopt)))}
+const open	= {path, opts;	-> check(sys.open(path, (opts : sys.fdopt)))}
 const openmode	= {path, opts, mode;
 	var fd
 
 
 	if opts & Ocreat != 0
-		fd = sys.create(path, (opts & ~Ocreat) castto(sys.fdopt), mode castto(int))
+		fd = sys.create(path, (opts & ~Ocreat : sys.fdopt), (mode : int))
 	else
-		fd = sys.open(path, opts castto(sys.fdopt))
+		fd = sys.open(path, (opts : sys.fdopt))
 	;;
 	if opts & Oappend != 0
 		sys.seek(fd, 0, 2)
@@ -122,7 +122,7 @@
 	if sys.stat(path, buf[:]) < Stringsoff
 		-> `Fail Emisc
 	;;
-	-> `Ok (getle32(buf[Mtimeoff:Mtimeoff + 8]) castto(time))
+	-> `Ok (getle32(buf[Mtimeoff:Mtimeoff + 8] : ime))
 }
 
 const fsize = {path
@@ -131,7 +131,7 @@
 	if sys.stat(path, buf[:]) < Stringsoff
 		-> `Fail Emisc
 	;;
-	-> `Ok (getle64(buf[Lengthoff:Lengthoff + 8]) castto(off))
+	-> `Ok (getle64(buf[Lengthoff:Lengthoff + 8] : off))
 }
 
 extern const put : (fmt : byte[:], args : ... -> int64)
@@ -170,12 +170,12 @@
 	si.arch = getenvv("objtype", "amd64")
 }
 
-const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(errno)}
-const read	= {fd, buf;	-> check(sys.pread(fd castto(sys.fd), buf, -1))}
-const write	= {fd, buf;	-> check(sys.pwrite(fd castto(sys.fd), buf, -1))}
-const seek	= {fd, off, whence; 	-> check(sys.seek(fd castto(sys.fd), off castto(sys.off), whence castto(int64)))}
-const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(errno)}
-const dup2	= {ofd, nfd;	-> check(sys.dup(ofd castto(sys.fd), nfd castto(sys.fd)))}
+const close	= {fd;		-> (sys.close((fd : sys.fd)) : errno)}
+const read	= {fd, buf;	-> check(sys.pread((fd : sys.fd), buf, -1))}
+const write	= {fd, buf;	-> check(sys.pwrite((fd : sys.fd), buf, -1))}
+const seek	= {fd, off, whence; 	-> check(sys.seek((fd : sys.fd), (off : sys.off), (whence : nt64)))}
+const pipe	= {fds;		-> (sys.pipe((fds : sys.fd[2]#)) : errno)}
+const dup2	= {ofd, nfd;	-> check(sys.dup((ofd : sys.fd), (nfd : sys.fd)))}
 
 /* path manipulation */
 const remove	= {path;	-> sys.remove(path) == 0}
@@ -183,7 +183,7 @@
 const mkdir	= {path, mode;
 	var fd
 
-	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
+	fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode : int))
 	if fd < 0
 		-> lasterr()
 	;;
@@ -192,9 +192,9 @@
 }
 
 /* process stuff */
-const getpid	= {;	-> sys.tosptr.pid castto(pid)}
-const suicide	= {;	(0 castto(byte#))#}	/* let's happy segfault!! t */
-const fork	= {;		-> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
+const getpid	= {;	-> (sys.tosptr.pid : pid)}
+const suicide	= {;	(0 : byte#)#}	/* let's happy segfault!! t */
+const fork	= {;		-> (sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) : pid)}
 const execv	= {cmd, args;
 	sys.exec(cmd, args)
 	-> lasterr()
@@ -206,7 +206,7 @@
 }
 
 const nanosleep = {nsecs
-	if sys.sleep((nsecs/1_000_000) castto(uint32)) < 0
+	if (sys.sleep((nsecs/1_000_000) : int32)) < 0
 		-> lasterr()
 	;;
 	-> 0
@@ -217,22 +217,22 @@
 	var endp, oldp
 
 	oldp = sys.curbrk
-	endp = (sys.curbrk castto(intptr)) + (sz castto(intptr))
+	endp = (sys.curbrk : intptr) + (sz : intptr)
 	endp = (endp + 4095) & ~4095
-	if sys.brk_(endp castto(byte#)) < 0
+	if sys.brk_((endp : byte#)) < 0
 		-> Failmem
 	;;
-	sys.curbrk = endp castto(byte#)
+	sys.curbrk = (endp : byte#)
 	-> oldp
 }
 	
 const freemem = {p, sz
 	/* FIXME: we leak address space */
-	sys.segfree(p, sz castto(sys.size))
+	sys.segfree(p, (sz : sys.size))
 }
 
 const curtime = {
-	-> sys.nsec()/1000 castto(time)
+	-> (sys.nsec()/1000 : time)
 }
 
 const p9errstr = {errbuf
@@ -247,7 +247,7 @@
 
 /* FIXME: will be needed when we resize stat bufs when statting.
 const statsz = {buf
-	-> (buf[0] castto(int64)) | ((buf[1] << 8) castto(int64))
+	-> (buf[0] : int64)) | ((buf[1] << 8 : int64))
 }
 */
 
@@ -255,7 +255,7 @@
 	if e < 0
 		-> `Fail lasterr()
 	else
-		-> `Ok e castto(@b)
+		-> `Ok (e : @b)
 	;;
 }
 
--- a/lib/std/syswrap+posixy.myr
+++ b/lib/std/syswrap+posixy.myr
@@ -19,18 +19,18 @@
 		uname	: sys.utsname	/* storage */
 	;;
 
-	const Failmem	: byte#	= -1 castto(byte#)
+	const Failmem	: byte#	= (-1	: byte#)
 
-	const Seekset	: whence = sys.Seekset	castto(whence)
-	const Seekcur	: whence = sys.Seekcur	castto(whence)
-	const Seekend	: whence = sys.Seekend	castto(whence)
+	const Seekset	: whence = (sys.Seekset	: whence)
+	const Seekcur	: whence = (sys.Seekcur	: whence)
+	const Seekend	: whence = (sys.Seekend	: whence)
 
-	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
-	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
-	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
-	const Ocreat   	: fdopt = sys.Ocreat	castto(fdopt)
-	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
-	const Odir	: fdopt = sys.Odir	castto(fdopt)
+	const Ordonly  	: fdopt = (sys.Ordonly	: fdopt)
+	const Owronly  	: fdopt = (sys.Owronly	: fdopt)
+	const Ordwr    	: fdopt = (sys.Ordwr	: fdopt)
+	const Ocreat   	: fdopt = (sys.Ocreat	: fdopt)
+	const Otrunc   	: fdopt = (sys.Otrunc	: fdopt)
+	const Odir	: fdopt = (sys.Odir	: fdopt)
 
 	/* fd stuff */
 	const open	: (path : byte[:], opts : fdopt -> result(fd, errno))
@@ -72,19 +72,19 @@
 ;;
 
 /* fd stuff */
-const open	= {path, opts;	-> check(sys.open(path, opts castto(sys.fdopt)))}
-const openmode	= {path, opts, mode;	-> check(sys.openmode(path, opts castto(sys.fdopt), mode))}
-const close	= {fd;		-> sys.close(fd castto(sys.fd)) castto(errno)}
+const open	= {path, opts;	-> check(sys.open(path, (opts : sys.fdopt)))}
+const openmode	= {path, opts, mode;	-> check(sys.openmode(path, (opts : sys.fdopt), mode))}
+const close	= {fd;		-> (sys.close((fd : sys.fd)) : errno)}
 
 const creat	= {path, mode;	-> check(sys.creat(path, mode))}
-const read	= {fd, buf;	-> check(sys.read(fd castto(sys.fd), buf))}
-const write	= {fd, buf;	-> check(sys.write(fd castto(sys.fd), buf))}
-const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#)) castto(errno)}
-const seek	= {fd, delta, whence;	-> check(sys.lseek(fd castto(sys.fd), delta castto(sys.off), whence castto(sys.whence)))}
-const dup2	= {ofd, nfd;	-> check(sys.dup2(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd))}
+const read	= {fd, buf;	-> check(sys.read((fd : sys.fd), buf))}
+const write	= {fd, buf;	-> check(sys.write((fd : sys.fd), buf))}
+const pipe	= {fds;		-> (sys.pipe((fds : sys.fd[2]#)) : errno)}
+const seek	= {fd, delta, whence;	-> check(sys.lseek((fd : sys.fd), (delta : sys.off), (whence : sys.whence)))}
+const dup2	= {ofd, nfd;	-> check((sys.dup2((ofd : sys.fd), (nfd : sys.fd)) : fd))}
 
 /* path manipulation */
-const mkdir	= {path, mode;	-> sys.mkdir(path, mode) castto(errno)}
+const mkdir	= {path, mode;	-> (sys.mkdir(path, mode) : errno)}
 const chdir	= {path;	-> sys.chdir(path) == 0}
 const remove	= {path;	-> sys.unlink(path) == 0}
 
@@ -98,25 +98,25 @@
 }
 
 /* process stuff */
-const getpid	= {;		-> sys.getpid() castto(pid)}
+const getpid	= {;		-> (sys.getpid() : pid)}
 const suicide	= {;		sys.kill(sys.getpid(), 6)}	/* kill self with sigabort */
-const fork	= {;		-> sys.fork() castto(pid)}
-const execv	= {cmd, args;	-> sys.execv(cmd, args) castto(errno)}
-const execve	= {cmd, args, env;	-> sys.execve(cmd, args, env) castto(errno)}
+const fork	= {;		-> (sys.fork() : pid)}
+const execv	= {cmd, args;	-> (sys.execv(cmd, args) : errno)}
+const execve	= {cmd, args, env;	-> (sys.execve(cmd, args, env) : errno)}
 
 /* memory stuff */
 const getmem	= {sz;		
 	sz = (sz + 4095) & ~4095
-	-> sys.mmap(0 castto(byte#), sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+	-> sys.mmap((0 : byte#), (sz : sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
 }
-const freemem	= {p, sz;	sys.munmap(p, sz castto(sys.size))}
+const freemem	= {p, sz;	sys.munmap(p, (sz : sys.size))}
 const curtime = {
 	var tm, sec, nsec
 
 	if sys.clock_gettime(`sys.Clockrealtime, &tm) == 0
 		sec = tm.sec
-		nsec = tm.nsec castto(uint64)
-		-> (sec*1_000_000 + nsec/1000) castto(time)
+		nsec = (tm.nsec : uint64)
+		-> ((sec*1_000_000 + nsec/1000) : time)
 	else
 		-> -1
 	;;
@@ -154,8 +154,8 @@
 
 	r = sys.stat(path, &sb)
 	if r >= 0
-		sec = sb.mtime.sec castto(time)
-		nsec = sb.mtime.nsec castto(time)
+		sec = (sb.mtime.sec : time)
+		nsec = (sb.mtime.nsec : time)
 		-> `Ok sec*1000 + nsec/1_000_000
 	else
 		-> check(r)
@@ -167,7 +167,7 @@
 
 	r = sys.stat(path, &sb)
 	if r >= 0
-		-> `Ok (sb.size castto(off))
+		-> `Ok ((sb.size : off))
 	else
 		-> check(r)
 	;;
@@ -175,8 +175,8 @@
 
 generic check = {e : @a::(integral, numeric) -> result(@b, errno)
 	if e < 0
-		-> `Fail e castto(errno)
+		-> `Fail (e : errno)
 	else
-		-> `Ok e castto(@b)
+		-> `Ok (e : @b)
 	;;
 }
--- a/lib/std/syswrap-ss+freebsd.myr
+++ b/lib/std/syswrap-ss+freebsd.myr
@@ -19,7 +19,7 @@
 	ns = nsecs % 1_000_000_000
 	req = [.sec = s, .nsec = ns]
 
-	-> sys.nanosleep(&req, &rem) castto(errno)
+	-> (sys.nanosleep(&req, &rem) : errno)
 }
 
 const exit = {status
@@ -29,9 +29,9 @@
 const bgetcwd = {buf
 	var res
 
-	res = sys.__getcwd(buf) castto(errno)
+	res = (sys.__getcwd(buf) : errno)
 	if res == 0
-		-> cstrlen(buf) castto(errno)
+		-> (cstrlen(buf) : errno)
 	elif res == Enomem
 		-> Erange
 	else
--- a/lib/std/syswrap-ss+linux.myr
+++ b/lib/std/syswrap-ss+linux.myr
@@ -16,7 +16,7 @@
 	ns = nsecs % 1_000_000_000
 	req = [.sec = s, .nsec = ns]
 
-	-> sys.nanosleep(&req, &rem) castto(errno)
+	-> (sys.nanosleep(&req, &rem) : errno)
 }
 
 const exit = {status;
@@ -25,7 +25,7 @@
 
 const bgetcwd = {buf;
 	var err
-	err = sys.getcwd(buf) castto(errno)
+	err = (sys.getcwd(buf) : errno)
 	/*
 	if we got a length back, it includes
 	the nul byte. chop that off.
--- a/lib/std/syswrap-ss+openbsd.myr
+++ b/lib/std/syswrap-ss+openbsd.myr
@@ -14,7 +14,7 @@
 const exit	= {status;	sys.exit(status)}
 
 const bgetcwd	= {buf
-	-> (sys.__getcwd(buf) - 1) castto(errno)
+	-> (sys.__getcwd(buf) - 1 : errno)
 }
 
 const nanosleep	= {nsecs
@@ -25,6 +25,6 @@
 	ns = nsecs % 1_000_000_000
 	req = [.sec = s, .nsec = ns]
 
-	-> sys.nanosleep(&req, &rem) castto(errno)
+	-> (sys.nanosleep(&req, &rem) : errno)
 }
 
--- a/lib/std/syswrap-ss+osx.myr
+++ b/lib/std/syswrap-ss+osx.myr
@@ -18,14 +18,14 @@
 	var s, us
 
 	s = nsecs / 1_000_000_000
-	us = (nsecs % 1_000_000_000 / 1000) castto(uint32)
-	-> sys.select( \
+	us = (nsecs % 1_000_000_000 / 1000 : uint32)
+	-> (sys.select( \
 		0, \
-		0 castto(sys.fdset#), \
-		0 castto(sys.fdset#), \
-		0 castto(sys.fdset#), \
+		(0 : sys.fdset#), \
+		(0 : sys.fdset#), \
+		(0 : sys.fdset#), \
 		&[.sec = s, .usec = us] \
-	) castto(errno)
+	) : errno)
 }
 
 const exit	= {status;
@@ -38,13 +38,13 @@
 
 	fd = sys.open(".", sys.Ordonly)
 	if fd < 0
-		-> fd castto(errno)
+		-> (fd : errno)
 	;;
 	/* 
 	FIXME: if the path is longer than sys.Pathmax, we should fall back to
 	the ugly method of finding the path.
 	*/
-	err = sys.fcntl(fd, sys.Fgetpath, path[:] castto(byte#)) castto(errno)
+	err = (sys.fcntl(fd, sys.Fgetpath, (path[:] : byte#)) : errno)
 	if err < 0
 		-> err
 	;;
@@ -53,5 +53,5 @@
 		-> Erange
 	;;
 	slcp(buf[:len], path[:len])
-	-> len castto(errno)
+	-> (len : errno)
 }
--- a/lib/std/syswrap-ss+plan9.myr
+++ b/lib/std/syswrap-ss+plan9.myr
@@ -13,7 +13,7 @@
 
 	fd = sys.open(".", sys.Ordonly)
 	if fd < 0
-		-> fd castto(errno)
+		-> (fd : errno)
 	;;
 
 	if sys.fd2path(fd, buf) == 0
@@ -27,7 +27,7 @@
 		if cstrlen(buf) + 5 == buf.len
 			-> Erange
 		else
-			-> cstrlen(buf) castto(errno)
+			-> (cstrlen(buf) : errno)
 		;;
 	;;
 	-> Emisc
--- a/lib/std/test/bytebuf.myr
+++ b/lib/std/test/bytebuf.myr
@@ -20,42 +20,42 @@
 	std.assert(std.sleq(bb.buf[:bb.len], "abc"), \
 		"byte buf contents not \"abc\"\n")
 
-	std.bytebufputb(bb, 'd' castto(byte))
+	std.bytebufputb(bb, ('d' : byte))
 	std.assert(bb.len == 4, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcd"), \
 		"byte buf contents not \"abcd\"\n")
 
-	std.bytebufputle8(bb, 'e' castto(int64))
+	std.bytebufputle8(bb, ('e' : int64))
 	std.assert(bb.len == 5, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcde"), \
 		"byte buf contents not \"abcde\"\n")
 
-	std.bytebufputbe8(bb, 'e' castto(int64))
+	std.bytebufputbe8(bb, ('e' : int64))
 	std.assert(bb.len == 6, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcdee"), \
 		"byte buf contents not \"abcdee\"\n")
 
-	std.bytebufputle16(bb, ('f' | ('g' << 8)) castto(int64))
+	std.bytebufputle16(bb, ('f' | ('g' << 8) : int64))
 	std.assert(bb.len == 8, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefg"), \
 		"byte buf contents not \"abcdeefg\"\n")
 
-	std.bytebufputbe16(bb, ('f' | ('g' << 8)) castto(int64))
+	std.bytebufputbe16(bb, ('f' | ('g' << 8) : int64))
 	std.assert(bb.len == 10, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggf"), \
 		"byte buf contents not \"abcdeefggf\"\n")
 
-	std.bytebufputle32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24)) castto(int64))
+	std.bytebufputle32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24) : int64))
 	std.assert(bb.len == 14, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijk"), \
 		"byte buf contents not \"abcdeefggfhijk\"\n")
 
-	std.bytebufputbe32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24)) castto(int64))
+	std.bytebufputbe32(bb, ('h' | ('i' << 8) | ('j' << 16) | ('k' << 24) : int64))
 	std.assert(bb.len == 18, "byte buf size wrong\n")
 	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjih"), \
 		"byte buf contents not \"abcdeefggfhijkkji\"\n")
 
-	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24)) castto(int64)
+	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24) : int64)
 	v |= v << 32
 	std.bytebufputle64(bb, v)
 	std.assert(bb.len == 26, "byte buf size wrong\n")
@@ -62,7 +62,7 @@
 	std.assert(std.sleq(bb.buf[:bb.len], "abcdeefggfhijkkjihlmnolmno"), \
 		"byte buf contents not \"abcdeefggfhijkkjihlmnolmno\"\n")
 
-	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24)) castto(int64)
+	v = ('l' | ('m' << 8) | ('n' << 16) | ('o' << 24) : int64)
 	v |= v << 32
 	std.bytebufputbe64(bb, v)
 	std.assert(bb.len == 34, "byte buf size wrong\n")
--- a/lib/std/test/fmt.myr
+++ b/lib/std/test/fmt.myr
@@ -49,7 +49,7 @@
 	check("a", "{w=0,p=1}", "a")
 	check("        10", "{w=10}", 10)
 	check("0000000010", "{p=0,w=10}", 10)
-	check("4294967295", "{p=0,w=10}", -1 castto(uint))
+	check("4294967295", "{p=0,w=10}", (-1 : uint))
 	check("-000000001", "{p=0,w=10}", -1)
 	check("xxxxxxxx-1", "{p=x,w=10}", -1)
 	check("        -1", "{w=10}", -1)
@@ -123,7 +123,7 @@
 	/* multiple values */
 	check("formatted a pair: [-10, -10], formatted a pair: [-10, -10]", "{}, {}", p, p)
 	/* multiple values of different types */
-	check("11, formatted a pair: [-10, -10], formatted an int: 111", "{}, {}, {}", 11 castto(byte), p, 111)
+	check("11, formatted a pair: [-10, -10], formatted an int: 111", "{}, {}, {}", (11 : byte), p, 111)
 
 	/* in aggregates */
 	check("[formatted a pair: [-10, -10]]", "{}", [p])
@@ -137,7 +137,7 @@
 	std.assert(opts.len == 0, "options passed where none should be")
 	x = std.vanext(ap)
 	/* cast to other int type so we don't recurse */
-	std.sbfmt(sb, "formatted an int: {}", x castto(int32))
+	std.sbfmt(sb, "formatted an int: {}", (x : int32))
 }
 
 const pairfmt = {sb, ap, opts
--- a/lib/std/utf.myr
+++ b/lib/std/utf.myr
@@ -2,7 +2,7 @@
 use "types"
 
 pkg std =
-	const Badchar	: char = -1 castto(char)
+	const Badchar	: char	= -1
 	const Maxcharlen : size = 4
 	const Maxcharval : char = 0x10FFFF
 
@@ -40,15 +40,15 @@
 	if (len == 1)
 		mark = 0
 	else
-		mark = (((1 << (8 - len)) - 1) ^ 0xff) castto(char)
+		mark = ((1 << (8 - len) - 1) ^ 0xff : char)
 	;;
 
 	for var i = len - 1; i > 0; i--
-		buf[i] = (c & 0x3f | 0x80) castto(byte)
+		buf[i] = (c & 0x3f | 0x80 : byte)
 		c >>= 6
 	;;
 
-	buf[0] = (c | mark) castto(byte)
+	buf[0] = (c | mark : byte)
 	-> len
 }
 
@@ -93,11 +93,11 @@
 	;;
 
 	mask = (1 << (8 - len)) - 1
-	chr = (c castto(uint32)) & mask
+	chr = (c : uint32) & mask
 	for var i = 1; i < len; i++
-		tmp = str[i] castto(uint32)
+		tmp = (str[i] : uint32)
 		chr = (chr << 6) | (tmp & 0x3f)
 	;;
 
-	-> (chr castto(char), str[len:])
+	-> ((chr : char), str[len:])
 }
--- a/lib/std/varargs.myr
+++ b/lib/std/varargs.myr
@@ -48,8 +48,8 @@
 	*/
 		
 	tc = typeenc(args)
-	ip = (args castto(intptr)) + sizeof(byte#)
-	a = ip castto(byte#)
+	ip = (args : intptr) + sizeof(byte#)
+	a = (ip : byte#)
 	-> [.args = a, .tc = tc]
 }
 
@@ -74,10 +74,10 @@
 	ti = typeinfo(ty)
 
 	/* apply the alignment to the arg pointer */
-	align = ti.align castto(intptr)
-	p = arg castto(intptr)
+	align = (ti.align : intptr)
+	p = (arg : intptr)
 	p = (p + align - 1) & ~(align - 1)
-	-> p castto(byte#)
+	-> (p : byte#)
 }
 
 const vaenterunion = {ap, elt
@@ -84,10 +84,10 @@
 	var sub, ti, p, align
 
 	ti = typeinfo(tcpeek(&ap.tc))
-	align = ti.align castto(intptr)
-	p = ap.args castto(intptr)
+	align = (ti.align : intptr)
+	p = (ap.args : intptr)
 	p = (p + align - 1) & ~(align - 1)
-	ap.args = p castto(byte#)
+	ap.args = (p : byte#)
 	match typedesc(vatype(ap))
 	| `Tyunion nc:	
 		for var i = 0; i < elt; i++
@@ -111,16 +111,16 @@
 	ti = typeinfo(tcpeek(&ap.tc))
 
 	/* apply the alignment to the arg pointer */
-	align = ti.align castto(intptr)
-	p = ap.args castto(intptr)
+	align = (ti.align : intptr)
+	p = (ap.args : intptr)
 	p = (p + align - 1) & ~(align - 1)
-	ap.args = p castto(byte#)
+	ap.args = (p : byte#)
 
 	sl = ap.args[:ti.size]
 	tcnext(&ap.tc)
 
-	sz = ti.size castto(intptr)
-	ap.args = ((p castto(intptr)) + sz) castto(byte#)
+	sz = (ti.size : intptr)
+	ap.args = ((p : intptr) + sz : byte#)
 
 	-> sl
 }
@@ -133,26 +133,26 @@
 	ti = typeinfo(tcpeek(&ap.tc))
 
 	/* apply the alignment to the arg pointer */
-	align = ti.align castto(intptr)
-	p = ap.args castto(intptr)
+	align = (ti.align : intptr)
+	p = (ap.args : intptr)
 	p = (p + align - 1) & ~(align - 1)
 
 	/* TODO: check for type mismatch */
 	tcnext(&ap.tc)
 	/* only move on after we read through the value */
-	ap.args = ((p castto(intptr)) + sizeof(@a)) castto(byte#)
-	-> (p castto(@a#))#
+	ap.args = ((p : intptr) + sizeof(@a) : byte#)
+	-> (p : @a#)#
 }
 
 const addp = {p, k
-	-> (p castto(intptr)) + k castto(byte#)
+	-> ((p : intptr) + k  : byte#)
 }
 
 const sliceptr = {p
-	-> (p castto(byte##))#
+	-> (p : byte##)#
 }
 
 const slicelen = {p
 	p = addp(p, sizeof(intptr))
-	-> (p castto(size#))#
+	-> (p : size#)#
 }
--- a/lib/std/wait+plan9.myr
+++ b/lib/std/wait+plan9.myr
@@ -34,7 +34,7 @@
 	var n
 
 	if !statusinit
-		statusmap = mkht(pidhash, pideq)
+		statusmap = mkht(inthash, inteq)
 		statusinit = true
 	;;
 		
@@ -91,5 +91,3 @@
 
 }
 
-const pidhash	= {x;	-> inthash(x castto(int32))}
-const pideq	= {a, b;	-> a == b}
--- a/lib/std/wait+posixy.myr
+++ b/lib/std/wait+posixy.myr
@@ -18,7 +18,7 @@
 	var st
 
 :again
-	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
+	if sys.waitpid((pid : sys.pid), &st, 0) > 0
 		match sys.waitstatus(st)
 		/* 
 		when a process stops, eg, if paused by a debugger,
--- a/lib/sys/sys+freebsd-x64.myr
+++ b/lib/sys/sys+freebsd-x64.myr
@@ -311,7 +311,7 @@
 	const Fdup2fd_cloexec	 : fcntlcmd = 18		/* Like F_DUP2FD, but FD_CLOEXEC is set */
 
 	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
+	const Mapbad	: byte# = (-1 : byte#)
 
 	/* umtx ops */
 	const Umtxlock	: umtxop = 0
@@ -875,9 +875,9 @@
 
 /* 
 wraps a syscall argument, converting it to 64 bits for the syscall function. This is
-the same as casting, but more concise than writing castto(int64)
+the same as casting, but more concise than (writing : int64)
 */
-generic a = {x : @t; -> x castto(uint64)}
+generic a = {x : @t; -> (x : uint64)}
 
 extern const cstring	: (str : byte[:] -> byte#)
 extern const alloca	: (sz : size	-> byte#)
@@ -887,12 +887,12 @@
 
 /* process management */
 const exit	= {status;		syscall(Sysexit, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid, 1) castto(pid)}
+const getpid	= {;			-> (syscall(Sysgetpid, 1) : pid)}
 const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
-const fork	= {;			-> syscall(Sysfork) castto(pid)}
+const fork	= {;			-> (syscall(Sysfork) : pid)}
 const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, pid, loc, opt, usage)}
 const waitpid	= {pid, loc, opt;
-	-> wait4(pid, loc, opt, 0 castto(rusage#)) 
+	-> wait4(pid, loc, opt, (0 : rusage#)) 
 }
 
 const execv	= {cmd, args
@@ -901,11 +901,11 @@
 	/* of course we fucking have to duplicate this code everywhere,
 	* since we want to stack allocate... */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
+	cargs = ((p : byte##))[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
 }
 
@@ -915,11 +915,11 @@
 
 	/* copy the args */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len]
+	cargs = ((p : byte##))[:args.len]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 
 	/*
 	 copy the env.
@@ -927,75 +927,75 @@
 	 since we want to stack allocate... 
 	*/
 	p = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (p castto(byte##))[:env.len]
+	cenv = ((p : byte##))[:env.len]
 	for i = 0; i < env.len; i++
 		cenv[i] = cstring(env[i])
 	;;
-	cenv[env.len] = 0 castto(byte#)
+	cenv[env.len] = (0 : byte#)
 
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
 }
 
 /* thread management */
-const thr_new	= {param, sz;	-> syscall(Systhr_new, a(param), a(sz)) castto(int)}
+const thr_new	= {param, sz;	-> (syscall(Systhr_new, a(param), a(sz)) : int)}
 const thr_exit	= {state;	syscall(Systhr_exit, a(state))}
-const umtx_op	= {obj, op, val, a1, a2; -> syscall(Sys_umtx_op, a(obj), a(op), a(val), a(a1), a(a2)) castto(int)}
-const yield	= {;	-> syscall(Sysyield) castto(int)}
+const umtx_op	= {obj, op, val, a1, a2; -> (syscall(Sys_umtx_op, a(obj), a(op), a(val), a(a1), a(a2)) : int)}
+const yield	= {;	-> (syscall(Sysyield) : int)}
 
 /* fd manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const open	= {path, opts;		-> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)}
+const openmode	= {path, opts, mode;	-> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)}
 const close	= {fd;			-> syscall(Sysclose, a(fd))}
-const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
-const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const creat	= {path, mode;		-> (openmode(path, Ocreat | Otrunc | Owronly, mode) : fd)}
+const unlink	= {path;		-> (syscall(Sysunlink, cstring(path)) : int)}
+const read	= {fd, buf;		-> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)}
+const write	= {fd, buf;		-> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)}
 const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
 const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
 const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
 const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)
+const mkdir	= {path, mode;		-> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)}
+generic ioctl	= {fd, req, arg;	-> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)
 }
-const getdirentries	= {fd, buf, basep;	-> syscall(Sysgetdirentries, a(fd), buf castto(byte#), a(buf.len), a(basep))}
+const getdirentries	= {fd, buf, basep;	-> syscall(Sysgetdirentries, a(fd), (buf : byte#), a(buf.len), a(basep))}
 const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
 const __getcwd	= {buf;	-> syscall(Sys__getcwd, a(buf), a(buf.len))}
 
 /* file stuff */
 const pipe	= {fds;	-> __freebsd_pipe(fds)}
-const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
-const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
+const dup 	= {fd;	-> (syscall(Sysdup, a(fd)) : fd)}
+const dup2 	= {src, dst;	-> (syscall(Sysdup2, a(src), a(dst)) : fd)}
 const fcntl	= {fd, cmd, args; 	-> syscall(Sysfcntl, a(fd), a(cmd), a(args))}
-const poll	= {pfd, tm;	-> syscall(Syspoll, pfd castto(byte#), a(pfd.len), a(tm)) castto(int)}
+const poll	= {pfd, tm;	-> (syscall(Syspoll, (pfd : byte#), a(pfd.len), a(tm)) : int)}
 
 /* signals */
-const sigaction	= {sig, act, oact;	-> syscall(Syssigaction, a(sig), a(act), a(oact)) castto(int)}
-const sigprocmask	= {sig, act, oact;	-> syscall(Syssigprocmask, a(sig), a(act), a(oact)) castto(int)}
+const sigaction	= {sig, act, oact;	-> (syscall(Syssigaction, a(sig), a(act), a(oact)) : int)}
+const sigprocmask	= {sig, act, oact;	-> (syscall(Syssigprocmask, a(sig), a(act), a(oact)) : int)}
 
 /* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-const setsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
-const getsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
+const socket	= {dom, stype, proto;	-> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd) }
+const connect	= {sock, addr, len;	-> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)}
+const accept	= {sock, addr, len;	-> (syscall(Sysaccept, a(sock), a(addr), a(len)) : fd)}
+const listen	= {sock, backlog;	-> (syscall(Syslisten, a(sock), a(backlog)) : int)}
+const bind	= {sock, addr, len;	-> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)}
+const setsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
+const getsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
 
 /* memory management */
 const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
 const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)}
+	-> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) : byte#)}
 
 /* time */
-const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
-const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
-const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
-const nanosleep	= {req, rem;	-> syscall(Sysnanosleep, a(req), a(rem)) castto(int32)}
+const clock_getres = {clk, ts;	-> (syscall(Sysclock_getres, clockid(clk), a(ts)) : int32)}
+const clock_gettime = {clk, ts;	-> (syscall(Sysclock_gettime, clockid(clk), a(ts)) : int32)}
+const clock_settime = {clk, ts;	-> (syscall(Sysclock_settime, clockid(clk), a(ts)) : int32)}
+const nanosleep	= {req, rem;	-> (syscall(Sysnanosleep, a(req), a(rem)) : int32)}
 const sched_yield = {;	syscall(Syssched_yield)}
 
 
 /* system information */
-const uname	= {buf;	-> syscall(Sysfreebsd4_uname, a(buf)) castto(int)}
+const uname	= {buf;	-> (syscall(Sysfreebsd4_uname, a(buf)) : int)}
 
 const sysctl = {mib, old, new
 	var mibp
@@ -1007,16 +1007,16 @@
 	var newsz
 	var ret
 
-	mibp = mib castto(byte#)
+	mibp = (mib : byte#)
 	mibsz = a(mib.len)
 	o = old#
-	oldp = o castto(byte#)
+	oldp = (o : byte#)
 	oldsz = a(o.len)
-	newp = new castto(byte#)
+	newp = (new : byte#)
 	newsz = a(new.len)
 
 	/* all args already passed through a() or ar  ptrs */
-	ret = syscall(Sys__sysctl, mibp, mibsz, oldp, oldsz, newp, newsz) castto(int)
+	ret = (syscall(Sys__sysctl, mibp, mibsz, oldp, oldsz, newp, newsz) : int)
 
 	old# = o[:oldsz]
 	-> ret
--- a/lib/sys/sys+linux-x64.myr
+++ b/lib/sys/sys+linux-x64.myr
@@ -318,7 +318,7 @@
 	const Seekend	: whence = 2
 
 	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
+	const Mapbad	: byte# = (-1 : byte#)
 
 	/* syscalls */
 	const Sysread			: scno = 0
@@ -723,9 +723,9 @@
 
 /* 
 wraps a syscall argument, converting it to 64 bits for the syscall function.
-This is the same as casting, but more concise than writing castto(int64).
+This is the same as casting, but more concise than writing a cast to int64.
 */
-generic a = {x : @t; -> x castto(uint64)}
+generic a = {x : @t; -> (x : uint64)}
 
 /* asm stubs from util.s */
 extern const cstring	: (str : byte[:] -> byte#)
@@ -734,10 +734,10 @@
 /* process management */
 const exit	= {status;		syscall(Sysexit, a(status))}
 const exit_group	= {status;	syscall(Sysexit_group, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid) castto(pid)}
+const getpid	= {;			-> (syscall(Sysgetpid) : pid)}
 const kill	= {pid, sig;		-> syscall(Syskill, a(pid), a(sig))}
-const fork	= {;			-> syscall(Sysfork) castto(pid)}
-const clone	= {flags, stk, ptid, ctid, ptreg;	-> syscall(Sysclone, a(flags), a(stk), a(ptid), a(ctid), a(ptreg)) castto(pid)}
+const fork	= {;			-> (syscall(Sysfork) : pid)}
+const clone	= {flags, stk, ptid, ctid, ptreg;	-> (syscall(Sysclone, a(flags), a(stk), a(ptid), a(ctid), a(ptreg)) : pid)}
 const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, a(pid), a(loc), a(opt), a(usage))}
 const waitpid	= {pid, loc, opt;
 	var rusage
@@ -750,11 +750,11 @@
 	/* of course we fucking have to duplicate this code everywhere,
 	* since we want to stack allocate... */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
+	cargs = (p : byte##)[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
 }
 
@@ -764,11 +764,11 @@
 
 	/* copy the args */
 	ap = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (ap castto(byte##))[:args.len + 1]
+	cargs = (ap : byte##)[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 
 	/*
 	 copy the env.
@@ -776,38 +776,38 @@
 	 since we want to stack allocate... 
 	*/
 	ep = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (ep castto(byte##))[:env.len]
+	cenv = (ep : byte##)[:env.len]
 	for i = 0; i < env.len; i++
 		cenv[i] = cstring(env[i])
 	;;
-	cenv[env.len] = 0 castto(byte#)
+	cenv[env.len] = (0 : byte#)
 
 	-> syscall(Sysexecve, cstring(cmd), a(ap), a(ep))
 }
 
 /* file manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const open	= {path, opts;		-> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)}
+const openmode	= {path, opts, mode;	-> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)}
 const close	= {fd;			-> syscall(Sysclose, a(fd))}
-const creat	= {path, mode;		-> syscall(Syscreat, cstring(path), a(mode)) castto(fd)}
+const creat	= {path, mode;		-> (syscall(Syscreat, cstring(path), a(mode)) : fd)}
 const rename	= {from, to;		-> syscall(Sysrename, cstring(from), cstring(to))}
-const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const unlink	= {path;		-> (syscall(Sysunlink, cstring(path)) : int)}
+const read	= {fd, buf;		-> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)}
+const write	= {fd, buf;		-> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)}
 const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
 const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
 const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
 const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
-const getdents64	= {fd, buf;	-> syscall(Sysgetdents64, a(fd), buf castto(byte#), a(buf.len))}
+const mkdir	= {path, mode;		-> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)}
+generic ioctl	= {fd, req, arg;	-> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)}
+const getdents64	= {fd, buf;	-> syscall(Sysgetdents64, a(fd), (buf : byte#), a(buf.len))}
 const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
 const getcwd	= {buf;	-> syscall(Sysgetcwd, a(buf), a(buf.len))}
 
 /* file stuff */
 const pipe	= {fds;	-> syscall(Syspipe, a(fds))}
-const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
-const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
+const dup 	= {fd;	-> (syscall(Sysdup, a(fd)) : fd)}
+const dup2 	= {src, dst;	-> (syscall(Sysdup2, a(src), a(dst)) : fd)}
 
 /* threading */
 const futex	= {uaddr, op, val, timeout, uaddr2, val3
@@ -814,36 +814,36 @@
 	-> syscall(Sysfutex, a(uaddr), a(op), a(val), a(timeout), a(uaddr2), a(val3))}
 
 /* poll */
-const poll	= {pfd, timeout;	-> syscall(Syspoll, pfd castto(pollfd#), a(pfd.len), a(timeout)) castto(int)}
+const poll	= {pfd, timeout;	-> (syscall(Syspoll, (pfd : pollfd#), a(pfd.len), a(timeout)) : int)}
 const epollctl	= {epfd, op, fd, evt;
-	-> syscall(Sysepoll_ctl, a(epfd), a(op), a(fd), a(evt)) castto(int)}
+	-> (syscall(Sysepoll_ctl, a(epfd), a(op), a(fd), a(evt)) : int)}
 const epollwait	= {epfd, evts, timeout;
-	-> syscall(Sysepoll_wait, a(epfd), evts castto(epollevt#), a(evts.len), a(timeout)) castto(int)}
-const epollcreate	= {flg;	-> syscall(Sysepoll_create1, a(flg)) castto(fd)}
+	-> (syscall(Sysepoll_wait, a(epfd), (evts : epollevt#), a(evts.len), a(timeout)) : int)}
+const epollcreate	= {flg;	-> (syscall(Sysepoll_create1, a(flg)) : fd)}
 
 /* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd)}
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const accept	= {sock, addr, lenp;	-> syscall(Sysaccept, a(sock), a(addr), a(lenp)) castto(fd)}
-const setsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
-const getsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
+const socket	= {dom, stype, proto;	-> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd)}
+const connect	= {sock, addr, len;	-> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)}
+const bind	= {sock, addr, len;	-> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)}
+const listen	= {sock, backlog;	-> (syscall(Syslisten, a(sock), a(backlog)) : int)}
+const accept	= {sock, addr, lenp;	-> (syscall(Sysaccept, a(sock), a(addr), a(lenp)) : fd)}
+const setsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
+const getsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
 
 /* memory mapping */
 const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
 const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)
+	-> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) : byte#)
 }
 
 /* time */
-const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
-const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
-const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
-const nanosleep	= {req, rem;	-> syscall(Sysnanosleep, a(req), a(rem)) castto(int32)}
+const clock_getres = {clk, ts;	-> (syscall(Sysclock_getres, clockid(clk), a(ts)) : int32)}
+const clock_gettime = {clk, ts;	-> (syscall(Sysclock_gettime, clockid(clk), a(ts)) : int32)}
+const clock_settime = {clk, ts;	-> (syscall(Sysclock_settime, clockid(clk), a(ts)) : int32)}
+const nanosleep	= {req, rem;	-> (syscall(Sysnanosleep, a(req), a(rem)) : int32)}
 
 /* system information */
-const uname	= {buf;	-> syscall(Sysuname, buf) castto(int)}
+const uname	= {buf;	-> (syscall(Sysuname, buf) : int)}
 
 const clockid = {clk
 	match clk
--- a/lib/sys/sys+openbsd-x64.myr
+++ b/lib/sys/sys+openbsd-x64.myr
@@ -253,7 +253,7 @@
 	const Fosetlk	 : fcntlcmd = 8		/* set record locking information */
 
 	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
+	const Mapbad	: byte# = (-1 : byte#)
 
 	/* syscalls */
 	const Syssyscall : scno = 0
@@ -536,9 +536,9 @@
 
 /* 
 wraps a syscall argument, converting it to 64 bits for the syscall function. This is
-the same as casting, but more concise than writing castto(int64)
+the same as casting, but more concise than writing a cast to uint64
 */
-generic a = {x : @t; -> x castto(uint64)}
+generic a = {x : @t; -> (x : uint64)}
 
 extern const cstring	: (str : byte[:] -> byte#)
 extern const alloca	: (sz : size	-> byte#)
@@ -548,12 +548,12 @@
 
 /* process management */
 const exit	= {status;		syscall(Sysexit, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid, 1) castto(pid)}
+const getpid	= {;			-> (syscall(Sysgetpid, 1) : pid)}
 const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
-const fork	= {;			-> syscall(Sysfork) castto(pid)}
+const fork	= {;			-> (syscall(Sysfork) : pid)}
 const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, pid, loc, opt, usage)}
 const waitpid	= {pid, loc, opt;
-	-> wait4(pid, loc, opt, 0 castto(rusage#)) 
+	-> wait4(pid, loc, opt, (0 : rusage#)) 
 }
 
 const execv	= {cmd, args
@@ -562,11 +562,11 @@
 	/* of course we fucking have to duplicate this code everywhere,
 	* since we want to stack allocate... */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
+	cargs = (p : byte##)[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
 }
 
@@ -576,11 +576,11 @@
 
 	/* copy the args */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len]
+	cargs = (p : byte##)[:args.len]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 
 	/*
 	 copy the env.
@@ -588,58 +588,58 @@
 	 since we want to stack allocate... 
 	*/
 	p = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (p castto(byte##))[:env.len]
+	cenv = (p : byte##)[:env.len]
 	for i = 0; i < env.len; i++
 		cenv[i] = cstring(env[i])
 	;;
-	cenv[env.len] = 0 castto(byte#)
+	cenv[env.len] = (0 : byte#)
 
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
 }
 
 /* fd manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const open	= {path, opts;		-> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)}
+const openmode	= {path, opts, mode;	-> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)}
 const close	= {fd;			-> syscall(Sysclose, a(fd))}
-const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
-const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const creat	= {path, mode;		-> (openmode(path, Ocreat | Otrunc | Owronly, mode) : fd)}
+const unlink	= {path;		-> (syscall(Sysunlink, cstring(path)) : int)}
+const read	= {fd, buf;		-> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)}
+const write	= {fd, buf;		-> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)}
 const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
 const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
 const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
 const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
+const mkdir	= {path, mode;		-> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)}
+generic ioctl	= {fd, req, arg;	-> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)}
 const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
 const __getcwd	= {buf;	-> syscall(Sys__getcwd, a(buf), a(buf.len))}
-const getdents	= {fd, buf;		-> syscall(Sysgetdents, a(buf), a(buf.len)) castto(int64)}
+const getdents	= {fd, buf;		-> (syscall(Sysgetdents, a(buf), a(buf.len)) : int64)}
 
 /* file stuff */
 const pipe	= {fds;	-> syscall(Syspipe, fds)}
-const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
-const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
+const dup 	= {fd;	-> (syscall(Sysdup, a(fd)) : fd)}
+const dup2 	= {src, dst;	-> (syscall(Sysdup2, a(src), a(dst)) : fd)}
 const fcntl	= {fd, cmd, args; 	-> syscall(Sysfcntl, a(fd), a(cmd), a(args))}
 
 /* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-const setsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
-const getsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
+const socket	= {dom, stype, proto;	-> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd)}
+const connect	= {sock, addr, len;	-> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)}
+const accept	= {sock, addr, len;	-> (syscall(Sysaccept, a(sock), a(addr), a(len)) : fd)}
+const listen	= {sock, backlog;	-> (syscall(Syslisten, a(sock), a(backlog)) : int)}
+const bind	= {sock, addr, len;	-> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)}
+const setsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
+const getsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
 
 /* memory management */
 const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
 const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)
+	-> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) : byte#)}
 }
 
 /* time */
-const clock_getres = {clk, ts;	-> syscall(Sysclock_getres, clockid(clk), a(ts)) castto(int32)}
-const clock_gettime = {clk, ts;	-> syscall(Sysclock_gettime, clockid(clk), a(ts)) castto(int32)}
-const clock_settime = {clk, ts;	-> syscall(Sysclock_settime, clockid(clk), a(ts)) castto(int32)}
+const clock_getres = {clk, ts;	-> (syscall(Sysclock_getres, clockid(clk), a(ts)) : int32)}
+const clock_gettime = {clk, ts;	-> (syscall(Sysclock_gettime, clockid(clk), a(ts)) : int32)}
+const clock_settime = {clk, ts;	-> (syscall(Sysclock_settime, clockid(clk), a(ts)) : int32)}
 
 const sleep = {time
 	var req, rem
@@ -647,7 +647,7 @@
 	-> nanosleep(&req, &rem)
 }
 
-const nanosleep	= {req, rem;	-> syscall(Sysnanosleep, a(req), a(rem)) castto(int32)}
+const nanosleep	= {req, rem;	-> (syscall(Sysnanosleep, a(req), a(rem)) : int32)}
 
 
 /* system information */
@@ -714,16 +714,16 @@
 	var newsz
 	var ret
 
-	mibp = mib castto(byte#)
+	mibp = (mib : byte#)
 	mibsz = a(mib.len)
 	o = old#
-	oldp = o castto(byte#)
-	oldsz = o.len castto(int64)
-	newp = new castto(byte#)
+	oldp = (o : byte#)
+	oldsz = (o.len : int64)
+	newp = (new : byte#)
 	newsz = a(new.len)
 
 	/* all args already passed through a() or ar  ptrs */
-	ret = syscall(Sys__sysctl, mibp, mibsz, oldp, a(&oldsz), newp, newsz) castto(int)
+	ret = (syscall(Sys__sysctl, mibp, mibsz, oldp, a(&oldsz), newp, newsz) : int)
 
 	old# = o[:oldsz]
 	-> ret
--- a/lib/sys/sys+osx-x64.myr
+++ b/lib/sys/sys+osx-x64.myr
@@ -329,7 +329,7 @@
 	const Pollnval		: uint16 = 0x0020	/* requested events "invalid" */
 
 	/* return value for a failed mapping */
-	const Mapbad	: byte# = -1 castto(byte#)
+	const Mapbad	: byte# = (-1 : byte#)
 
 	/* syscalls.
 	note, creat() implemented as open(path, Creat|Trunc|Wronly) */
@@ -764,10 +764,10 @@
 
 /*
 wraps a syscall argument, converting it to 64 bits for the syscall function. This is
-the same as casting, but more concise than writing castto(int64)
+the same as casting, but more concise than writing a cast to uint64
 */
 generic a = {x : @t
-	-> x castto(uint64)
+	-> (x : uint64)
 }
 
 /* OSX has a number of funky syscalls */
@@ -789,30 +789,30 @@
 
 /* process control */
 const exit	= {status;		syscall(Sysexit, a(status))}
-const getpid	= {;			-> syscall(Sysgetpid) castto(pid)}
+const getpid	= {;			-> (syscall(Sysgetpid) : pid)}
 const kill	= {pid, sig;		-> syscall(Syskill, a(pid), a(sig))}
 const fork	= {;			-> __osx_fork()}
 const wait4	= {pid, loc, opt, rusage;	-> syscall(Syswait4, a(pid), a(loc), a(opt), a(rusage))}
 const waitpid	= {pid, loc, opt;
-	-> wait4(pid, loc, opt, 0 castto(rusage#))
+	-> wait4(pid, loc, opt, (0 : rusage#))
 }
 
 const bsdthread_register = {start, wqthread, sz, dummy, targetconc, queueoff
-	-> syscall(Sysbsdthread_register, \
+	-> (syscall(Sysbsdthread_register, \
 		a(start), \
 		a(wqthread), \
 		a(sz), \
 		a(dummy), \
 		a(targetconc), \
-		a(queueoff)) castto(int)
+		a(queueoff)) : int)
 }
 
 const bsdthread_create	= {func , arg , stk , pthr , flags
-	-> syscall(Sysbsdthread_create, a(func), a(arg), a(stk), a(pthr)) castto(void#)
+	-> (syscall(Sysbsdthread_create, a(func), a(arg), a(stk), a(pthr)) : void#)
 }
 
 const bsdthread_terminate	= {stk , len , port , sem
-	-> syscall(Sysbsdthread_terminate, a(stk), a(len), a(port), a(sem)) castto(int)
+	-> (syscall(Sysbsdthread_terminate, a(stk), a(len), a(port), a(sem)) : int)
 }
 
 const sleep = {time;	-> 0}
@@ -822,11 +822,11 @@
 
 	/* doesn't just call execve() for efficiency's sake. */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
+	cargs = (p : byte##)[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
 }
 
@@ -836,11 +836,11 @@
 
 	/* copy the args */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (p castto(byte##))[:args.len + 1]
+	cargs = (p : byte##)[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 
 	/*
 	 copy the env.
@@ -848,11 +848,11 @@
 	 since we want to stack allocate...
 	*/
 	p = alloca((env.len + 1)*sizeof(byte#))
-	cenv = (p castto(byte##))[:env.len]
+	cenv = (p : byte##)[:env.len]
 	for i = 0; i < env.len; i++
 		cenv[i] = cstring(env[i])
 	;;
-	cenv[env.len] = 0 castto(byte#)
+	cenv[env.len] = (0 : byte#)
 
 	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
 }
@@ -859,37 +859,37 @@
 
 
 /* fd manipulation */
-const open	= {path, opts;		-> syscall(Sysopen, cstring(path), a(opts), a(0o777)) castto(fd)}
-const openmode	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), a(opts), a(mode)) castto(fd)}
+const open	= {path, opts;		-> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)}
+const openmode	= {path, opts, mode;	-> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)}
 const close	= {fd;			-> syscall(Sysclose, a(fd))}
 const rename	= {from, to;		-> syscall(Sysrename, cstring(from), cstring(to))}
-const creat	= {path, mode;		-> openmode(path, Ocreat | Otrunc | Owronly, mode) castto(fd)}
-const unlink	= {path;		-> syscall(Sysunlink, cstring(path)) castto(int)}
-const read	= {fd, buf;		-> syscall(Sysread, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
-const write	= {fd, buf;		-> syscall(Syswrite, a(fd), buf castto(byte#), a(buf.len)) castto(size)}
+const creat	= {path, mode;		-> (openmode(path, Ocreat | Otrunc | Owronly, mode) : fd)}
+const unlink	= {path;		-> (syscall(Sysunlink, cstring(path)) : int)}
+const read	= {fd, buf;		-> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)}
+const write	= {fd, buf;		-> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)}
 const lseek	= {fd, off, whence;	-> __osx_lseek(fd, off, whence)}
 const stat	= {path, sb;		-> syscall(Sysstat64, cstring(path), a(sb))}
 const lstat	= {path, sb;		-> syscall(Syslstat64, cstring(path), a(sb))}
 const fstat	= {fd, sb;		-> syscall(Sysfstat64, a(fd), a(sb))}
-const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
-const getdirentries64	= {fd, buf, basep;	-> syscall(Sysgetdirentries64, a(fd), buf castto(byte#), a(buf.len), a(basep))}
+const mkdir	= {path, mode;		-> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)}
+generic ioctl	= {fd, req, arg;	-> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)}
+const getdirentries64	= {fd, buf, basep;	-> syscall(Sysgetdirentries64, a(fd), (buf : byte#), a(buf.len), a(basep))}
 const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
 
 /* fd stuff */
 const pipe	= {fd;	-> __osx_pipe(fd)}
-const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
-const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
+const dup 	= {fd;	-> (syscall(Sysdup, a(fd)) : fd)}
+const dup2 	= {src, dst;	-> (syscall(Sysdup2, a(src), a(dst)) : fd)}
 const fcntl	= {fd, cmd, args; 	-> syscall(Sysfcntl, a(fd), a(cmd), a(args))}
-const poll	= {pfd, tm;	-> syscall(Syspoll, pfd castto(byte#), a(pfd.len), a(tm)) castto(int)}
-const select	= {nfd, readfd, writefd, errfd, tm; -> syscall(Sysselect, a(nfd), a(readfd), a(writefd), a(errfd), a(tm)) castto(int32)}
+const poll	= {pfd, tm;	-> (syscall(Syspoll, (pfd : byte#), a(pfd.len), a(tm)) : int)}
+const select	= {nfd, readfd, writefd, errfd, tm; -> (syscall(Sysselect, a(nfd), a(readfd), a(writefd), a(errfd), a(tm)) : int32)}
 
 /* kqueueueueueueue */
-const kqueue	= {;	-> syscall(Syskqueue) castto(fd)}
+const kqueue	= {;	-> (syscall(Syskqueue) : fd)}
 const kevent	= {q, cl, el, flg, timeout
 	-> syscall(Syskevent, a(q), \
-		cl castto(kevent#), a(cl.len), \
-		el castto(kevent#), a(el.len), \
+		(cl : kevent#), a(cl.len), \
+		(el : kevent#), a(el.len), \
 		a(flg), \
 		timeout)
 }
@@ -896,29 +896,29 @@
 
 const kevent64	= {q, cl, el, flg, timeout
 	-> syscall(Syskevent, a(q), \
-		cl castto(kevent#), a(cl.len), \
-		el castto(kevent#), a(el.len), \
+		(cl : kevent#), a(cl.len), \
+		(el : kevent#), a(el.len), \
 		a(flg), \
 		timeout)
 }
 
 /* networking */
-const socket	= {dom, stype, proto;	-> syscall(Syssocket, a(dom), a(stype), a(proto)) castto(fd) }
-const connect	= {sock, addr, len;	-> syscall(Sysconnect, a(sock), a(addr), a(len)) castto(int)}
-const accept	= {sock, addr, len;	-> syscall(Sysaccept, a(sock), a(addr), a(len)) castto(fd)}
-const listen	= {sock, backlog;	-> syscall(Syslisten, a(sock), a(backlog)) castto(int)}
-const bind	= {sock, addr, len;	-> syscall(Sysbind, a(sock), a(addr), a(len)) castto(int)}
-const setsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
-const getsockopt	= {sock, lev, opt, val, len;	-> syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) castto(int)}
+const socket	= {dom, stype, proto;	-> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd)}
+const connect	= {sock, addr, len;	-> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)}
+const accept	= {sock, addr, len;	-> (syscall(Sysaccept, a(sock), a(addr), a(len)) : fd)}
+const listen	= {sock, backlog;	-> (syscall(Syslisten, a(sock), a(backlog)) : int)}
+const bind	= {sock, addr, len;	-> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)}
+const setsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
+const getsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
 
 /* memory management */
 const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
 const mmap	= {addr, len, prot, flags, fd, off;
-	-> syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) castto(byte#)}
+	-> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(off)) : byte#)}
 
 /* time */
-const gettimeofday = {tv, tz;	-> __osx_gettimeofday(tv, tz) castto(int)}
-const settimeofday = {tv, tz;	-> syscall(Syssettimeofday, a(tv), a(tz)) castto(int)}
+const gettimeofday = {tv, tz;	-> (__osx_gettimeofday(tv, tz) : int)}
+const settimeofday = {tv, tz;	-> (syscall(Syssettimeofday, a(tv), a(tz)) : int)}
 
 /* faked  with gettimeofday */
 const clock_getres = {clk, ts
@@ -931,7 +931,7 @@
 	var tv
 	var ret
 
-	ret = gettimeofday(&tv, 0 castto(timezone#))
+	ret = gettimeofday(&tv, (0 : timezone#))
 	ts.sec = tv.sec
 	ts.nsec = tv.usec * 1000
 	-> ret
@@ -942,7 +942,7 @@
 
 	tv.sec = ts.sec
 	tv.usec = ts.nsec / 1000
-	-> settimeofday(&tv, 0 castto(timezone#))
+	-> settimeofday(&tv, (0 : timezone#))
 }
 
 /* system information */
@@ -1009,20 +1009,20 @@
 	var newsz
 	var ret
 
-	mibp = mib castto(byte#)
-	mibsz = mib.len castto(uint64)
+	mibp = (mib : byte#)
+	mibsz = (mib.len : uint64)
 	o = old#
-	oldp = o castto(byte#)
-	oldsz = (o.len castto(uint64))
+	oldp = (o : byte#)
+	oldsz = (o.len : uint64)
 	if new.len > 0
-		newp = new castto(byte#)
-		newsz = new.len castto(uint64)
+		newp = (new : byte#)
+		newsz = (new.len : uint64)
 	else
-		newp = 0 castto(byte#)
+		newp = (0 : byte#)
 		newsz = 0
 	;;
 
-	ret = syscall(Sys__sysctl, a(mibp), a(mibsz), a(oldp), a(&oldsz), a(newp), a(newsz)) castto(int)
+	ret = (syscall(Sys__sysctl, a(mibp), a(mibsz), a(oldp), a(&oldsz), a(newp), a(newsz)) : int)
 
 	old# = o[:oldsz]
 	-> ret
--- a/lib/sys/sys+plan9-x64.myr
+++ b/lib/sys/sys+plan9-x64.myr
@@ -181,24 +181,24 @@
 8 bytes, Myrddin uses natural alignment (min(sizeof(t), 16).
 Cast to a 64 bit type to paper over this.
 */
-generic a	= {a : @t;	-> a castto(uint64)}
-generic s	= {a : @t;	-> a castto(int64)}
-generic p	= {a : @t;	-> a castto(byte#)}
+generic a	= {a : @t;	-> (a : uint64)}
+generic s	= {a : @t;	-> (a : int64)}
+generic p	= {a : @t;	-> (a : byte#)}
 
 const sysr1	= {;		-> syscall(Syssysr1)}
 const bind	= {name, old;	-> syscall(Sysbind, cstring(name), cstring(old))}
 const chdir 	= {dir;		-> syscall(Syschdir, cstring(dir)) }
 const close 	= {fd;		-> syscall(Sysclose, a(fd))}
-const dup	= {ofd, nfd;	-> syscall(Sysdup, a(ofd), a(nfd)) castto(fd)}
+const dup	= {ofd, nfd;	-> (syscall(Sysdup, a(ofd), a(nfd)) : fd)}
 const alarm 	= {msec;	-> syscall(Sysalarm, a(msec))}
 const exits 	= {msg;		-> syscall(Sysexits, cstring(msg))}
 const fauth 	= {fd, aname;	-> syscall(Sysfauth, a(fd), cstring(aname))}
 const segbrk 	= {saddr, addr;	-> syscall(Syssegbrk, a(saddr), a(addr))}
-const open 	= {path, opt;	-> syscall(Sysopen, cstring(path), a(opt)) castto(fd)}
+const open 	= {path, opt;	-> (syscall(Sysopen, cstring(path), a(opt)) : fd)}
 const sleep 	= {msec;	-> syscall(Syssleep, a(msec))}
-const rfork 	= {rflags;	-> syscall(Sysrfork, a(rflags)) castto(pid)}
+const rfork 	= {rflags;	-> (syscall(Sysrfork, a(rflags)) : pid)}
 const pipe 	= {fds;		-> syscall(Syspipe, a(fds))}
-const create 	= {path, mode, perm;	-> syscall(Syscreate, cstring(path), a(mode), a(perm)) castto(fd)}
+const create 	= {path, mode, perm;	-> (syscall(Syscreate, cstring(path), a(mode), a(perm)) : fd)}
 const fd2path	= {fd, buf;	-> syscall(Sysfd2path, a(fd), p(buf), a(buf.len))}
 const remove	= {path;	-> syscall(Sysremove, cstring(path))}
 const notify	= {fn;		-> syscall(Sysnotify, fn)}	/* FIXME: this is likely to break when we do closures... */
@@ -214,11 +214,11 @@
 const wstat	= {name, edir;	-> syscall(Syswstat, cstring(name), p(edir), a(edir.len))}
 const fwstat	= {fd, edir;	-> syscall(Sysfwstat, a(fd), p(edir), a(edir.len))}
 const mount	= {fd, afd, old, flag, aname;	-> syscall(Sysmount, a(fd), a(afd), cstring(old), a(flag), cstring(aname))}
-const pread	= {fd, buf, off;	-> syscall(Syspread, a(fd), p(buf), a(buf.len), off) castto(size)}
-const pwrite	= {fd, buf, off;	-> syscall(Syspwrite, a(fd), p(buf), a(buf.len), s(off)) castto(size)}
+const pread	= {fd, buf, off;	-> (syscall(Syspread, a(fd), p(buf), a(buf.len), off) : size)}
+const pwrite	= {fd, buf, off;	-> (syscall(Syspwrite, a(fd), p(buf), a(buf.len), s(off)) : size)}
 const await	= {buf;	-> syscall(Sysawait, p(buf), a(buf.len))}
 const brk_	= {endp;	-> syscall(Sysbrk_, p(endp))}
-const nsec	= {;	-> syscall(Sys_nsec) castto(uint64)}
+const nsec	= {;	-> (syscall(Sys_nsec) : uint64)}
 const seek	= {fd, n, ty
 	var ret : off
 	syscall(Sysseek, a(&ret), a(fd), a(n), a(ty))
@@ -230,15 +230,15 @@
 
 	/* we need an array of C strings. */
 	p = alloca((args.len + 1)*sizeof(byte#))
-	cargs = (a(p) castto(byte##))[:args.len + 1]
+	cargs = (a(p) : byte##)[:args.len + 1]
 	for i = 0; i < args.len; i++
 		cargs[i] = cstring(args[i])
 	;;
-	cargs[args.len] = 0 castto(byte#)
+	cargs[args.len] = (0 : byte#)
 	-> syscall(Sysexec, cstring(bin), a(cargs))
 }
 
 /*const fversion	= {fd, bufsz, vers, nvers;	-> syscall(Sysfversion, fd, bufsz, }*/
-const semacquire	= {addr, block; -> syscall(Syssemacquire, a(addr), a(block)) castto(int)}
-const tsemacquire	= {addr, ms; -> syscall(Systsemacquire, a(addr), a(ms)) castto(int)}
-const semrelease	= {addr, count; -> syscall(Syssemrelease, a(addr), a(count)) castto(int32)}
+const semacquire	= {addr, block; -> (syscall(Syssemacquire, a(addr), a(block)) : int)}
+const tsemacquire	= {addr, ms; -> (syscall(Systsemacquire, a(addr), a(ms)) : int)}
+const semrelease	= {addr, count; -> (syscall(Syssemrelease, a(addr), a(count)) : int32)}
--- a/lib/thread/atomic.myr
+++ b/lib/thread/atomic.myr
@@ -16,20 +16,20 @@
 ;;
 
 impl atomic int32 =
-	xget	= {p; -> xget32(p castto(uint32#)) castto(int32)}
-	xset	= {p, v; xset32(p castto(uint32#), v castto(uint32))}
-	xadd	= {p, v; -> xadd32(p castto(uint32#), v castto(uint32)) castto(int32)}
-	xcas	= {p, old, new; -> xcas32(p castto(uint32#), old castto(uint32), new castto(uint32)) castto(int32)}
-	xchg	= {p, v; -> xchg32(p castto(uint32#), v castto(uint32)) castto(int32)}
+	xget	= {p; -> (xget32((p : uint32#)) : int32)}
+	xset	= {p, v; xset32((p : uint32#), (v : uint32))}
+	xadd	= {p, v; -> (xadd32((p : uint32#), (v : uint32)) : int32)}
+	xcas	= {p, old, new; -> (xcas32((p : uint32#), (old : uint32), (new : uint32)) : int32)}
+	xchg	= {p, v; -> (xchg32((p : uint32#), (v : uint32)) : int32)}
 ;;
 
 
 impl atomic int64 =
-	xget	= {p; -> xget64(p castto(uint64#)) castto(int64)}
-	xset	= {p, v; xset64(p castto(uint64#), v castto(uint64))}
-	xadd	= {p, v; -> xadd64(p castto(uint64#), v castto(uint64)) castto(int64)}
-	xcas	= {p, old, new; -> xcas64(p castto(uint64#), old castto(uint64), new castto(uint64)) castto(int64)}
-	xchg	= {p, v; -> xchg64(p castto(uint64#), v castto(uint64)) castto(int64)}
+	xget	= {p; -> (xget64((p : uint64#)) : int64)}
+	xset	= {p, v; xset64((p : uint64#), (v : uint64))}
+	xadd	= {p, v; -> (xadd64((p : uint64#), (v : uint64)) : int64)}
+	xcas	= {p, old, new; -> (xcas64((p : uint64#), (old : uint64), (new : uint64)) : int64)}
+	xchg	= {p, v; -> (xchg64((p : uint64#), (v : uint64)) : int64)}
 ;;
 
 impl atomic uint32 =
--- a/lib/thread/common.myr
+++ b/lib/thread/common.myr
@@ -1,5 +1,5 @@
 use std
 
 pkg thread = 
-	generic Zptr = 0 castto(@a#)
+	generic Zptr = (0 : @a#)
 ;;
--- a/lib/thread/condvar+freebsd.myr
+++ b/lib/thread/condvar+freebsd.myr
@@ -29,9 +29,9 @@
 	seq = cond._seq
 
 	mtxunlock(mtx)
-	sys.umtx_op(&cond._seq castto(void#), \
+	sys.umtx_op((&cond._seq : void#), \
 		sys.Umtxwaituintpriv, \
-		seq castto(uint64), \
+		(seq : uint64), \
 		Zptr, Zptr)
 
 	/*
@@ -40,9 +40,9 @@
 	unlocker of the mutex.
 	*/
 	while xchg(&mtx._state, Contended) != Unlocked
-		sys.umtx_op(&mtx._state castto(void#), \
+		sys.umtx_op((&mtx._state : void#), \
 			sys.Umtxwaituintpriv, \
-			Contended castto(uint64), \
+			(Contended : uint64), \
 			Zptr, Zptr)
 	;;
 }
@@ -49,11 +49,11 @@
 
 const condsignal = {cond : cond#
 	xadd(&cond._seq, 1)
-	sys.umtx_op(&cond._seq castto(void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
+	sys.umtx_op((&cond._seq : void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
 }
 
 const condbroadcast = {cond : cond#
 	xadd(&cond._seq, 1)
-	sys.umtx_op(&cond._seq castto(void#), sys.Umtxwakepriv, 0x7ffffff, Zptr, Zptr)
+	sys.umtx_op((&cond._seq : void#), sys.Umtxwakepriv, 0x7ffffff, Zptr, Zptr)
 }
 
--- a/lib/thread/condvar+linux.myr
+++ b/lib/thread/condvar+linux.myr
@@ -55,7 +55,7 @@
 	requeueing
 	*/
 	sys.futex(&cond._seq, sys.Futexcmprequeue | sys.Futexpriv, \
-		1, 0x7fffffff castto(sys.timespec#), \
+		1, (0x7fffffff : sys.timespec#), \
 		&cond._mtx._state, cond._seq)
 }
 
--- a/lib/thread/hookstd.myr
+++ b/lib/thread/hookstd.myr
@@ -13,11 +13,11 @@
 	netlck = mkmtx()
 	envlck = mkmtx()
 	std.__lockinit( \
-		&memlck castto(void#), \
-		&netlck castto(void#), \
-		&envlck castto(void#), \
-		{mtx; mtxlock(mtx castto(mutex#))}, \
-		{mtx; mtxunlock(mtx castto(mutex#))} \
+		(&memlck : void#), \
+		(&netlck : void#), \
+		(&envlck : void#), \
+		{mtx; mtxlock((mtx : mutex#))}, \
+		{mtx; mtxunlock((mtx : mutex#))} \
 	)
 }
 
--- a/lib/thread/mutex+freebsd.myr
+++ b/lib/thread/mutex+freebsd.myr
@@ -51,9 +51,9 @@
 
 	while c != Unlocked
 		sys.umtx_op( \
-			&mtx._state castto(void#), \
+			(&mtx._state : void#), \
 			sys.Umtxwaituintpriv, \
-			Contended castto(uint64), \
+			(Contended : uint64), \
 			Zptr, Zptr)
 		c = xchg(&mtx._state, Contended)
 	;;
@@ -76,6 +76,6 @@
 	;;
 
 	/* wake all threads: for some reason nwake */
-	sys.umtx_op(&mtx._state castto(void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
+	sys.umtx_op((&mtx._state : void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
 }
 
--- a/lib/thread/spawn+freebsd.myr
+++ b/lib/thread/spawn+freebsd.myr
@@ -25,46 +25,46 @@
 	;;
 	tid = -1
 	/* find top of stack */
-	tos = (stk castto(std.intptr)) + (sz castto(std.intptr))
+	tos = (stk : std.intptr) + (sz : std.intptr)
 
 	/* store the stack size */
 	tos -= sizeof(sys.size)
 	sz -= sizeof(sys.size)
-	szp = tos castto(sys.size#)
+	szp = (tos : sys.size#)
 	szp# = Stacksz
 
 	/* store the function we call */
 	tos -= sizeof((->void))
 	sz -= sizeof((->void))
-	fp = tos castto((->void)#)
+	fp = (tos : (->void)#)
 	fp# = fn
 
 	ret = sys.thr_new(&[
-		.startfn = startthread castto(void#),
-		.arg = tos castto(void#),
-		.stkbase = stk castto(byte#),
+		.startfn = (startthread : void#),
+		.arg = (tos : void#),
+		.stkbase = (stk : byte#),
 		.stksz = sz,
 		.tid = &ctid,
 		.ptid = &tid,
 		.flags = 2,
-		.rtp = 0 castto(sys.rtprio#)
+		.rtp = (0 : sys.rtprio#)
 	], sizeof(sys.thrparam))
 
 	if ret < 0
 		-> `std.Fail "couldn't spawn thread"
 	;;
-	-> `std.Ok tid castto(tid)
+	-> `std.Ok (tid : tid)
 }
 
 const getstk = {sz
 	var p, m
 
-	p = sys.mmap(0 castto(byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+	p = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
 	if p == sys.Mapbad
 		-> p
 	;;
-	m = p castto(std.intptr)
-	-> m castto(byte#)
+	m = (p : std.intptr)
+	-> (m : byte#)
 }
 
 const startthread = {fn : (-> void)#
--- a/lib/thread/spawn+linux.myr
+++ b/lib/thread/spawn+linux.myr
@@ -28,36 +28,36 @@
 	if stk == sys.Mapbad
 		-> `std.Fail "couldn't get stack"
 	;;
-	tos = stk castto(std.intptr)
+	tos = (stk : std.intptr)
 	tos -= sizeof(int64)
-	szp = tos castto(sys.size#)
+	szp = (tos : sys.size#)
 	szp# = Stacksz
 	tos -= sizeof((->void))
-	fp = tos castto((->void)#)
+	fp = (tos : (->void)#)
 	fp# = fn
 
 	ret = sys.fnclone(Thrflag, \
-		tos castto(byte#),\
-		&tid, 0 castto(byte#), \
-		&ctid, 0 castto(byte#), \
-		startthread castto(void#)) castto(tid)
+		(tos : byte#),\
+		&tid, (0 : byte#), \
+		&ctid, (0 : byte#), \
+		(startthread : void#))
 	if ret < 0
 		-> `std.Fail "couldn't spawn thread"
 	;;
-	-> `std.Ok ret
+	-> `std.Ok (ret : tid)
 }
 
 const getstk = {sz
 	var p, m
 
-	p = sys.mmap(0 castto(byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+	p = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
 	if p == sys.Mapbad
 		-> p
 	;;
 	/* stack starts at the top of memory and grows down. */
-	m = p castto(std.intptr)
-	m += sz castto(std.intptr)
-	-> m castto(byte#)
+	m = (p : std.intptr)
+	m += (sz : std.intptr)
+	-> (m : byte#)
 }
 
 const startthread = {fn : (-> void)
--- a/lib/thread/spawn+openbsd.myr
+++ b/lib/thread/spawn+openbsd.myr
@@ -23,38 +23,41 @@
 		-> `std.Fail "couldn't get stack"
 	;;
 	/* store size */
-	tos = stk castto(std.intptr)
+	tos = (stk : std.intptr)
 	tos -= sizeof(int64)
-	szp = tos castto(sys.size#)
+	szp = (tos : sys.size#)
 	szp# = Stacksz
 
 	/* store func */
 	tos -= sizeof((->void))
-	fp = tos castto((->void)#)
+	fp = (tos : (->void)#)
 	fp# = fn
 
 	tfp = [
-		.tcb = 0 castto(void#),
+		.tcb = (0 : void#),
 		.tid = &ret,
-		.stk = tos castto(byte#),
+		.stk = (tos : byte#),
 	]
-	if sys.__tfork_thread(&tfp, sizeof(sys.tforkparams), startthread castto(void#), 0 castto(void#))  < 0
+	if sys.__tfork_thread(&tfp, \
+		sizeof(sys.tforkparams), \
+		(startthread : void#), \
+		(0 : void#))  < 0
 		-> `std.Fail "couldn't spawn thread"
 	;;
-	-> `std.Ok (ret castto(tid))
+	-> `std.Ok (ret : tid)
 }
 
 const getstk = {sz
 	var p, m
 
-	p = sys.mmap(0 castto(byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+	p = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
 	if p == sys.Mapbad
 		-> p
 	;;
 	/* stack starts at the top of memory and grows down. */
-	m = p castto(std.intptr)
-	m += sz castto(std.intptr)
-	-> m castto(byte#)
+	m = (p : std.intptr)
+	m += (sz : std.intptr)
+	-> (m : byte#)
 }
 
 const startthread = {fn : (-> void)
--- a/lib/thread/spawn+osx.myr
+++ b/lib/thread/spawn+osx.myr
@@ -16,12 +16,12 @@
 	var ret
 
 	ret = sys.bsdthread_register(\
-		start castto(void#), \	/* start */
-		0 castto(void#), \	/* wqthread */
-		0 castto(uint32), \	/* sz */
-		0 castto(uint32), \	/* dummy */
-		0 castto(void#), \	/* targconc */
-		0 castto(uint32))	/* queueoff */
+		(start	: void#), \	/* start */
+		(0	: void#), \	/* wqthread */
+		(0	: uint32), \	/* sz */
+		(0	: uint32), \	/* dummy */
+		(0	: void#), \	/* targconc */
+		(0	: uint32))	/* queueoff */
 	if ret < 0
 		std.fatal("unable to init threads: {}", ret)
 	;;
@@ -37,24 +37,24 @@
 	var tid : tid, ret
 
 
-	std.put("...hi? fn={}\n", fn castto(void#))
+	std.put("...hi? fn={}\n", (fn : void#))
 	ret = sys.bsdthread_create( \
-		fn castto(void#), \
+		(fn	: void#), \
 		envptr(&fn), \
-		sz castto(void#), \
-		0 castto(void#), \
+		(sz	: void#), \
+		(0	: void#), \
 		0)
 
-	if ret == (-1 castto(void#))
+	if ret == (-1 : void#)
 		-> `std.Fail "couldn't spawn thread"
 	;;
-	-> `std.Ok ret castto(tid)
+	-> `std.Ok (ret : tid)
 }
 
 const envptr = {fn
 	var repr : std.intptr[2]
 
-	repr = (fn castto(std.intptr[2]#))#
-	-> repr[0] castto(void#)
+	repr = (fn : std.intptr[2]#)#
+	-> (repr[0] : void#)
 }
 
--- a/lib/thread/spawn+plan9.myr
+++ b/lib/thread/spawn+plan9.myr
@@ -13,6 +13,6 @@
 		fn()
 		std.exit(0)
 	| -1:	-> `std.Fail "unable to spawn thread"
-	| thr:	-> `std.Ok thr castto(tid)
+	| thr:	-> `std.Ok (thr : tid)
 	;;
-}
\ No newline at end of file
+}
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -146,8 +146,8 @@
 %type <node> funclit seqlit tuplit name block stmt label use
 %type <node> fnparam declbody declcore typedeclcore structent arrayelt structelt tuphead
 %type <node> ifstmt forstmt whilestmt matchstmt elifs optexprln loopcond optexpr
-%type <node> match
 %type <node> castexpr
+%type <node> match
 %type <ucon> unionelt
 %type <node> blkbody
 %type <node> implstmt
@@ -644,7 +644,7 @@
 	| cmpexpr
 	;
 
-cmpexpr : cmpexpr cmpop castexpr
+cmpexpr : cmpexpr cmpop unionexpr
 	{$$ = mkexpr($1->loc, binop($2->type), $1, $3, NULL);}
 	| unionexpr
 	;
@@ -658,6 +658,7 @@
 	;
 
 castexpr: castexpr Tcast Toparen type Tcparen {
+		fprintf(stdout, "%s:%d: deprecated cast syntax being removed\n", fname($2->loc), lnum($2->loc));
 		$$ = mkexpr($1->loc, Ocast, $1, NULL);
 		$$->expr.type = $4;
 	}
@@ -745,6 +746,10 @@
 	| literal
 	| Toparen expr Tcparen
 	{$$ = $2;}
+	| Toparen expr Tcolon type Tcparen {
+		$$ = mkexpr($1->loc, Ocast, $2, NULL);
+		$$->expr.type = $4;
+	}
 	| Tsizeof Toparen type Tcparen
 	{$$ = mkexpr($1->loc, Osize, mkpseudodecl($1->loc, $3), NULL);}
 	;
--- a/test/basicfloat.myr
+++ b/test/basicfloat.myr
@@ -6,5 +6,5 @@
 
 /* basic sanity check on floating point operations. should return 84. */
 const main = {
-	std.exit((42.0 + get42()) castto(int))
+	std.exit((42.0 + get42() : int))
 }
--- a/test/bigliteral.myr
+++ b/test/bigliteral.myr
@@ -1,5 +1,5 @@
 use std
 
 const main = {
-	std.put("{}\n", 34359738368 castto(int64))
+	std.put("{}\n", (34359738368 : int64))
 }
--- a/test/doublecall.myr
+++ b/test/doublecall.myr
@@ -9,5 +9,5 @@
 }
 
 const b = {
-	-> 33 castto(int16)
+	-> (33 : int16)
 }
--- a/test/fncast.myr
+++ b/test/fncast.myr
@@ -9,8 +9,8 @@
 	envfn = {
 		ptr = ptr
 	}
-	ptr = fn castto(byte#)
-	ptr = envfn castto(byte#)
+	ptr = (fn : byte#)
+	ptr = (envfn : byte#)
 	std.put("ok\n")
 }
 
--- a/test/log-and.myr
+++ b/test/log-and.myr
@@ -1,5 +1,5 @@
 use std
 /* checks that evaluating a logical and to a bool works. should return 0. */
 const main = {
-	std.exit((0 && 1) castto(int))
+	std.exit((0 && 1 : int))
 }
--- a/test/log-or.myr
+++ b/test/log-or.myr
@@ -1,5 +1,5 @@
 use std
 /* checks that evaluating a logical or works. exits with 1. */
 const main = {
-	std.exit((0 || 1) castto(int))
+	std.exit((0 || 1 : int))
 }
--- a/test/mul8.myr
+++ b/test/mul8.myr
@@ -5,5 +5,5 @@
 	-> 3
 }
 const main = {
-	std.exit(((a*f()) castto(int)))
+	std.exit(((a*f() : int)))
 }
--- a/test/sqrt.myr
+++ b/test/sqrt.myr
@@ -28,6 +28,9 @@
 }
 
 const main = {
-	std.exit(sqrt(20.0) castto(int))
+	var r
+
+	r = (sqrt(20.0) : int)
+	std.exit(r)
 }
 
--- a/test/str.myr
+++ b/test/str.myr
@@ -5,5 +5,5 @@
 	var str
 
 	str = "asdf"
-	std.exit(str[3] castto(int))
+	std.exit((str[3] : int))
 }
--- a/test/swidencast.myr
+++ b/test/swidencast.myr
@@ -5,6 +5,6 @@
 	var v : int32
 	
 	u = 99
-	v = u castto(int32)
-	std.exit(v castto(int))
+	v = (u : int32)
+	std.exit((v : int))
 }
--- a/test/traitimpl.myr
+++ b/test/traitimpl.myr
@@ -29,7 +29,7 @@
 const main = {
 	var a, b, c
 	a = foo(123)
-	b = foo(11 castto(int16))
+	b = foo((11 : int16))
 	c = frob("meeeeeeh")
 	std.put("{},{},{}\n", a, b, c)
 }
--- a/test/trunccast.myr
+++ b/test/trunccast.myr
@@ -5,6 +5,6 @@
 	var y : int32
 
 	y = 9999
-	x = y castto(uint8)
-	std.exit((x % 73) castto(int))
+	x = (y : uint8)
+	std.exit((x % 73 : int))
 }
--- a/test/zwidencast.myr
+++ b/test/zwidencast.myr
@@ -5,6 +5,6 @@
 	var v : uint32
 	
 	u = 99
-	v = u castto(uint32)
-	std.exit(v castto(int))
+	v = (u : uint32)
+	std.exit((v : int))
 }