Operators & Symbols

This section contains all of the syntactic operators that are available within Hash

General operators 🚧

Here are the general operators for arithmetic, bitwise assignment operators. This table does not include all of the possible operators specified within the grammar. There are more operators that are related to a specific group of operations or are used to convey meaning within the language.

OperatorExampleDescriptionOverloadable trait
==, !=a == 2, b != 'a'Equalityeq
=a = 2AssignmentN/A
!!aLogical notnot
&&a && bLogical andand
||a || bLogical oror
+2 + 2, 3 + bAdditionadd
-3 - aSubtractionsub
--2Negationneg
*3 * 2, 2 * cMultiplicationmul
^^3 ^^ 2, 3 ^^ 2.3Exponentiationexp
/4 / 2, a / bDivisiondiv
%a % 1Modulomod
<<4 << 1Bitwise left shiftshl
>>8 >> 1Bitwise right shiftshr
&5 & 4, a & 2Bitwise andandb
|a | 2Bitwise ororb
^3 ^ 2Bitwise exclusive orxorb
~~2Bitwise notnotb
>=, <=, <, >2 < b, c >= 3Order comparisonord
+=x += yAdd with assignmentadd_eq
-=x -= 1Subtract with assignmentsub_eq
*=b *= 10Multiply with assignmentmul_eq
/=b /= 2Divide with assignmentdiv_eq
%=a %= 3Modulo with assignmentmod_eq
&&=b &&= cLogical and with assignmentand_eq
>>=b >>= 3Bitwise right shift equalityshr_eq
<<=b <<= 1Bitwise left shift equalityshl_eq
||=b ||= cLogical or with assignmentor_eq
&=a &= bBitwise and with assignmentandb
|=b |= SOME_CONSTBitwise or with assignmentorb
^=a ^= 1Bitwise xor with assignmentxorb
.a.fooStruct/Tuple enum property accessorN/A
:{2: 'a'}Map key-value separatorN/A
::io::open()Namespace symbol accessN/A
ast as strType assertionN/A
@N/APattern value bindingN/A
...N/ASpread operator (Not-implemented)range?
;expression;statement terminatorN/A
?k<T> where s<T, ?> := ...Type argument wildcardN/A
->(str) -> usizeFunction return type notationN/A
=>(a) => a + 2Function Body definitionN/A

Comments 🚧

This table represents the syntax for different types of comments in Hash:

SymbolDescription
//...Line comment
/*...*/Block comment
///function doc comment 🚧
//!module doc comment 🚧

Type Signature Assertions

Basics

As in many other languages, the programmer can specify the type of a variable or a literal by using some special syntax. For example, in languages such as typescript, you can say that:

#![allow(unused)]
fn main() {
some_value as str
}

which implies that you are asserting that some_value is a string, this is essentially a way to avoid explicitly stating that type of a variable every single time and telling the compiler "Trust me some_value is a string".

The principle is somewhat similar in Hash, but it is more strictly enforced. For example, within the statement x := 37;, the type of x can be any of the integer types. This might lead to unexpected behaviour in future statements, where the compiler has decided the type of x (it might not be what you intended it).

So, you can either declare x to be some integer type explicitly like so:

x: u32 = 37;

Or you can, use as to imply a type for a variable, which the compiler will assume to be true, like so:

x := 37 as u32;

Failing type assertions

If you specify a type assertion, the compiler will either attempt to infer this information from the left-hand side of the as operator to the right. If the inference results in a different type to the right-hand side, this will raise a typechecking failure.

For example, if you were to specify the expression:

#![allow(unused)]
fn main() {
"A" as char
}

The compiler will report this error as:

error[0001]: Types mismatch, got a `str`, but wanted a `char`.
 --> <interactive>:1:8
1 |   "A" as char
  |          ^^^^ This specifies that the expression should be of type `char`

 --> <interactive>:1:1
1 |   "A" as char
  |   ^^^ Found this to be of type `str`

Usefulness

Why are type assertions when there is already type inference within the language? Well, sometimes the type inference system does not have enough information to infer the types of variables and declarations. Type inference may not have enough information when dealing with functions that are generic, so it can sometimes be useful to assert to the compiler that a given variable is a certain type.

Additionally, whilst the language is in an early stage of maturity and some things that are quirky or broken, type assertions can come to the rescue and help the compiler to understand your program.

In general, type assertions should be used when the compiler cannot infer the type of some expression with the given information and needs assistance. You shouldn't need to use type assertions often.