pint° v0.0.4: hello, world!
pint° v0.0.4 introduces a few features that allow one to finally make a “hello, world”: basic literals, let declarations, method calling and non-class imports. Two of them were already highlighted (although partially) in a previous post, but we will show them again, now in their full implementation.
Basic literals #
The following literals are now supported in pint°:
Unit literals #
As basic as it can be, unit literals are ()
. They are currently their own
thing, but when we introduce records/tuples/structs, they will be generalized
to be part of them.
Dart has no inherent concept of a unit or unit literal (although it’s not hard
to implement your own, and Null
itself is a singletone type), so how unit
compiles to Dart will depend on some heuristics, described in a
previous post.
Boolean literals #
Boolean are also as basic as they could be, and the follow what Dart (an many
other languages) do: true
and false
.
String literals #
For 0.0.4, we don’t support advanced features that one could expect for a string literal, like escaping, raw string, multi-line literals, or anything fancy, but we included a basic support for them.
In pint°, string literals are always double-quoted1. So, for instance:
"lorem ipsum dolor sit amet"
Number literals #
This one is new in relation to the last post. As said earlier, we are still discussing some details about how we will handle numbers bases (and other things), so we decided to ship a basic version of it that only supports the most simple case for both integer and double literals.
Number literals support digit divisors out of the box, so here are some examples of some number literals:
42
1_000
1__000_000__000_000
1.0
10_000.0
0.000_000_1
Let declarations #
pint° now supports let declarations. They come in two flavors: regular let declarations and function let declarations.
Regular let declarations #
As the constrasting name implies, this one is the one presented in the post aforementioned. It allows one to declare associate a name with a value2.
Here are some examples:
|
|
Let declarations introduces the identifier in the top-level scope of your program3. These identifiers can then be referred by other let declarations or in function calls.
Function let declarations #
By appending a parameter to a let declaration identifier, it is converted to a function let declaration4.
|
|
pint° functions have always a single parameter5, and current implementation parameters are simply ignored, so you can’t use them. However, this code works and compiles to a parameterless function in Dart.
|
|
Function calls #
If an identifier has the function type, it can be called.
|
|
Non-classes imports #
In 0.0.3, pint° could already import from Dart. However, it only imported classes. From this version, it also import top-level identifiers and methods6.
This enables us to… #
Finally have a (useless, but still) hello world in pint°.
|
|
This code will be compiled to a valid “hello world” Dart code:
|
|
What’s next? #
These changes are already in the GitHub repository, but I still didn’t release it to pub.dev. We want to update the syntax highlighting for our VSCode extension before doing so.
For the next version, three things will be the focus:
- Implementing records/tuples/structs (the name is yet to be decided);
- By consequence, implementing function parameters;
- And, for this to be able to happen, we need to have some basic7 type system implemented (subtype/supertype relation).
Contributors #
A special thanks to seha, that made his first contribution to our repository by implementing number literals.
Unlike Dart, our compilation target, which supports both single quotes and double quotes. We decided for this because by doing so we can use the
'
token for other things, aside from a more uniform syntax. ↩︎Let declarations are not reassignable. They can be either be compiled to Dart’s
const
declarations orfinal
declarations. This will depend on some heuristics, but most of the time it will be compiled tofinal
. ↩︎Local bindings will be introduced later (probably in 0.0.5) with let expressions. We may have other ways of introducing bindings, but let expressions will be our first and main way of doing so. ↩︎
Implementation detail: currently, let function declarations are their own thing, but in the future they will simply be a syntax sugar to a regular let declaration to a function literal, which we still don’t have. ↩︎
Multiple parameters will be handled in the future with records/tuples/structs. ↩︎
Other things are imported, like type aliases, but I’m not sure if they work, as I didn’t specifically supported them. Also, some unsupported types won’t be imported, like records. ↩︎
With basic, I mean we won’t have bounds for type parameters. ↩︎