Skip to main content
Version: 0.1

Standard library and built-ins

G# deliberately keeps its language-defined library small. Primitive types, collection intrinsics, channels, function values, and a few legacy built-in functions are provided by the compiler and evaluator. Most everyday library APIs are the .NET Base Class Library reached through imports and CLR interop; for example, printing in samples normally uses Console.WriteLine from the implicit or explicit System import. See CLR interop for constructors, members, delegates, events, generics, attributes, and other .NET surface.

Primitive types

The built-in primitive type symbols are exactly:

CategoryTypesNotes
BooleanboolLiterals are true and false.
Unsigned integersuint8, uint16, uint32, uint64, nuintWidth-bearing names are canonical. Older aliases such as uint and byte are not built-in primitive names.
Signed integersint8, int16, int32, int64, nintUnsuffixed integer literals default to int32. Older aliases such as int and long are not built-in primitive names.
Floating point and decimalfloat32, float64, decimalUnsuffixed float literals default to float64; suffixes include F, D, and M.
Textchar, stringchar is one UTF-16 code unit; string is the CLR string type.
Top and no-valueobject, voidobject is the universal upper bound; void is the no-result type.
Absencenilnil is a special literal type that converts to nullable types, not a named runtime type.

object accepts implicit boxing from G# values backed by CLR types and from user value types. Explicit unboxing is available for CLR value types. nil converts to T?, and postfix !! asserts a nullable value is present.

Operators on built-in types

G# does not perform cross-type operator promotion. Binary operators are defined for same-typed primitive operands unless otherwise noted.

  • bool: !, &, &&, |, ||, ^, ==, !=.
  • Signed integers: unary +, unary -, ^; binary +, -, *, /, %, &, |, ^, &^, <<, >>, ==, !=, <, <=, >, >=.
  • Unsigned integers: unary +, ^; binary +, -, *, /, %, &, |, ^, &^, <<, >>, ==, !=, <, <=, >, >=.
  • float32, float64, decimal: unary +, unary -; binary +, -, *, /, %, ==, !=, <, <=, >, >=.
  • char: unary +; binary ==, !=, <, <=, >, >=.
  • string: +, ==, !=.
  • object: ==, !=.

Shift counts are int32. Compound assignments exist for the corresponding binary operators: +=, -=, *=, /=, %=, &=, |=, ^=, &^=, <<=, and >>=.

Intrinsic functions and operations

These names are recognized specially by the binder. They are language intrinsics, not methods imported from the BCL.

IntrinsicFormSupported operandsResult
lenlen(x)arrays, slices, strings, mapsint32 length/count
capcap(x)arrays, slicesint32 capacity
appendappend(slice, value)first argument must be []T; second converts to Tnew []T containing the appended value
deletedelete(map, key)first argument must be map[K]V; key converts to Kno value; removes the key if present
closeclose(ch)chan Tno value; completes the channel writer
makemake(chan T) or make(chan T, capacity)channel creation onlychan T
receive<-chchan Tnext T value, or the closed-channel default value
sendch <- valueleft side chan T; value converts to Tstatement

make is currently special-cased only for channel creation; it is not a general allocator for slices or maps.

let ch = make(chan int32, 3)
ch <- 1
close(ch)
let value = <-ch

Arrays and slices

Fixed arrays use [N]T; slices use []T. Literals use the same shape with an initializer body. Slices are backed by CLR arrays in the current implementation; append allocates and copies a new array.

var nums = []int32{10, 20, 30}
Console.WriteLine(len(nums))
Console.WriteLine(cap(nums))
nums = append(nums, 40)
Console.WriteLine(nums[3])

Arrays and slices support indexing, index assignment when mutable, len, and cap. for i := 0 ... len(nums) is the common indexed loop form; for x in nums and for x := range nums are also supported by the language.

Maps

Map types are written map[K]V and are backed by Dictionary<K,V>. Map literals use key/value entries, indexing reads values, index assignment writes values, delete removes a key, and len returns the current count.

var counts = map[string]int32{"gsharp": 1}
counts["gsharp"] = counts["gsharp"] + 1
delete(counts, "missing")
Console.WriteLine(len(counts))

The .NET Dictionary[K,V] type is also usable through CLR interop when you import System.Collections.Generic; that surface is the BCL, not the language-defined map intrinsic.

Sequences and iteration

sequence[T] is the G# type-clause spelling for IEnumerable[T]. Iterator functions that return a sequence can use yield expr. async sequence[T] is the spelling for IAsyncEnumerable[T], and await for iterates async streams. Sequence APIs beyond iteration come from the BCL, such as LINQ extension methods imported from System.Linq.

Functions, delegates, and closures

Function values use func(P1, P2) R type clauses and function literals. Compatible function literals and method groups can convert to CLR delegate types during interop. Delegate construction and invocation are documented in CLR interop.

Console and legacy built-in functions

The curated documentation prefers .NET console APIs:

import System

Console.WriteLine("hello")

The compiler also contains legacy built-in functions print(text string), input() string, and rnd(max int32) int32. They are implemented by the evaluator as console/random helpers and are not the shape used by current reference samples.