We are all familiar with python and nodejs assertions:
// nodejs
assert(1+1 === 2)
// true but on failure throws AssertionError
# python
assert 1+1 == 2
# same as above
This idea expands upon the above concept and looks at assertions in extra detail along with a cooler syntax😉
warning
A lot of unstable terrain ahead! proceed with caution.
Value Assertions
These are the normal assertions that we are all familiar from node and python.
1 + 1 :: 2 // true
"ecmascript" :: "javascript" // AssertionError
"string" :: typeof "hi" // true
The last example is particularly interesting.
notice that a value assertion cannot begin with a typeof operator; because that's a whole other kind of assertion👇
Type Assertions
These provide a way for type verification.
Notice however they follow a particular syntax and remember that they are not meant to provide solid static typing.
let x = "JavaScript"
typeof x :: String
let y = String
typeof y :: Object
let z = [1, 2, 3, 4, 5, 6, 7]
typeof z :: [Array(7) Number]
let a = {
foo: "bar",
[Symbol("sim")]: 100
}
typeof a :: Object
// or [Object { String: String, Symbol: Number }]
// irrespective of order
typeof null :: null // I don't know, maybe it should be [Object null]
typeof undefined :: undefined
// some other exotic Objects
let b = new Set(1, 2, 3, 4, 5, 6, 7)
typeof b :: [Set(7) Number]
let c = new Map([ [0, 1], [2, 3], [4, 5], [6, 7] ])
typeof b :: [Map {Number : Number}]
// or [Map Number] -- typeof keys only
// or [Map {:Number} ] -- typeof values only
// or [Map {Number} ] -- typeof keys and values
// Functions
typeof greet :: [Function AsyncFunction]
async function greet(word) {
typeof word :: String
const greetings = word + " world!"
typeof greetings :: String
return greetings
}
// generators
typeof speak :: [Function AsyncGenerator]
// if it's simply a generator then [Function Generator]
async function *speak(firstWord) {
typeof firstWord :: String
yield firstWord
const word2 = "Buzz"
typeof word2 :: String
yield word2
const word3 = "Zap"
typeof word3 :: String
yield word3
const lastWord = "Bye"
typeof lastWord :: String
return lastWord
}
class Animate {
x2 = 0
y2 = 0
constructor(x, y) {
this.x1 = x
this.y1 = y
typeof this.x1 :: Number
typeof this.y1 :: Number
typeof this.x2 :: Number
typeof this.y2 :: Number
typeof this.moveTo :: Function
// this is trivial any away
}
moveTo(x2, y2) {
typeof x2 :: Number
typeof y2 :: Number
// do something
typeof [x2, y2] :: [Array Number]
return [x2, y2]
}
}
typeof Animate :: [Function Object]
We can take this further and create algebraic types
let str = "I'm a String"
typeof str :: String | Number
let sym = Symbol("I'm Invincible")
typeof sym :: !String
// sym can be anything except a String
typeof sym :: !(String | Number)
// means that sym can be anything except a String and a Number
The real power of algebraic types can be seen from Arrays and other collection types.
typeof [1, "hi", 3, true] :: [Array Number | String | Boolean]
typeof new Map([ ["a", "apple"], [0, false] ]) :: [Map {Number | String: Number | Boolean}]
Instance Assertions
These assertions are for instance checking
instanceof Error :: TypeError // true
instanceof Human :: Person | Mammal // true
instanceof Insect :: Dodo // AssertionError
I personally think they are cool and would make JavaScript even cooler!
What's your take on this idea??
This is a lengthy idea, so there might be some errors, misunderstandings and syntax ambiguities along the way! please care to mention them and help refine this idea!