Types and shapes
Venutian's eight types, value versus reference semantics, and shape, the language's one way to declare a record type.
Venutian has eight types, in full: Integer, Number, Text, Truth, Nothing, List, Function, and one type per shape you declare. There is no Dictionary, no Tuple, no Set, no file object type, and no separate boolean subtype the way some languages check bool before int under the hood: kind(yes) always reads "Truth".
Value types and reference types
Every core type is either a value type, copied rather than shared, or a reference type, shared and mutated in place:
- Value types:
Integer,Number,Text,Truth,Nothing. - Reference types:
List, and everyshapeinstance.
a = [1, 2, 3]
b = a :: b is bound to the same List, not a copy
b[0] = 99
print a :: [99, 2, 3], a changed too
print b :: [99, 2, 3]
Reassigning a itself never mutates anything a List shares: a = [7] afterward just rebinds the name a, leaving whatever b still points at untouched. == is Venutian's only comparison operator, and for a List or a shape instance it compares structurally, field by field, not by identity.
Numbers
Integer and Number are the two numeric types. An Integer literal is plain digits (12); a Number literal is digits, a dot, and digits (3.14). There is no hex, octal or binary literal prefix, no underscore digit grouping, no exponent notation, and no .5 or 10. shorthand.
print 2 + 3 * 4 :: 14, ordinary precedence, no exponent operator
print power(2, 10) :: 1024, exponentiation is a builtin
print 7 / 2 :: 3.5, '/' always produces a Number
shape: Venutian's record type
shape declares a record type: fields only, with no attached methods. A shape's fields are typed, and an instance is built by calling the shape name like a function:
:: 'shape' declares a record type.
shape Person
name: Text
age: Integer
ada = Person("Ada Lovelace", 36)
print ada.name
print ada.age
print ada
Ada Lovelace
36
Person(name: "Ada Lovelace", age: 36)
A shape instance is a reference type: assigning it shares the same instance, and a field assignment mutates it in place, visible through every name bound to it.
same_person = ada
ada.age = 37
print same_person.age
37
Two shape instances compare equal when every field does, not by identity:
print Person("Ada", 36) == Person("Ada", 36)
print kind(ada)
yes
Person
Inheritance
A shape can inherit another shape's fields with inherits, and a typed pattern that names the parent shape matches an instance of any shape that inherits it, the same way a typed rescue does (see errors):
shape Animal
name: Text
shape Dog inherits Animal
breed: Text
shape Cat inherits Animal
indoor: Truth
make describe(value)
choose value
is d: Dog
print d.name, "is a Dog (breed", d.breed + ")"
is c: Cat
print c.name, "is a Cat (indoor:", as_text(c.indoor) + ")"
is a: Animal
print a.name, "is some other kind of Animal"
is : Text
print "just plain Text, not an Animal at all"
otherwise
print "no idea what that is"
describe(Dog("Rex", "Labrador"))
describe(Cat("Whiskers", yes))
Rex is a Dog (breed Labrador)
Whiskers is a Cat (indoor: yes)
choose's is name: Type pattern binds the matched value under name at that type; is : Type matches without binding a name at all. Patterns are tried in order, and the first one that matches wins, so a more specific shape like Dog is listed before its parent Animal.
See errors for how the same typed matching works in a rescue clause, and modules for using a shape declared in another file.