Gren 0.2: Hello, NodeJS
Published: 2022-12-12Gren is a pure functional programmming language that aims to be easy to learn and to reason about, while remaining powerful and portable enough for real-world use.
Six months after the release of 0.1, a new release is here with a bunch of exciting features. This includes a built-in code formatter and basic support for creating applications that run on NodeJS.
Platforms
When defining new projects, you now need to specify which platform you're targeting. There are three platforms to choose from: common
, browser
and node
. The latter two decide where the application can run, wheras the common
platform indicates that your code can run anywhere. In other words, packages targeting the common
platform can be dependencies of either browser
and node
projects.
In practical terms, the platform setting decides which core packages you're allowed to depend on. If you're targeting the browser
platform, you're not allowed to depend on gren-lang/node
, directly or indirectly. Likewise, a project targeting the node
platform is forbidden from depending on gren-lang/browser
. When targeting the common
platform, you can depend on neither.
In order to make it easier to setup a project correctly, we've added two flags to the gren init
command: --package
and --platform
. For instance, if you want to create a package project targeting the node
platform, you can run:
gren init --package --platform node
If you'd rather create a node
application, then just leave out the --package
flag.
The long-term goal is to support all built-in NodeJS API's, but currently we only support a small subset. To get a better idea of what's possible you can read the gren-lang/node documentation or take a look at the cat example program.
You might also want to take a look at this live demo where Robin implements the unix echo program in Gren.
Formatting
Aaron VonderHaar, the author of elm-format
, was working on a formatting tool for Gren before 0.1 was even released. With Gren 0.2, this tool is now ready to use.
To format your project, simply run gren format
. To validate the formatting of a project, just run gren format --validate
.
While the formatter should work well enough for most projects, it's not finished. Bugs and less-than-stellar formatting is to be expected in some cases. If you come across any interesting behaviour, please let us know.
Package consolidation
Several different packages have now been consolidated into fewer, but bigger packages. For example: gren-lang/virtual-dom
, gren-lang/html
and gren-lang/svg
are now merged into gren-lang/browser
.
The main reason for doing this has to do with project management. It's easier for me to deal with 5 bug trackers than 15, and it takes less time to migrate and publish 5 packages to Gren 0.2, instead of 15.
At the same time, there aren't really any downsides to developers. Fewer packages means less time being spent downloading packages, and since Gren has excellent dead-code elimination, your compiled output isn't getting bigger either.
Everything hasn't been consolidated, though. gren-lang/url
, gren-lang/parser
and gren-lang/web-storage
do still exist and will continue to do so until I'm certain that their API is stable enough to be consolidated into one of the "big three" packages.
Going forward, new functionality is likely to be introduced in standalone packages, then become merged into the right platform package when the API has stabilized.
Package management
The package manager has improved in almost every way.
It is now significantly faster, gives detailed error messages when you have incompatible dependencies in your project, and has learned a few new tricks to make it easier to manage your dependencies.
There's now a gren package uninstall
command for removing a dependency from your project, as well as gren package outdated
for seeing which dependencies are out of date.
New language features
Gren 0.2 also brings a few new language features. These don't radically change the language in any way, but provide small quality-of-life improvements.
Record update now works on any expression
In 0.1, record update syntax only worked on variable names, like this:
originalRecord = { value = "original" }
updatedRecord = { originalRecord | value = "updated" }
However, any other expression isn't legal. So you can't do things like this:
updatedRecord = { OtherModule.originalRecord | value = "updated" }
This is one of the only places where we have such limitations. For instance, we don't limit what expressions you can have in if
expressions or case
expressions, or even inside literals. So it's confusing when a limitation like this exists.
In 0.2, you can now use record update syntax with any expression. The above snippet will now compile, but so will much more complex expressions.
This change was contributed by Julian Antonielli.
Import aliases can now contain dots
Exactly what it says on the tin, the following import statement is now legal:
import Much.Nested.Module.Path as Nested.Path
Named unused constants
When pattern matching or defining functions, you can use _
to ignore a value. Here's an example:
length : Array a -> Int
length array =
Array.foldl (\_ len -> len + 1) 0 array
Sometimes, it can be helpful to attach a name to the ignored value, as a reminder for what the value represents. In 0.2, you can do just that:
length : Array a -> Int
length array =
Array.foldl (\_value len -> len + 1) 0 array
Note: trying to use _value
will trigger a compilation error.
This feature was contributed by Allan Clark.
Multi-line strings trims leading whitespace
Gren has dedicated syntax for defining a multi-line string. It looks like this:
str =
"""
this
is a
string
"""
In 0.1, this is equivalent to
str = "\n this\n is a\n string\n"
In 0.2, multi-line strings trims away a common number of leading whitespace on each line, so that the multi-line string compiles to the equivalent of:
str = "this\n is a\nstring"
What's next?
The 0.2 release is a big release, but we have no intention of stopping here. The 0.3 release will focus on testing & debugging, and will include features such as an official test framework, source maps for viewing Gren code in a JavaScript debugger and improved code generation.
Since Gren will continue with its six-month release cadence, 0.3 is scheduled for release in June 2023.
That's it for now. Head over to the install page to get started.