You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: docs/tut/beginnerIntoToSparrow.rst
+12-33
Original file line number
Diff line number
Diff line change
@@ -64,7 +64,7 @@ An important concept of imperative programming languages is the variable. A vari
64
64
var m: Int = 15
65
65
var f: Float = 0.3
66
66
var greet = "Hello, world!"
67
-
var k: Long
67
+
var k: Int64
68
68
var p1, p2, p3: String
69
69
70
70
When declaring a variable one needs to supply the name of the new variable (or variables), an optional type, and an optional initial value. It is not possible to have a variable definition that lacks both the type and the initial value. If the variable receives an initial value without a type, the type of the value will be taken from the initializer. If the variable does not have an initial value, the variable will be *default constructed* (more precisely, the default constructor will be called for the variable); this assures that the variable is initialized.
@@ -104,36 +104,15 @@ Basic types
104
104
105
105
In Sparrow, any value, variable, or expression needs to have a well defined type. A type determines the way a value can be encoded in the system's memory and what operations are valid for that variable.
106
106
107
-
The standard library defines a series of integer types: ``Byte``, ``UByte``, ``Short``, ``UShort``, ``Int``, ``UInt``, ``Long`` and ``ULong`` of sizes 8, 16, 32 and 64 bits, signed and unsigned. Two additional integer types are defined to contain at least as many bits as a pointer: ``SizeType`` and ``DiffType``; the first one is unsigned and the second one is a signed type. To represent floating point numbers, the language defines the types ``Float`` (32 bits) and ``Double`` (64 bits).
107
+
The standard library defines ``Int`` as the main type to be used for storing signed integers; it has 32 bits. For better control, it also defines ``Int8``, ``UInt8``, ``Int16``, ``UInt16``, ``Int32``, ``UInt32``, ``Int64``, ``UInt64``; as their name implies, these cover both signed and unsigned, of sizez 8, 16, 32 and 64 bit. ``Int`` and ``Int32`` are aliases.
108
+
109
+
To represent floating point numbers, the language defines the type ``Float``; this is 64 bit. For better control, the language also defines ``Float32`` and ``Float64``. In this case too, ``Float`` is an alias to ``Float64``.
108
110
109
111
To represent booleans the language defines the ``Bool`` type. To represent characters we have the ``Char`` type. In Sparrow, strings use UTF-8 encoding, so setting the ``Char`` to 8 bits is an obvious choice.
110
112
111
113
In the most basic form, strings can be represented as a ``StringRef`` type. This just refers to the string, but does not hold ownership of the string data. To use a string with ownership of data, one can use the ``String`` type. String literals have the type ``StringRef``, but there is an implicit conversion between a ``StringRef`` and ``String``.
112
114
113
-
Certain implicit conversions (called *type coercions*) can be made between these types. An integer type can always be converted into an integer type of a larger size. An unsigned type can be converted into a signed type of the same size, and vice-versa. Any integer type can be implicitly converted into a floating point type.
114
-
115
-
Here are some implicit conversion examples:
116
-
117
-
::
118
-
119
-
var b: Byte = 1
120
-
var ub: UByte = 2
121
-
var i: Int = 3
122
-
var ui: UInt = 4
123
-
var l: Long = 5
124
-
var f: Float = 3.14f
125
-
var d: Double = 3.14159265359
126
-
127
-
i = b // OK: Byte -> Int
128
-
i = ub // OK: UByte -> Int
129
-
ui = i // OK: Int -> UInt
130
-
i = ui // OK: UInt -> Int
131
-
// b = i // ERROR: cannot convert wider to narrower type
132
-
f = l // OK: Long -> Float
133
-
d = b // OK: Byte -> Double
134
-
135
-
136
-
Note that some of these conversions can loose precision (e.g., large integers to floating points), and sometimes can even dramatically change the actual value (negative number to unsigned or large number to signed). The user must be careful when performing such conversions. As the benefits provided by these conversions are typically more significant than the drawbacks, they are allowed.
115
+
Sparrow does not allow implicit conversion (called *type coercions*) between numeric types. However, explicit conversions can be made between any numeric types. With the assumption that most of the times ``Int`` will be used for integers and ``Float`` for floating-points, having implicit conversions has more downsides than positives.
137
116
138
117
References
139
118
----------
@@ -291,7 +270,7 @@ So far, we have shown function definitions that operate on concrete data types.
291
270
fun sum(x, y: Numeric) = x+y;
292
271
293
272
294
-
The ``Numeric`` name refers to a *concept* defined in the standard library that accepts any numeric type (e.g., ``Int``, ``ULong``, ``Double``).
273
+
The ``Numeric`` name refers to a *concept* defined in the standard library that accepts any numeric type (e.g., ``Int``, ``UInt64``, ``Float``).
295
274
296
275
There is a special concept in Sparrow called ``AnyType`` that is compatible with any type. Here is an example of a function that prints to the console the value given as parameter:
297
276
@@ -301,10 +280,10 @@ There is a special concept in Sparrow called ``AnyType`` that is compatible with
301
280
cout << x << endl
302
281
303
282
writeLn(10); // prints an Int value
304
-
writeLn(3.14); // prints a Double value
283
+
writeLn(3.14); // prints a Float value
305
284
writeLn("Pretty cool, huh?"); // prints a StringRef value
306
285
307
-
Both the ``sum`` function above and this ``writeLn`` function are generics, template functions, just like C++ template functions. This means, that the compiler will actually generate three ``writeLn`` functions for the three instantiations shown here: one with a ``Int`` parameter, one with a ``Double`` parameter, and one with a ``StringRef`` parameter. All these three functions will be compiled independently of each other.
286
+
Both the ``sum`` function above and this ``writeLn`` function are generics, template functions, just like C++ template functions. This means, that the compiler will actually generate three ``writeLn`` functions for the three instantiations shown here: one with a ``Int`` parameter, one with a ``Float`` parameter, and one with a ``StringRef`` parameter. All these three functions will be compiled independently of each other.
308
287
309
288
In cases where all parameters are ``AnyType``, the parentheses and the type specifications can be omitted:
310
289
@@ -378,7 +357,7 @@ Defining an operator is very similar to defining a function. Here is an example
378
357
379
358
::
380
359
381
-
fun **(x: Double, p: Int): Double
360
+
fun **(x: Float, p: Int): Float
382
361
var res = 1.0
383
362
for i = 0..p
384
363
res *= x
@@ -568,15 +547,15 @@ All the parameters to a datatype need to be compile-time. For example, a datatyp
568
547
569
548
::
570
549
571
-
var p1: Pair(Int, Float) // call default constructor
572
-
var p2 = Pair(Int, Double)(1, 3.14) // call initialization constructor
550
+
var p1: Pair(Int, Float32) // call default constructor
551
+
var p2 = Pair(Int, Float)(1, 3.14) // call initialization constructor
On the first line we are telling the compiler that ``t1`` is ``Int`` and ``t2`` is ``Float``, and we ask it to instantiate a ``Pair`` with these two types. This is not a constructor call, it's a generic instantiation.
578
557
579
-
On the second line, we ask the compiler to generate another type, one that is parameterized with valued ``Int`` and ``Double``. But this, time, after specifying the parameter values for the generic, we are specifying arguments for a constructor call (``1`` and ``3.14``).
558
+
On the second line, we ask the compiler to generate another type, one that is parameterized with valued ``Int`` and ``Float32``. But this, time, after specifying the parameter values for the generic, we are specifying arguments for a constructor call (``1`` and ``3.14``).
580
559
581
560
In our case, we haven't manually created a constructor associated with our generic datatype. But, we specified the ``[initCtor]`` modifier. This will tell the compiler to generate a constructor withe the right number of parameters to initialize all the fields.
0 commit comments