// an example in Java
int[] array = new int[]{1, 2, 3};
Lense recognizes literals for `Sequence`s, `Association`s and `Tuple`s. As a rule, because it must be possible to infer the type of literal from the syntax, we need a diferent sintax for each container type.
In C-familly languages an array is a fundamental type and can be created literally using curly brackets { and }, but in more mathematical oriented languages such as Fortran an Julia common brackets are used.
// an example in Java
int[] array = new int[]{1, 2, 3};
On a closer look we can understand the C-family languages syntax like Java or C# as not having array literals per se, but initializers applied to arrays. So the syntax {1 ,2 , 3}
does not denote an array, but an initializer. Initializers do not have type and they are intrinsically understood by the compiler.
What’s happening in that java code is that an array is being constructed with new int[]
and then initialized with the values 1, 2 and 3. The JVM will translate this two operations as a single operation, but
conceptually there is a difference.
In C# the same concept is used to initialize both arrays and lists
int[] array = new int[]{1, 2, 3};
List<int> list = new List(){1, 2, 3};
In Lense the type of the container is fixed by the syntax and a conversion constructor is used to copy the values to another type if need be. So no constructor is called. A runtime object is created that depends on the underlying platform. The type inside the container is inferred from the declared value types.
Lense uses common brackets to represent Sequence
literals. Keep in mind arrays are not fundamental types in Lense, sequences are.An array is a special (mutable) sub type of sequence.
(as always types are shown for clarity, they are optional)
let sequence : Sequence<Natural> = [1, 2, 3];
let array : Array<Natural> = [1, 2, 3];
The first line creates a sequence of elements 1, 2 and 3. The second line creates an array of the elements 1, 2 and 3 by first creating a sequence and them promoting
it to an Array
by calling its conversion constructor. In practice the compiler is free to optimize these literal constructions
and not really call the conversion constructor on Array<T>
.
Currently there is no special syntax for sets. A set can be created by using a literal sequence and a constructor.
let sequence : Set<Natural> = new HashSet([1, 2, 2, 3, 4, 3]);
Or, you can use the toSet
method in Sequence
:
let sequence : Set<Natural> = [1, 2, 2, 3, 4, 3].toSet();
The set will only contain the elements 1, 2, 3 and 4 once.
Associations are used to maintain pairs of values related to each other. Normally in a key to value relationship.
let association : Association<Natural,String> = { 1 -> "First", 2 -> "Second", 3 -> "Third" };
let map : Map<Natural, String> = { 1 -> "First", 2 -> "Second", 3 -> "Third" };
Like Sequence
, Association
is a fundamental type in Lense, so it has its own literal type.
The first line creates an association of elements. The second line creates a map of the same elements by first creating an association and them promoting it to a Map. In Lense, Map
is a specific (mutable) implementation of Association
and not an interface like in Java. Is equivalent to HashMap
in Java.
Tuples are similar to sequences, but each index has its own type. Tuples also are fundamental types in Lense.
Structurally a Tuple is a node in a linked-list kind of structure. But Tuples are not Sequences, eventhought they are Iterable<Any>
The syntax is similar to Sequences.
let tuple : Tuple<Natural , Tuple<String, Tuple< Boolean, Nothing >>> = ( 1 , "2" , true );
let association : (Natural , String , Boolean) = ( 1 : "2" : true );
The first line creates a tuple of elements. The second line creates the same tuple but uses the tuple short type syntax for representing tuple types. The default form used in the first line can be very long and odd to write and read eventhought is the exact correct type of that tuple.
It could be possible to define a specific syntax for a two dimensional`Matrix`. This is not currently implemented.
let matrix : Matrix<Natural> = [ 1 ,2 ,3 ; 4, 5, 6 ; 5 6 7];
// also can be written as
let matrix : Matrix<Natural> = [
1 ,2 ,3 ;
4, 5, 6 ;
5, 6, 7
];
This would make a lot of sense in order to facilitate using Lense in more math and/or science scenarios. An alternative is to write sequence of sequences literals an use conversion constructors :
let matrix : Matrix<Natural> = [ [1 ,2 ,3 ], [4, 5, 6 ], [ 5 6 7]];
// also can be written as
let matrix : Matrix<Natural> = [
[1 ,2 ,3],
[4, 5, 6],
[5, 6, 7]
];
The support for matrixes is still under consideration and may not be implemented.
Records are a special object that represents a non typed property bag. Records are not currently implemented. A possible syntax would be similar to an association, but using = instead of ":". The difference is that on an association both sides of the ":" can be variables, in a record only the right side can be a variable. The left side is interpreted as the name of a property.
let address : Record = {
Street = "Baker Street",
Number = "221B",
City = "Lodon",
Country = "England"
}
This syntax takes us full circle to the initializer concept discussed at the beginning. We can now use records to initialize other types like so:
let address : Address = new Address {
Street = "Baker Street",
Number = "221B",
City = "London",
Country = "England"
}
This a combination of a call to the primary constructor and a initialization of each property referred in the record literal. This is not a conversion but syntax sugar for:
// define a record
let tempRecord : Record = {
Street = "Baker Street",
Number = "221B",
City = "London",
Country = "England"
}
// copy properties with the same name
let address : Address = new Address();
address.Street = tempRecord.Street;
address.Number = tempRecord.Number;
address.City = tempRecord.City;
address.Country = tempRecord.Country;
That is optimized to:
let address : Address = new Address();
address.Street = "Baker Street";
address.Number = "221B";
address.City = "London";
address.Country = "England";
This feature is similar to the initialization syntax in C# even thought in Lense we would be using the conjunction of two concepts : constructors and record literals.